常用的自定义控件四(QuickBarView),2024年GitHub上那些优秀Android开源库总结

  1.   `* 设置字母更新监听`
    
  2.   `*`
    
  3.   `* @param listener`
    
  4.   `*/`
    
  5.  `public void setListener(OnLetterUpdateListener listener) {`
    
  6.      `this.listener = listener;`
    
  7.  `}`
    
  8.  `public QuickIndexBar(Context context) {`
    
  9.      `this(context, null);`
    
  10.  `}`
    
  11.  `public QuickIndexBar(Context context, AttributeSet attrs) {`
    
  12.      `this(context, attrs, 0);`
    
  13.  `}`
    
  14.  `public QuickIndexBar(Context context, AttributeSet attrs, int defStyle) {`
    
  15.      `super(context, attrs, defStyle);`
    
  16.      `mContext = context;`
    
  17.      `//初始化自定义属性`
    
  18.      `obtainAttrs(attrs);`
    
  19.      `// 初始化画笔`
    
  20.      `mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);`
    
  21.      `float textSize = UIUtils.dip2px(15, mContext);`
    
  22.      `mPaint.setTextSize(textSize);`
    
  23.      `mPaint.setTypeface(Typeface.DEFAULT_BOLD);`
    
  24.  `}`
    
  25.  `private void obtainAttrs(AttributeSet attrs) {`
    
  26.      `TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.QuickIndexBar);`
    
  27.      `int selectColor = typedArray.getColor(R.styleable.QuickIndexBar_select_color, -1);`
    
  28.      `if (selectColor != -1) {`
    
  29.          `mSelectColor = selectColor;`
    
  30.      `}`
    
  31.      `int normalColor = typedArray.getColor(R.styleable.QuickIndexBar_normal_color, -1);`
    
  32.      `if (normalColor != -1) {`
    
  33.          `mNormalColor = normalColor;`
    
  34.      `}`
    
  35.      `typedArray.recycle();`
    
  36.  `}`
    
  37.  `@Override`
    
  38.  `protected void onDraw(Canvas canvas) {`
    
  39.      `for (int i = 0; i < LETTERS.length; i++) {`
    
  40.          `String text = LETTERS[i];`
    
  41.          `// 计算坐标`
    
  42.          `int x = (int) (cellWidth / 2.0f - mPaint.measureText(text) / 2.0f);`
    
  43.          `// 获取文本的高度`
    
  44.          `Rect bounds = new Rect();// 矩形`
    
  45.          `mPaint.getTextBounds(text, 0, text.length(), bounds);`
    
  46.          `int textHeight = bounds.height();`
    
  47.          `int y = (int) (cellHeight / 2.0f + textHeight / 2.0f + i * cellHeight);`
    
  48.          `// 根据按下的字母, 设置画笔颜色`
    
  49.          `mPaint.setColor(mLastTouchIndex == i ? mSelectColor : mNormalColor);`
    
  50.          `// 绘制文本A-Z`
    
  51.          `canvas.drawText(text, x, y, mPaint);`
    
  52.      `}`
    
  53.  `}`
    
  54.  `@Override`
    
  55.  `public boolean onTouchEvent(MotionEvent event) {`
    
  56.      `int index = -1;`
    
  57.      `switch (MotionEventCompat.getActionMasked(event)) {`
    
  58.          `case MotionEvent.ACTION_DOWN:`
    
  59.              `// 获取当前触摸到的字母索引`
    
  60.              `index = (int) (event.getY() / cellHeight);`
    
  61.              `if (index >= 0 && index < LETTERS.length) {`
    
  62.                  `// 判断是否跟上一次触摸到的一样,不一样才进行回调`
    
  63.                  `if (index != mLastTouchIndex) {`
    
  64.                      `if (listener != null) {`
    
  65.                          `//`
    
  66.                          `listener.onLetterUpdate(LETTERS[index]);`
    
  67.                      `}`
    
  68.                      `Log.d(TAG, "onTouchEvent: " + LETTERS[index]);`
    
  69.                      `//记录上一次触摸的Index为当前的index;`
    
  70.                      `mLastTouchIndex = index;`
    
  71.                  `}`
    
  72.              `}`
    
  73.              `break;`
    
  74.          `case MotionEvent.ACTION_MOVE:`
    
  75.              `index = (int) (event.getY() / cellHeight);`
    
  76.              `if (index >= 0 && index < LETTERS.length) {`
    
  77.                  `// 判断是否跟上一次触摸到的一样`
    
  78.                  `if (index != mLastTouchIndex) {`
    
  79.                      `if (listener != null) {`
    
  80.                          `listener.onLetterUpdate(LETTERS[index]);`
    
  81.                      `}`
    
  82.                      `Log.d(TAG, "onTouchEvent: " + LETTERS[index]);`
    
  83.                      `mLastTouchIndex = index;`
    
  84.                  `}`
    
  85.              `}`
    
  86.              `break;`
    
  87.          `case MotionEvent.ACTION_UP:`
    
  88.              `// 手指抬起的时候重置`
    
  89.              `mLastTouchIndex = -1;`
    
  90.              `break;`
    
  91.          `default:`
    
  92.              `break;`
    
  93.      `}`
    
  94.      `//调用这个方法会重新调用draw方法,重新绘制`
    
  95.      `invalidate();`
    
  96.      `return true;`
    
  97.  `}`
    
  98.  `/**`
    
  99.   `* 当大小 改变的时候会回调这个方法,`
    
  100.   `* 这里我们就不主动调用measure()方法了`
    
  101.   `*`
    
  102.   `* @param w`
    
  103.   `* @param h`
    
  104.   `* @param oldw`
    
  105.   `* @param oldh`
    
  106.   `*/`
    
  107.  `@Override`
    
  108.  `protected void onSizeChanged(int w, int h, int oldw, int oldh) {`
    
  109.      `super.onSizeChanged(w, h, oldw, oldh);`
    
  110.      `// 获取单元格的宽和高`
    
  111.      `cellWidth = getMeasuredWidth();`
    
  112.      `int mHeight = getMeasuredHeight();`
    
  113.      `cellHeight = mHeight * 1.0f / LETTERS.length;`
    
  114.  `}`
    
  115. }

