Android自定义控件使用-仿ios来电接听按钮
- 开发自定义控件步骤
1.编写继承自View的子类或viewGroup的子类
2.为自定义View类增加属性
3.绘制控件
4.响应用户消息
5.自定义回调函数
- 自定义控件的一些方法
onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后调用的方法
onMeasure() 检测View组件及其子组件的大小
onLayout() 当该组件需要分配其子组件的位置、大小时
onSizeChange() 当该组件的大小被改变时
onDraw() 当组件将要绘制它的内容时
onKeyDown 当按下某个键盘时
onKeyUp 当松开某个键盘时
onTrackballEvent 当发生轨迹球事件时
onTouchEvent 当发生触屏事件时
onWindowFocusChanged(boolean) 当该组件得到、失去焦点时
onAtrrachedToWindow() 当把该组件放入到某个窗口时
onDetachedFromWindow() 当把该组件从某个窗口上分离时触发的方法
onWindowVisibilityChanged(int): 当包含该组件的窗口的可见性发生改变时触发的方法 - view的结构
Android系统的视图结构的设计也采用了组合模式,即View作为所有图形的基类,Viewgroup对View继承扩展为视图容器类。
自定义控件类
public class CallToggleButton extends View {
private Bitmap backgroundBitmap;// 背景图
private Bitmap slidBtn;// 可以滑动的图片
private int backgroundWidth, slidBtnWidth;
private Paint paint;//画笔
private float slidBtn_left;// 滑动按钮的左边距
private int firstX;// 手机按下的x坐标
private int lastX;// 手机抬起的x坐标
public myOnEventListener listener;
public CallToggleButton(Context context) {
super(context);
initView();
}
public CallToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public CallToggleButton(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
//获取按钮背景
backgroundBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.ldx_07_s480);
options.inSampleSize = ScreenTools.calculateInSampleSize(options, 110,
160); // 110,160:转换后的宽和高,具体值会有些出入
options.inJustDecodeBounds = false;
//获取滑动按钮图
slidBtn = BitmapFactory.decodeResource(getResources(),
R.drawable.ldx_03);
paint = new Paint();
//设置抗锯齿
paint.setAntiAlias(true);
backgroundWidth = backgroundBitmap.getWidth();
slidBtnWidth = slidBtn.getWidth();
slidBtn_left = (backgroundWidth / 2) - (slidBtnWidth / 2);
}
/*
* 测量view宽高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
ScreenTools.init(getContext());
// 设置宽高
setMeasuredDimension(backgroundBitmap.getWidth(),
backgroundBitmap.getHeight());
}
/*
* 绘制当前view的内容
*/
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(backgroundBitmap, 0, 0, paint);
canvas.drawBitmap(slidBtn, slidBtn_left, 0, paint);
}
/*
* 滑动事件
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
firstX = lastX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
// 计算手指移动的距离
int dis = (int) event.getX();
// 根据手指的位置,改变slidBtn_left的值
slidBtn_left = dis;
break;
case MotionEvent.ACTION_UP:
int maxLeft = backgroundWidth - slidBtnWidth;
if (slidBtn_left >= maxLeft) {
// 滑动到最右调用的方法
listener.RightEvent();
} else if (slidBtn_left < (slidBtnWidth / 2)) {
// 滑动到最左调用的方法``
listener.LeftEvent();
} else {
// 接听按钮回到原点
Log.i("simple", "接听按钮回到原点");
slidBtn_left = (backgroundWidth / 2) - (slidBtnWidth / 2);
}
break;
}
flushView();
return true;
}
/**
* 刷新当前视图
*/
private void flushView() {
int maxLeft = backgroundWidth - slidBtnWidth;
// 确保 slideBtn_left >= 0
slidBtn_left = (slidBtn_left > 0) ? slidBtn_left : 0;
// 确保 slideBtn_left <=maxLeft
slidBtn_left = (slidBtn_left < maxLeft) ? slidBtn_left : maxLeft;
/*
* 刷新当前视图调用invalidate 导致 执行onDraw执行
*/
invalidate();
}
/**view事件方法*/
public void setOnEvent(myOnEventListener listener){
this.listener = listener;
}
/**view接口方法*/
interface myOnEventListener{
abstract void RightEvent();
abstract void LeftEvent();
}
MainActivity类
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CallToggleButton cb = (CallToggleButton)findViewById(R.id.toggleButton);
cb.setOnEvent(new CallToggleButton.myOnEventListener() {
@Override
public void RightEvent() {
Log.i("simple","滑动到最右");
Toast.makeText(MainActivity.this,"滑动到最右",Toast.LENGTH_SHORT).show();
}
@Override
public void LeftEvent() {
Log.i("simple","滑动到最左");
Toast.makeText(MainActivity.this,"滑动到最左",Toast.LENGTH_SHORT).show();
}
});
}
}
布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<com.simple.togglebuttondemo.CallToggleButton
android:id="@+id/toggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
/>
</RelativeLayout>