内容简介:小伙伴们大家好呀,这次介绍一个稍微有点意思的View,在很多阅读类、新闻类的APP上都标配的字体大小调整功能。100多行代码就可以实现,来看看效果吧!思路分析1、刻度线代表着每个字体的大小取值,是不是
小伙伴们大家好呀,这次介绍一个稍微有点意思的View,在很多阅读类、新闻类的APP上都标配的字体大小调整功能。100多行代码就可以实现,来看看效果吧!
思路分析
1、刻度线代表着每个字体的大小取值,是不是 SeekBar 就是这样的功能呀,改一下刻度浮标的样式即可。
2、刻度条上面的标注的文本代表着字体大小的说明,假设用一个 LinearLayout 包着3个 TextView 的方法很难实现文本跟刻度对齐,只能画出来了。
开始写代码
我们以 SeekBar 作为基础,对它进行重写 onDraw() 的方法,在这之前先来初始化一下基本属性。
/**
* 字体大小调整滑杆
* Created by ChenRui on 2017/10/13 0013 12:50.
*/
public class RaeSeekBar extends AppCompatSeekBar {
// 刻度说明文本,数组数量跟刻度数量一致,跟mTextSize的长度要一致
private String[] mTickMarkTitles = new String[]{
"A",
"标准",
"",
"",
"A"
};
// 刻度代表的字体大小
private int[] mTextSize = new int[]{
16,
18,
24,
26,
28
};
// 刻度文本画笔
private final Paint mTickMarkTitlePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
// 刻度文本字体大小
private float mTickMarkTitleTextSize = 18;
// 刻度文本跟刻度之间的间隔
private float mOffsetY = 40;
// 刻度线的高度
private int mLineHeight = 10;
// 保存位置大小信息
private final Rect mRect = new Rect();
// ...省略一些其他构造函数
public RaeSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
protected void init() {
// 初始化刻度文本字体大小
mTickMarkTitleTextSize = getSize(mTickMarkTitleTextSize);
// 刻度文本跟刻度之间的间隔
mOffsetY = getSize(mOffsetY);
// 刻度线的高度
mLineHeight = getSize(mLineHeight);
// 刻度文字的对齐方式为居中对齐
mTickMarkTitlePaint.setTextAlign(Paint.Align.CENTER);
// 刻度文字的字体颜色
mTickMarkTitlePaint.setColor(ContextCompat.getColor(getContext(), R.color.ph1));
// 设置最大刻度值为字体大小数组的长度
setMax(mTextSize.length);
// 设置当前的刻度
setProgress(1);
}
}
测量布局
因为要在原来的 SeekBar 的基础 上添加文本,那就应该在原来的 SeekBar 的 高度上再增加最大刻度的文字的高度就是控件布局的高度。
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 原来的布局大小
int wm = MeasureSpec.getMode(widthMeasureSpec);
int hm = MeasureSpec.getMode(heightMeasureSpec);
int w = getMeasuredWidth();
int h = getMeasuredHeight();
// 以最大的字体为基础,加上刻度字体大小
h += getSize(mTextSize[mTextSize.length - 1]);
// 加上与刻度之间的间距大小
h += mOffsetY;
// 保存测量结果
setMeasuredDimension(MeasureSpec.makeMeasureSpec(w, wm), MeasureSpec.makeMeasureSpec(h, hm));
}
重绘
总结一下画的思路,这样可以比较好理解代码的实现。整个过程一共需要我们画3部分:
- 直线
- 刻度线
- 刻度文本
当然还有个滑动块,这个我们可以使用 SeekBar 自带的效果,即可以自定义样式,又能偷下懒。下面来一个个解析画的具体步骤。
1、画直线
我们先理解成外部是一个矩形,直线位于中间,左右两边的间距为滑块的一半。通过研究发现 getPaddingLeft() getPaddingRight() 正好就是这个一半值。
2、刻度线
很容易看得出来,刻度线实际是把直线进行等分,等分的多少取决于 setMax() 的取值,也相当于 mTextSize.length ,这样我们通过画直线就能轻松实现了。
3、刻度文本
最重要的是确定文本所在的 (x,y) 坐标值 即可,不难发现文本的坐标是跟随刻度线的位置变化的,所以在画刻度线的时候就可以一起把文本也画出来了。
4、滑块位置
系统滑块的位置其实是跟分割线的位置一样的。等分直线,处于分割线中心。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 刻度长度
int maxLength = getMax();
int width = getWidth();
int height = getHeight();
int h2 = height / 2; // 居中
// 画刻度背景
mRect.left = getPaddingLeft();
mRect.right = width - getPaddingRight();
mRect.top = h2 - getSize(1); // 居中
mRect.bottom = mRect.top + getSize(1.5f); // 1.5f为直线的高度
// 直线的长度
int lineWidth = mRect.width();
// 画直线
canvas.drawRect(mRect, mTickMarkTitlePaint);
// 遍历刻度,画分割线和刻度文本
for (int i = 0; i <= maxLength; i++) {
// 刻度的起始间隔 = 左间距 + (线条的宽度 * 当前刻度位置 / 刻度长度)
int thumbPos = getPaddingLeft() + (lineWidth * i / maxLength);
// 画分割线
mRect.top = h2 - mLineHeight / 2;
mRect.bottom = h2 + mLineHeight / 2;
mRect.left = thumbPos;
mRect.right = thumbPos + getSize(1.5f); // 直线的宽度为1.5
canvas.drawRect(mRect, mTickMarkTitlePaint);
// 画刻度文本
String title = mTickMarkTitles[i % mTickMarkTitles.length]; // 拿到刻度文本
mTickMarkTitlePaint.getTextBounds(title, 0, title.length(), mRect); // 计算刻度文本的大小以及位置
mTickMarkTitlePaint.setTextSize(getSize(mTextSize[i])); // 设置刻度文字大小
// 画文本
canvas.drawText(title, thumbPos, getSize(mTextSize[mTextSize.length - 1]), mTickMarkTitlePaint);
}
}
画好了是不是等不及了来实际应用一下呢?
具体应用示例
- 布局文件
<!--thumb属性为滑块的图片-->
<com.rae.cnblogs.widget.RaeSeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:progressDrawable="@android:color/transparent"
android:theme="@style/Widget.AppCompat.SeekBar"
android:thumb="@drawable/seekbar_thumb_material_anim_font_setting" />
- thumb滑块图片
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true">
<item>
<shape android:shape="oval">
<solid android:color="@color/badge_color" />
<size android:width="24dp" android:height="24dp" />
</shape>
</item>
</selector>
- 滑块回调监听
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int value, boolean b) {
// 获取滑块所在位置对应的字体大小
int size = mSeekBar.getRawTextSize(value);
mMessage.setTextSize(size);
}
//... 省略其他方法
});
源码
好啦,本篇文章到这里结束了。忍不住想试试的,可以参考 源代码 来做,在 博客园Android开源客户端 项目中,喜欢的给个 Star ~~
源码主要类:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Android View篇之调整字体大小滑杆的实现
- CSS 字体:字体特性
- iOS 自定义字体设置与系统自带的字体
- ReactNative字体大小不随系统字体大小变化而变化
- 再谈中文字体的子集化与动态创建字体
- 可爱气质的中文字体,字体视界法棍体-开源免费下载
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First JavaScript Programming
Eric T. Freeman、Elisabeth Robson / O'Reilly Media / 2014-4-10 / USD 49.99
This brain-friendly guide teaches you everything from JavaScript language fundamentals to advanced topics, including objects, functions, and the browser’s document object model. You won’t just be read......一起来看看 《Head First JavaScript Programming》 这本书的介绍吧!