安卓:为什么要在自定义视图覆盖onMeasure()后,该视图的文本不能在RalativeLayout显示?视图、要在、能在、自定义

2023-09-05 11:10:36 作者:爱是陪伴付出和忍让

我做了扩展查看和覆盖其 onMeasure(),该成分的含量是自定义组件一些文字,然后我将其添加到 RelativeLayout的,但这种文字不能显示,如果我评论 onMeasure()这已经覆盖了文本显示。是什么原因?

下面是code:

 公共类CustomView扩展视图{
    私人字符串文本;
    私人诠释viewWidth;
    私人诠释viewHeight;
    民营涂料粉刷;
    私人的FontMetrics的FontMetrics;
    公共CustomView(上下文的背景下){
        这(背景下,NULL);
    }
    公共CustomView(上下文的背景下,文本字符串){
        这(上下文,文本,0);
        this.text =文本;
        油漆=新的油漆(Paint.ANTI_ALIAS_FLAG);

        updateViewBounds();
    }
公共CustomView(上下文的背景下,字符串文本,诠释defStyle){
    超(上下文);

}
私人无效updateViewBounds(){
    viewWidth =(INT)paint.measureText(this.text);
    的FontMetrics = paint.getFontMetrics();
    viewHeight =(INT)(fontMetrics.descent  -  fontMetrics.ascent);
}
私人字符串的getText(){
    返回this.text;
}
保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){
    super.onMeasure(widthMeasureSpec,heightMeasureSpec);
    setMeasuredDimension(viewWidth,viewHeight);
    // setMeasuredDimension(560,100);即使给一个确保的尺寸,它不能反正//。
}
保护无效的OnDraw(帆布油画){
    super.onDraw(画布);
    paint.setColor(Color.WHITE);
    paint.setTextSize(30);
    canvas.drawText(文字,0,200,油漆);
    Log.e(内容,+ this.getText());
}
公共布尔的onTouchEvent(MotionEvent事件){
    Log.e(触摸,+ this.getText());
    返回false;

}

}
 

下面是活动:

 公共类CustomViewActivity延伸活动{
    / **第一次创建活动时调用。 * /
    私人RelativeLayout的contentLayout;
    私人CustomView厂景;
    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);
        contentLayout =(RelativeLayout的)findViewById(R.id.contentLayout);
        厂景=新CustomView(这一点,你让我疯狂!);
        RelativeLayout.LayoutParams的LayoutParams =新RelativeLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        view1.setLayoutParams(的LayoutParams);
        contentLayout.addView(厂景);
    }
}
 
如何自定义android Button样式

这是XML文件:

 < XML版本=1.0编码=UTF-8&GT?;
< RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:ID =@ + ID / contentLayout
    机器人:layout_width =1024px
    机器人:layout_height =560px
    机器人:方向=垂直>

    <按钮
        机器人:ID =@ + ID /按钮2
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_alignParentBottom =真
        机器人:layout_alignParentLeft =真
        机器人:layout_marginLeft =126dp
        机器人:文本=按钮/>

< / RelativeLayout的>
 

解决方案

您绝对可以设置MeasureSpec以不同的大小,但是,对于onMeasure参数是误导性的。甲MeasureSpec是一个专门翻译int值,必须要特别通过使用两像素量度和一个标志创建。正确的方法来设置如下所示特定的大小...

 最终诠释desiredHSpec = MeasureSpec.makeMeasureSpec(pixelHeight,MeasureSpec.MODE_CONSTANT);
最终诠释desiredWSpec = MeasureSpec.makeMeasureSpec(pixelWidth,MeasureSpec.MODE_CONSTANT);
setMeasuredDimension(desiredWSpec,desiredHSpec);
 

在MODE_CONSTANTS必须具备以下条件之一的值: * AT_MOST - 这意味着它是动态的,但将被剪切,如果内容太大 *确切地 - 这意味着它将会是大小无论多么大或小的内容 *未知 - 这意味着它会做出各种决定,它根据的参数,使父母,子女,器件尺寸,等等...

