我创建了一个扩展 LinearLayout
的类来绘制边框半径,并添加了 setRadius()
函数
public class RadiusLinearLayout extends LinearLayout {
private float CORNER_RADIUS;
private Bitmap maskBitmap;
private Paint paint, maskPaint;
private float cornerRadius;
public void setRadius(float cornerRadius) {
CORNER_RADIUS = cornerRadius;
}
public RadiusLinearLayout(Context context) {
super(context);
init(context, null, 0);
}
public RadiusLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public RadiusLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
setWillNotDraw(false);
}
@Override
public void draw(Canvas canvas) {
Bitmap offscreenBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas offscreenCanvas = new Canvas(offscreenBitmap);
super.draw(offscreenCanvas);
if (maskBitmap == null) {
maskBitmap = createMask(getWidth(), getHeight());
}
offscreenCanvas.drawBitmap(maskBitmap, 0f, 0f, maskPaint);
canvas.drawBitmap(offscreenBitmap, 0f, 0f, paint);
}
private Bitmap createMask(int width, int height) {
Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
Canvas canvas = new Canvas(mask);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
canvas.drawRect(0, 0, width, height, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);
return mask;
}
}
在与此类对应的 fragment 上,OnCreateView
我引用了Layout
并设置了半径值,但它不应用我发送到布局的值
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view: View = inflater.inflate(R.layout.calculator_fragment, container, false)
val test = view.findViewById(R.id.testCF) as RadiusLinearLayout
test.setRadius(2f)
return view
}
是否可以在 fragment 膨胀之前将值传递给Layout
?
最佳答案
Is it possible to pass a value to the Layout before the fragment gets inflated?
基本上是的 (*),但我想展示如何更灵活地更改自定义 View
的半径:
View
发生了某些变化,因此需要更新 UI,例如,如果您调用 View.setBackground()
。
在这种情况下,View
会调用 invalidate()
让运行时知道它需要重绘。
每次设置半径时,您的自定义View
都可以这样做:
public void setRadius(float cornerRadius) {
CORNER_RADIUS = cornerRadius;
// Now you need to calculate the field *cornerRadius* once more
//
DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);
invalidate();
}
顺便说一句,将圆角半径设置为 2f 不会造成太大的变化 - 我尝试使用 24f,效果很好。
(*) 如果您绝对需要在自定义 View
膨胀之前更改半径,您可以以编程方式创建它并在将其添加到之前调用 setRadius()
一个ViewGroup
。
或者你define a custom attribute通过布局文件配置View
。
关于java - 如何在浮点值膨胀之前将浮点值传递给扩展 LinearLayout 的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59095728/