Android自定义控件使用-仿ios来电接听按钮
2015-08-28 16:30
661 查看
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>
相关文章推荐
- Android状态栏透明(沉浸式效果)
- Android状态栏透明(沉浸式效果)
- 关于 android 设置背景图片时找不到指定文件的问题
- Android 问题:Attribute "xxx" has already been defined
- 怎么把android程序崩溃的信息保存起来
- Android 采用工厂类创建对话框
- 8月28日 XE8移动开发入门(三)XE8在Android应用中调用Java类, 使用LiveBindings(免费培训)
- Android手势检测 带你打造图片缩放预览(上)
- CardView设置item的margin问题
- android SDK 无法更新的问题
- android屏幕适配 - 切图
- Android-如何获得当前正在运行的activity和进程的相关信息
- 友盟微社区2.1版本的接入
- Android中JNI的使用方法
- ubuntu android 开发环境编译问题及解决方案
- 日积月累:Proguard进行Android代码混淆
- getview所犯低级错误
- 简述Android系统内存不足时候,内存回收机制
- Android之——史上最简单最酷炫的3D图片浏览效果的实现
- Android PinyinIME 源码笔记 -- 2. 底层服务启动