安卓自定义view全解:初始化,onDraw函数,onMeasure函数,用户手势事件

来源:互联网 发布:爱知超声波流量计软件 编辑:程序博客网 时间:2024/06/05 14:38

全栈工程师开发手册 (作者:栾鹏)

安卓教程全解

安卓自定义view全解。

view类包含如下函数。可供重写。

onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后调用的方法
onMeasure() 检测View组件及其子组件的大小
onLayout() 当该组件需要分配其子组件的位置、大小时
onSizeChange() 当该组件的大小被改变时
onDraw() 当组件将要绘制它的内容时
onKeyDown 当按下某个键盘时
onKeyUp 当松开某个键盘时
onTrackballEvent 当发生轨迹球事件时
onTouchEvent 当发生触屏事件时
onWindowFocusChanged(boolean) 当该组件得到、失去焦点时
onAtrrachedToWindow() 当把该组件放入到某个窗口时
onDetachedFromWindow() 当把该组件从某个窗口上分离时触发的方法
onWindowVisibilityChanged(int): 当包含该组件的窗口的可见性发生改变时触发的方法

安卓自定义view

在本文的示例中,我们使用view基类的基本函数进行了属性设置,在onDraw函数中使用Canvas进行绘图,在onMeasure函数中调整控件大小,并且重写了onKeyDown、onKeyUp、onTrackballEvent、onTouchEvent函数监听用户事件。

public class UI_View extends View {        // 使用代码创建时必须的构造函数      public UI_View(Context context) {        super(context);        init();      }      //使用资源文件进行填充时必须的构造函数      public UI_View (Context context, AttributeSet attrs) {        super(context, attrs);        init();      }      // 使用资源文件进行填充时必须的构造函数      public UI_View (Context context, AttributeSet ats, int defaultStyle) {        super(context,ats,defaultStyle);        init();      }      //进行控件初始化      private void init(){          this.setBackgroundColor(Color.GREEN);   //设置背景颜色          this.setX(100);   //设置x          //...还有一大堆自己控制      }      //绘制自定义控件      @Override      protected void onDraw(Canvas canvas) {        // 在上次对onMeasure方法调用的基础上获得控件的大小        int height = getMeasuredHeight();        int width = getMeasuredWidth();        //找出控件的中心        int px = width/2;        int py = height/2;        // 创建新的画刷,注意:由于效率的原因,这项工作应该在视图的构造函数中完成        Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mTextPaint.setColor(Color.RED);    //设置文字颜色        mTextPaint.setTextSize(40);       //设置文字大小        mTextPaint.setStrokeWidth(3);     //设置线宽           mTextPaint.setTextAlign(Align.LEFT);  //设置对齐方式        //定义字符串        String displayText = "Hello World!";        //计算文本字符串的宽度        float textWidth = mTextPaint.measureText(displayText);        //在控件的中心绘制文本字符串        canvas.drawText(displayText, px-textWidth/2, py, mTextPaint);        Log.v("自定义view", "绘制控件");      }      //onMeasure用来调整控件大小,默认为100*100      @Override      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int measuredHeight = measureHeight(heightMeasureSpec);        int measuredWidth = measureWidth(widthMeasureSpec);        //必须调用setMeasuredDimension,否则在布局控件的时候会造成运行时异常        setMeasuredDimension(measuredHeight, measuredWidth);        Log.v("自定义view", "调整大小");      }      private int measureHeight(int measureSpec) {        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        //  如果不指定限制,就是默认大小        int result = 200;        if (specMode == MeasureSpec.AT_MOST) {          //计算控件在这个最大尺寸范围内的理想大小,如果控件填充了可用空间,则返回外边界          result = specSize;        } else if (specMode == MeasureSpec.EXACTLY) {          // 如果控件可以放置在这个边界内,则返回该值          result = specSize;        }        return result;      }      private int measureWidth(int measureSpec) {        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        //如果不指定限制,就是默认的大小        int result = 200;        if (specMode == MeasureSpec.AT_MOST) {          // 计算控件在这个最大的尺寸范围内的理想大小,如果控件填充了可用的空间,那么返回外边界          result = specSize;        } else if (specMode == MeasureSpec.EXACTLY) {          // 如果控件可以放置在这个边界内,则返回该值          result = specSize;        }        return result;      }      //用户交互事件      @Override      public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {          //如果事件得到处理,返回true          Log.v("自定义view", "按键按下");          return true;      }      @Override      public boolean onKeyUp(int keyCode, KeyEvent keyEvent) {          //如果事件得到处理,返回true          Log.v("自定义view", "按键弹起");          return true;      }      @Override      public boolean onTrackballEvent(MotionEvent event ) {        // 获得这个事件代表的动作类型        int actionPerformed = event.getAction();        Log.v("自定义view", event.toString());        // 如果事件得到处理,返回true        return true;      }      @Override      public boolean onTouchEvent(MotionEvent event) {        // 获得这个事件代表的动作类型        int actionPerformed = event.getAction();        Log.v("自定义view", event.toString());        // 如果事件得到处理,返回true        return true;      }}

将我们自定义的view添加到窗口中有两种方式

1、在activity中将自定义view添加到窗口中

LinearLayout linearLayout = (LinearLayout)findViewById(R.id.activity1_linearlayout1);UI_View myview = new UI_View(this);linearLayout.addView(myview);

2、在xml布局文件中添加

在xml中添加也可以设置view的基本属性。不过在view显示时还是会调用onMeasure函数中设置的控件大小。

<?xml version="1.0" encoding="utf-8"?><LinearLayout 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:id="@+id/activity1_linearlayout1"    android:orientation="vertical">    <com.lp.app.ui.UI_View         android:id="@+id/activity1_ui_view1"        android:layout_width="match_parent"        android:layout_height="100px"        /></LinearLayout>
阅读全文
0 0