自定义view在xml文件中wrap_content无法展现?只有设置高宽值才出现?
老师:你好!
我的自定义BlockView 高宽设置为wrap_content,background设红色方块图,但是运行时无法出现这个BlockView,只有在布局文件中,设置具体高宽运行才能看见BlockView?
这个xml布局文件:
<com.example.animationhomework.BlockView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
hyman:test_dimension="100dp"
android:background="@drawable/red" />
这是自定义BlockView attrs 和类:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--属性申明,可以使用系统自带的设置,加上Android:-->
<declare-styleable name="BlockView">
<attr name="test_dimension" format="dimension" />
</declare-styleable>
</resources>
自定义类:
public class BlockView extends View {
private Paint mPaint;//画笔对象
public BlockView(Context context) {
super(context);
}
public BlockView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initPaint();//初始化画笔属性
// 获取属性文件
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BlockView);
/*属性赋值,赋予默认值*/
float dimensionTest = ta.getDimension(R.styleable.BlockView_test_dimension, 0);
ta.recycle();//回收ta 属性文件
}
//设置画笔属性
private void initPaint() {
mPaint = new Paint();//画笔对象
mPaint.setStyle(Paint.Style.STROKE);//FiLL实心,STROKE空心
mPaint.setStrokeWidth(6);//画笔粗细
mPaint.setColor(0xFFFF0000);//画笔颜色
mPaint.setAntiAlias(true);//画笔平滑
}
//测量控件大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);//获取测量宽度模式:MeasureSpec.EXACTLY MeasureSpec.AT_MOST MeasureSpec.UNSPECIFIED
int widthSize = MeasureSpec.getSize(widthMeasureSpec);//获取测量宽度尺寸
int width = 0;
if (widthMode == MeasureSpec.EXACTLY)//用户自定义宽度大小
{
width = widthSize;
} else {
int needWidth = getMeasuredWidth() + getPaddingLeft() + getPaddingRight();//需要的宽度尺寸
if (widthMode == MeasureSpec.AT_MOST)//如果测量宽度模式限制了最大值
{
width = Math.min(needWidth, widthSize);//测量宽度取 (需要值、测量值 ) 的最小值
} else {
width = needWidth;//没有设置最大值限制,宽度取需要值
}
}
int heightMode = MeasureSpec.getMode(heightMeasureSpec);//获取测量高度模式
int heightSize = MeasureSpec.getSize(heightMeasureSpec);//测量高度尺寸
int height = 0;
if (heightMode == MeasureSpec.EXACTLY)//用户自定义高度值
{
height = heightSize;//取测量高度
} else {
int needHeight = getMeasuredHeight() + getPaddingTop() + getPaddingBottom();//需要的高度尺寸
if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(needHeight, heightSize);//最大值限制,取需要高度和测量高度的最小值
} else {
height = needHeight;
}//无限制高度,取需要高度尺寸
}
setMeasuredDimension(width, height);//设置宽高尺寸
}
//获取屏幕尺寸 减去paddiing后的1/6
private float measureDisplayMetricOneSixth() {
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
return ( dm.widthPixels-getPaddingLeft()-getPaddingRight())*1f/6;
}
//正方形图形,宽高一致
private float measureHeight() {
return measureDisplayMetricOneSixth();
}
//六个方块铺底,每块宽度是 1/6*屏宽
private float measureWidth() {
return measureDisplayMetricOneSixth();
}
//TextView触屏(包含屏幕翻转)事件.屏幕回转后会恢复到原来的mStringTest="imooc"的值,通过保存和恢复函数实现才能保存"8888"值
@Override
public boolean onTouchEvent(MotionEvent event) {
invalidate();//其内部实际是调用invalidate(true)。是完全重绘自身TextView,本例中重绘后把文字变成"8888"
return true;
}
}
正在回答
onMeasure()里直接固定好宽和高就可以了。例如手机需要放6个控件,再去掉间距,平均一下。祝:学习愉快
- 参与学习 人
- 提交作业 116 份
- 解答问题 1012 个
本阶段是提升项目经验的必备,除Android开发的高级控件,还有Android官方大力推荐的开发语言Kotlin,未来Android发展的方向,最后使用Kotlin来开发热门电商项目。
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星