代码 解析

  • 代码其实不长,加上一些注释总共才180多行,总体来说,思路分分为以下几个步骤
  1. 在构造方法里面初始化画笔,同时为了使用方便,我们封装了自定义属性

  2. public QuickIndexBar(Context context, AttributeSet attrs, int defStyle) {

  3.      `super(context, attrs, defStyle);`
    
  4.      `mContext = context;`
    
  5.      `//初始化自定义属性`
    
  6.      `obtainAttrs(attrs);`
    
  7.      `// 初始化画笔`
    
  8.      `mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);`
    
  9.      `float textSize = UIUtils.dip2px(15, mContext);`
    
  10.      `mPaint.setTextSize(textSize);`
    
  11.      `mPaint.setTypeface(Typeface.DEFAULT_BOLD);`
    
  12. }

  13.   `private void obtainAttrs(AttributeSet attrs) {`
    
  14.      `TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.QuickIndexBar);`
    
  15.      `int selectColor = typedArray.getColor(R.styleable.QuickIndexBar_select_color, -1);`
    
  16.      `if (selectColor != -1) {`
    
  17.          `mSelectColor = selectColor;`
    
  18.      `}`
    
  19.      `int normalColor = typedArray.getColor(R.styleable.QuickIndexBar_normal_color, -1);`
    
  20.      `if (normalColor != -1) {`
    
  21.          `mNormalColor = normalColor;`
    
  22.      `}`
    
  23.      `typedArray.recycle();`
    
  24.  `}`
    
  25. 接着我们在onSizeChange 方法里面拿到我们时间的宽度和高度,有人可能会问了为什么不在onMeasure里面获取了,其实在onMeasure方法里面获取是可以的,只不过我们还需要调用一下measure方法而已,在onSizeChnage方法里面,我们直接调用

  26. cellWidth = getMeasuredWidth();

即可获取到我们需要的宽度和高度。用起来比较方便,不过更多的是为了让大家知道View有这一个方法存在以及怎么使用它

顺便我们来看一下google官方对onSizeChange方法的解释

This is called during layout when the size of this view has changed. If you were just added to the view hierarchy, you’re called with the old values of 0.

从官方的解释我们可以知道这个方法是在onLayout方法中当大小改变的时候会调用这个方法,因此我们直接调用getMeasuredWidth();是可以获取得到宽度的,因为onMeasure 是先于onLayout方法调用的。

3. 接着我们重写onDraw方法,在onDraw方法我们所做的工作就是绘制 我们需要的26个字母

  1.  `protected void onDraw(Canvas canvas) {`
    
  2.      `for (int i = 0; i < LETTERS.length; i++) {`
    
  3.          `String text = LETTERS[i];`
    
  4.          `// 计算坐标`
    
  5.          `int x = (int) (cellWidth / 2.0f - mPaint.measureText(text) / 2.0f);`
    
  6.          `// 获取文本的高度`
    
  7.          `Rect bounds = new Rect();// 矩形`
    
  8.          `mPaint.getTextBounds(text, 0, text.length(), bounds);`
    
  9.          `int textHeight = bounds.height();`
    
  10.          `int y = (int) (cellHeight / 2.0f + textHeight / 2.0f + i * cellHeight);`
    
  11.          `// 根据按下的字母, 设置画笔颜色`
    
  12.          `mPaint.setColor(mLastTouchIndex == i ? mSelectColor : mNormalColor);`
    
  13.          `// 绘制文本A-Z`
    
  14.          `canvas.drawText(text, x, y, mPaint);`
    
  15.      `}`
    
  16.  `}`
    
  17. 讲到这里,我们的工作已经完成一大半了,接着就是处理我们是按下或者一个字母了,我们重写onTouchEvent方法,并且return true;是为了保证 Action_down动作按下以后,Action_move以后的动作能够顺利接受到,这涉及到View的事件分发机制,有空的话我会尝试总结一下,这里就不说了

  18. // 获取当前触摸到的字母索引

  19. index = (int) (event.getY() / cellHeight);

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后

数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-w2xTVfIG-1711088104173)]
[外链图片转存中…(img-twaGDkoq-1711088104174)]
[外链图片转存中…(img-Efts7tSL-1711088104174)]
[外链图片转存中…(img-ZyXxn5Pw-1711088104174)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-yjeIDXJU-1711088104175)]

最后

想要了解更多关于大厂面试的同学可以**点击这里免费获取《面试文档》**除此之外,我也分享一些免费的优质资源,包括:Android学习PDF+架构视频+源码笔记高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 这几块的内容。分享给大家,非常适合近期有面试和想在技术道路上继续精进的朋友。快来获取学习资料吧~

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值