从画布裁剪来说过度绘制

自定义View一直是安卓开发中比较困难的技术点,实现一个优秀的自定义View控件不仅涉及到View的定位、测量、绘制等知识体系,还涉及到控件的绘制效率、是否存在过度绘制、是否存在绘制时间超长、是否存在内存泄漏等问题。

过度绘制又是布局优化中很重要的一个环节,有部分过度绘制是因为视图中View层级太多,背景层次太多,还有部分是因为View本身在同一块区域进行了多次绘制导致。关于视图层级,有经验的开发者都会在构造XML文件时进行处理,这点比较好注意到,也比较好优化。而关于View本身的重复绘制,可能不是很好处理,特别是在使用第三方控件时,需要通过修改源码来优化。比较经典的一个例子就是自定义扑克牌控件,下面,我们一步步来看下如何对这种控件进行优化。

准备工作

在查看View的过度绘制状态时,我们一般会打开手机的GPU过度绘制调试开关,位于设备的开发者选项里:

他会将屏幕中的View的过度绘制状态以不同的颜色填充,具体为:

接下来我们就需要实现扑克牌控件了。

实现控件

我们将几张扑克牌绘制在一个自定义View中,按照从左到右的顺序,右边一张牌盖住左边一张牌的部分。实现效果应该如下图:

为了达到比较好的效果,这边准备了54张扑克牌的的素材。

接下来,我们来实现控件,需要注意的几点是:

  1. 计算扑克牌被盖住的部分宽度
  2. 获取扑克牌的Bitmap对象
  3. 获取每张扑克牌的绘制区域
  4. 绘制扑克牌

核心逻辑为:

/**
 * 扑克相叠视图
 */
public class PokerView extends View {
   

  /**
   * 默认一行刚好能排列4张扑克
   */
  private final static int DEFAULT_COUNT = 4;
  /**
   * 扑克资源引用,用来随机发牌
   */
  private final static List<Integer> POKER_LIST = new ArrayList<>();

  static {
   
    POKER_LIST.add(R.drawable.p1);
    POKER_LIST.add(R.drawable.p2);
    ......省略部分代码
    POKER_LIST.add(R.drawable.p53);
    POKER_LIST.add(R.drawable.p54);
  }

  private int count = DEFAULT_COUNT;
  private Paint mPaint;
  /**
 * 当前扑克的Bitmap列表
 */
  private Map<Integer, Bitmap> mCurBitmaps = new HashMap<>();
  
  ......省略构造方法以及初始化画笔方法init

  /**
   * 发牌,重绘视图
   */
  public void shuffle(int count) {
   
    this.count = count;
    randomPoker();
    invalidate();
  }

  private void init() {
   
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setStrokeWidth(0)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值