欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android view(5)自定义组件

程序员文章站 2022-07-05 14:51:03
...

 

一、view的绘制流程是从ViewRoot的performTraversals方法开始的,包含以下三个过程:

1.measure过程

从*view开始遍历,在performMeasure调用measure,然后调用OnMeasure。onMeasure会对所有子元素进行measure完成遍历。

2.layout过程

同上。performLayout->layout->onLayout

3.draw过程

同上。performDraw->draw->onDraw

二、DecorView

继续自LinearLayout,view层的事件都先经过DecorView,然后才传递给我们的view.在LinearLayout中,包含两个部分,分别是标题栏和内容栏。内容栏的id就叫content,经常使用的setContentView就是加到这个内容栏中的,如setContentView(R.layout.hello_world_layout);可以这样获取我们设置的view:

ViewGroup content = (ViewGroup)findViewById(android.R.id.content);

content.getChildAt(0)

三、如何获得宽高

因为view的measure过程和activity的生命周期不是同步执行的,因此无法保证activity执行onCreate,onStart,onResume时宽高已经测量完毕。如果没有测量完毕,则会返回0.有四种方法可以获得测量后的宽高,这里只介绍一个简单的:

protected void onStart(){

   super.onStart();

   view.post(new Runnable(){

         public void run(){

   int width = view.getMeasuredWidth();

int height = view.getMeasureHeight();

}

      }

   );

}

通过post可以将一个runnable投递到一个消息队列的尾部,然后等待looper调用此runnable的时候,view也已经初始化好了。

四、自定义组件注意事项

1.重写onMeasure方法并设置wrap_content时的自身大小,否则在布局中使用wrap_content就相当于使用match_parent。

2.在draw方法中支持padding和margin

3.view中如果有线程或者动画需要及时停止。当包含view的activity退出或者当前的view被remove时,view的onDetachedFromWindow方法会被调用,相对应的,启动时执行onAttachedToWindow。

五、自定义组件继承自View重写onDraw方法

public class CircleView extends View{

   private int mColor = Color.RED;

   private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

   

   public CircleView(Context context){

      super(context);

 init();

   }

 

   public CircleView(Context context,AttributeSet attrs){

      super(context,attrs);

 init();

   }

   

   public CircleView(Context context,AttributeSet attrs,int defStyleAttr){

      super(context,attrs,defStyleAttr);

 init();

   }

   

   private void init(){

      mPaint.setColor(mColor);

   }

   

   protected void onDraw(Canvas canvas){

      super.onDraw(canvas);

 //为了让padding和wrap_content生效,要做处理

 final int paddingLeft = getPaddingLeft();

 final int paddingRight = getPaddingRight();

 final int paddingTop = getPaddingTop();

 final int paddingBottom = getPaddingBottom();

 

 int width = getWidth() - paddingLeft - paddingRight;

 int height = getHeight() - paddingTop - paddingBottom;

 int radius = Math.min(width,height)/2;

 canvas.drawCircle(paddingLeft+width/2,paddingTop+height/2,radius,mPaint);

   }

}

自定义属性参见206页

六、继承viewgroup派生特殊的layout

参见210页

上一篇: android 通知栏

下一篇: java gc