前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android面试题之自定义View注意事项

Android面试题之自定义View注意事项

作者头像
AntDream
发布2024-07-22 18:35:27
1320
发布2024-07-22 18:35:27
举报
文章被收录于专栏:程序员修炼之路

自定义View的分类

继承View重写onDraw方法

主要用于实现不规则的效果,即这种效果不方便通过布局的组合方式来实现。相当于就是得自己“画”了。采用这种方式需要自己支持wrap_content,padding也需要自己处理

继承ViewGroup派生特殊的Layout

主要用于实现自定义的布局,看起来很像几种View组合在一起的时候,可以使用这种方式。这种方式需要合适地处理ViewGroup的测量和布局,并同时处理子元素的测量和布局过程。比如自定义一个自动换行的LinerLayout等。

继承特定的View,比如TextView

这种方法主要是用于扩展某种已有的View,增加一些特定的功能。这种方法比较简单,也不需要自己支持wrap_content和padding。

继承特定的ViewGroup,比如LinearLayout

这种方式也比较常见,和上面的第2种方法比较类似,第2种方法更佳接近View的底层。

自定义View有多种方式,需要根据实际需要选择一种简单低成本的方式来实现

自定义View需要注意的地方

让View支持wrap_content

直接继承View和ViewGroup的控件需要在onMeasure方法中处理wrap_content的方法。处理方法是在wrap_content的情况下设置一个固定的尺寸

代码语言:javascript
复制
//处理wrap_content的套路
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    //处理WAP_CONTENT
    int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(200,200);
    }else if (widthSpecMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(200, heightSize);
    }else if (heightSpecMode == MeasureSpec.AT_MOST) {
        setMeasuredDimension(widthSize, 200);
    }
}
让View支持padding

直接继承View的控件需要在onDraw方法中处理padding,否则用户设置padding属性就不会起作用。直接继承ViewGroup的控件需要在onMeasure和onLayout中考虑padding和子元素的margin对其造成的影响,不然将导致padding和子元素的margin失效。

代码语言:javascript
复制
@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //获取padding,然后根据实际情况处理就好
    mPaddingLeft = getPaddingLeft();
    mPaddingRight = getPaddingRight();
    mPaddingTop = getPaddingTop();
    mPaddingBottom = getPaddingBottom();
    mWidth = getWidth() - mPaddingLeft - mPaddingRight;
    mHeight = getHeight() - mPaddingTop - mPaddingBottom;
}
尽量不要在View中使用Handler

View中已经提供了post系列方法,完全可以替代Handler的作用。

代码语言:javascript
复制
@UiThread
public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
        
    ...
        
    public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }
    
        // Postpone the runnable until we know on which thread it needs to run.
        // Assume that the runnable will be successfully placed after attach.
        getRunQueue().post(action);
        return true;
    }

    public boolean postDelayed(Runnable action, long delayMillis) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.postDelayed(action, delayMillis);
        }
    
        // Postpone the runnable until we know on which thread it needs to run.
        // Assume that the runnable will be successfully placed after attach.
        getRunQueue().postDelayed(action, delayMillis);
        return true;
    } 
    
    ...
}

View中如果有线程或者动画,需要及时停止

在View的onDetachedFromWindow方法可以停止线程和动画,因为当View被remove或是包含此View的Activity退出时,就会调用View的onDetachedFromWindow方法。如果不处理的话很可能会导致内存泄漏

  • View带有滑动嵌套时,需要处理好滑动冲突问题
  • 在View的onDraw方法中不要创建太多的临时对象,也就是new出来的对象。因为onDraw方法会被频繁调用,如果有大量的临时对象,就会引起内存抖动,影响View的效果
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AntDream 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 自定义View的分类
    • 继承View重写onDraw方法
      • 继承ViewGroup派生特殊的Layout
        • 继承特定的View,比如TextView
          • 继承特定的ViewGroup,比如LinearLayout
          • 自定义View需要注意的地方
            • 让View支持wrap_content
              • 让View支持padding
                • 尽量不要在View中使用Handler
                  • View中如果有线程或者动画,需要及时停止
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档