如果您不指定其中的一个常量,那么Android的布局渲染引擎不知道该怎么做,而只是隐藏的对象。必须理解,作为一个开放的平台,这么多的设备,谷歌决定将布局引擎动态化和智能化,以支持尽可能多的平台上尽可能多的应用程序成为可能。这简单的要求开发,使设备确切地知道它需要什么。

注意:这听起来像正是你想要的,但仔细想想你的选择,多少设备,你会支持。 :)

I made a custom component that extends View and overrides its onMeasure(), the content of this component is some text, then I add it to a RelativeLayout, but this text can't display, if I comment onMeasure() that been overridden the text shows. What's the reason?

Here is the code:

public class CustomView extends View {
    private String text;
    private int viewWidth;
    private int viewHeight;
    private Paint paint;
    private FontMetrics fontMetrics;
    public CustomView(Context context) {
        this(context, null);
    }
    public CustomView(Context context, String text) {
        this(context, text, 0);
        this.text = text;
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        updateViewBounds();
    }
public CustomView(Context context, String text, int defStyle) {
    super(context);

}
private void updateViewBounds(){
    viewWidth = (int) paint.measureText(this.text);
    fontMetrics = paint.getFontMetrics();
    viewHeight =  (int)(fontMetrics.descent - fontMetrics.ascent);      
}
private String getText() {
    return this.text;
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    setMeasuredDimension(viewWidth, viewHeight);
    //setMeasuredDimension(560, 100);even though give a ensured size, it can't //anyway.
}
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    paint.setColor(Color.WHITE);
    paint.setTextSize(30);
    canvas.drawText(text, 0, 200, paint);
    Log.e("content", ""+this.getText());
}
public boolean onTouchEvent (MotionEvent event){
    Log.e("Touch", ""+this.getText());
    return false;

}

}

Here is the Activity:

public class CustomViewActivity extends Activity {
    /** Called when the activity is first created. */
    private RelativeLayout contentLayout;
    private CustomView view1;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        contentLayout = (RelativeLayout)findViewById(R.id.contentLayout);
        view1 = new CustomView(this, "You drive me crazy!!!");
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        view1.setLayoutParams(layoutParams);
        contentLayout.addView(view1);
    }
}

this is the XML file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/contentLayout"
    android:layout_width="1024px"
    android:layout_height="560px"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="126dp"
        android:text="Button" />

</RelativeLayout>

解决方案

You can absolutely set the MeasureSpec to a different size, however, the arguments for onMeasure are misleading. A MeasureSpec is a specially translated int that has to be specifically created by using both a pixel measure and a flag. The correct way to set a specific size it indicated below...

final int desiredHSpec = MeasureSpec.makeMeasureSpec(pixelHeight, MeasureSpec.MODE_CONSTANT);
final int desiredWSpec = MeasureSpec.makeMeasureSpec(pixelWidth, MeasureSpec.MODE_CONSTANT);
setMeasuredDimension(desiredWSpec, desiredHSpec);

The MODE_CONSTANTS must have a value of one of the following: * AT_MOST - meaning that it is dynamic, but will be clipped if the contents are too large * EXACTLY - meaning it will be that size no matter how large or small the contents are * UNSPECIFIED - meaning that it will make whatever decision it makes according to the parameters of the parents, children, device size, etc...

If you do not specify one of these constants, then the Android Layout rendering engine has no idea what to do, and simply hides the object. It must be understood, that as an open platform for so many devices, Google decided to make the layout engine "dynamic and intelligent" to support as many apps as possible on as many platforms as possible. This simply requires the developer to let the device know exactly what it needs.

Note: It sounds like you want EXACTLY, but think carefully about your choice and how many devices you will be supporting. :)

 
精彩推荐
图片推荐