Android(安卓)自定义TextView实现宫格布局,Drawable添加图片并控制宽高
16lz
2021-01-26
上图:
需求:
-
宫格布局(宽高一致,在屏幕上高度始终更随宽度变化)
-
图片在上文字在下布局
-
可以控制图片的宽高
布局完成,废话不多说直接上代码:
/** * 时 间 : 2019/7/22 0022 * 操作人 : yzhg * 版 本 : * 描 述 : * * * * * * * * * * * * * * * */public class HeightCustTextView extends AppCompatTextView { private Drawable drawableLeft; private Drawable drawableRight; private Drawable drawableTop; private int leftWidth; private int rightWidth; private int topWidth; private int leftHeight; private int rightHeight; private int topHeight; private Context mContext; public HeightCustTextView(Context context) { super(context, null); this.mContext = context; } public HeightCustTextView(Context context, AttributeSet attrs) { super(context, attrs, 0); this.mContext = context; init(context, attrs); } public HeightCustTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mContext = context; init(context, attrs); } private void init(Context context, AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.HeightCustTextView); drawableLeft = typedArray.getDrawable(R.styleable.HeightCustTextView_leftDrawable); drawableRight = typedArray.getDrawable(R.styleable.HeightCustTextView_rightDrawable); drawableTop = typedArray.getDrawable(R.styleable.HeightCustTextView_topDrawable); if (drawableLeft != null) { leftWidth = typedArray.getDimensionPixelOffset(R.styleable.HeightCustTextView_leftDrawableWidth, dip2px(context, 20)); leftHeight = typedArray.getDimensionPixelOffset(R.styleable.HeightCustTextView_leftDrawableHeight, dip2px(context, 20)); } if (drawableRight != null) { rightWidth = typedArray.getDimensionPixelOffset(R.styleable.HeightCustTextView_rightDrawableWidth, dip2px(context, 20)); rightHeight = typedArray.getDimensionPixelOffset(R.styleable.HeightCustTextView_rightDrawableHeight, dip2px(context, 20)); } if (drawableTop != null) { topWidth = typedArray.getDimensionPixelOffset(R.styleable.HeightCustTextView_topDrawableWidth, dip2px(context, 20)); topHeight = typedArray.getDimensionPixelOffset(R.styleable.HeightCustTextView_topDrawableHeight, dip2px(context, 20)); } } public int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); //获取宽的模式 int heightMode = MeasureSpec.getMode(heightMeasureSpec); //获取高的模式 int heightSize = MeasureSpec.getSize(heightMeasureSpec); //获取高的尺寸 int widthSize = MeasureSpec.getSize(widthMeasureSpec); //获取宽的尺寸 //重新测量高度,将宽度赋值给高度 heightMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY); //重新设置左侧图片的宽高 if (drawableLeft != null) { drawableLeft.setBounds(0, 0, leftWidth, leftHeight); } //重新设置右侧图片的宽高 if (drawableRight != null) { drawableRight.setBounds(0, 0, rightWidth, rightHeight); } //重新设置上面图片的宽高 if (drawableTop != null) { drawableTop.setBounds(0, 0, topWidth, topHeight); } //保存测量宽度和测量高度 setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { // 获取TextView的Drawable对象,返回的数组长度应该是4,对应左上右下 Drawable[] drawables = getCompoundDrawables(); Drawable drawable = drawables[0]; if (drawable != null) { // 当左边Drawable的不为空时,测量要绘制文本的宽度 float textWidth = getPaint().measureText(getText().toString()); int drawablePadding = getCompoundDrawablePadding(); int drawableWidth = drawable.getIntrinsicWidth(); // 计算总宽度(文本宽度 + drawablePadding + drawableWidth) float bodyWidth = textWidth + drawablePadding + drawableWidth; // 移动画布开始绘制的X轴 canvas.translate((getWidth() - bodyWidth) / 2, 0); } else if ((drawable = drawables[1]) != null) { // 否则如果上边的Drawable不为空时,获取文本的高度 Rect rect = new Rect(); getPaint().getTextBounds(getText().toString(), 0, getText().toString().length(), rect); float textHeight = rect.height(); int drawablePadding = getCompoundDrawablePadding(); int drawableHeight = drawable.getIntrinsicHeight(); // 计算总高度(文本高度 + drawablePadding + drawableHeight) float bodyHeight = textHeight + drawablePadding + drawableHeight; // 移动画布开始绘制的Y轴 canvas.translate(0, (getHeight() - bodyHeight) / 2); } super.onDraw(canvas); this.setCompoundDrawables(drawableLeft, drawableTop, drawableRight, null); } /** * 设置左侧图片并重绘 */ public void setDrawableLeft(Drawable drawableLeft) { this.drawableLeft = drawableLeft; invalidate(); } /** * 设置左侧图片并重绘 */ public void setDrawableLeft(int drawableLeftRes) { this.drawableLeft = mContext.getResources().getDrawable(drawableLeftRes); invalidate(); } /** * 设置右侧图片并重绘 */ public void setDrawableRight(Drawable drawableRight) { this.drawableRight = drawableLeft; invalidate(); } /** * 设置右侧图片并重绘 */ public void setDrawableRight(int drawableRightRes) { this.drawableRight = mContext.getResources().getDrawable(drawableRightRes); invalidate(); } /** * 设置上部图片并重绘 */ public void setDrawable(Drawable drawableTop) { this.drawableTop = drawableTop; invalidate(); } /** * 设置右侧图片并重绘 */ public void setDrawableTop(int drawableTopRes) { this.drawableTop = mContext.getResources().getDrawable(drawableTopRes); invalidate(); }}
styles:
参考xml布局(外层使用的是 ConstraintLayout )
必须设置:
android:gravity="center_horizontal"
代码很简单,一看就懂。不多解释,看不懂完全复制就行(坏笑)
注: 参考了两篇博客,可以说是将两篇博客的代码放在了一起(假笑/坏笑)
很遗憾,两篇博客地址已经找不到了,待找到之日在补上
更多相关文章
- 领略千变万化的Android(安卓)Drawable (一)
- Android(安卓)EditText获取焦点后只显示光标不弹出软键盘
- Android——selector背景选择器
- Android(安卓)SDK is missing, out of date, or is missing temp
- 01-android快速入门
- android在代码中设置margin属性
- Android解码/显示/播放Gif图片动画
- 修改设置Android(安卓)Preference相关样式
- Android(安卓)Training Caching Bitmaps 翻译