自定义视图中相对布局内的文本视图未正确应用重力?

Posted

技术标签:

【中文标题】自定义视图中相对布局内的文本视图未正确应用重力?【英文标题】:Textview inside RelativeLayout in custom View not applying gravity correctly? 【发布时间】:2011-09-07 13:17:53 【问题描述】:

所以我有一个设置,我正在创建自己的视图,并在其中添加一些 TextView。但是,它的重力设置被破坏了。 (它水平居中,但不是垂直居中)我这样做是因为除了 TextViews 之外,我还在我的视图中绘制了其他东西,但这些工作正常。 TextView 的重力只有一个问题。这是我所拥有的部分代码。

public class myView extends View 

    protected RelativeLayout baseLayout;
    protected TextView textView1;
    protected TextView textView2;

    public myView (Context context) 
        super(context);
        setLayoutParams(new LayoutParams(FILL_PARENT, FILL_PARENT));

        baseLayout = new RelativeLayout(context);
        baseLayout.setLayoutParams(new LayoutParams(FILL_PARENT, FILL_PARENT));

        textView1 = new TextView(context);
        // initialize textView1 string, id, textsize, and color here
        textView2 = new TextView(context);
        // initialize textView2 string, id, textsize, and color here

        baseLayout.addView(textView1);
        baseLayout.addView(textView2);
    

    @Override
    public void onDraw(Canvas canvas) 
        super.onDraw(canvas);

        Resources res = getResources();
        // calculate out size and position of both textViews here
        textView1.layout(left1, top1, left1 + width1, top1 + height1);
        textView1.setGravity(Gravity.CENTER);
            textView1.setBackgroundColor(green); // just to make sure it's drawn in the right spot
        textView2.layout(left2, top2, left2 + width2, top2 + height2);
        textView2.setGravity(Gravity.CENTER);
            textView2.setBackgroundColor(blue); // same as above

        baseLayout.draw(canvas);
    

这会将 TextViews 绘制在我想要它们的确切位置和大小(我知道是因为背景颜色),但重力将它们设置为仅水平居中..而不是垂直居中。 (是的,TextView 比实际的文本字符串大)

我可能可以实施此处找到的解决方案 (TextView gravity),但这似乎不是解决此问题的一种非常有效或可靠的方法。我做错了什么导致重力停止正常工作吗?任何输入/帮助表示赞赏。

【问题讨论】:

两件事: 1. 我没有意识到一个 View 可以包含一个 ViewGroup ? 2. 子视图的位置是绝对设置的,为什么要使用RelativeLayout? 没关系 1,我没有意识到 ViewGroup 扩展了 View !! 我发布这个已经有一段时间了,但如果我没记错的话 - AbsoluteLayout 需要不同的构造函数参数,而且使用 RealtiveLayout 更容易......但这可能不准确。 :/ 无论哪种方式-您可能希望某些视图位置是相对的,而某些视图位置是绝对的-谁知道您可能计划了什么。至少您可以选择相对布局。 :) 【参考方案1】:

好的.. 所以我想通了。我只需要在每个 TextView 上运行 measure() 方法。所以我的新代码如下所示:

    textView1.measure(MeasureSpec.makeMeasureSpec(width1, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height1, MeasureSpec.EXACTLY));
    textView1.layout(left1, top1, left1 + width1, top1 + height1);
    textView1.setGravity(Gravity.CENTER);

    textView2.measure(MeasureSpec.makeMeasureSpec(width2, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height2, MeasureSpec.EXACTLY));
    textView2.layout(left2, top2, left2 + width2, top2 + height2);
    textView2.setGravity(Gravity.CENTER);

现在它像它应该的那样水平和垂直居中。如果您遇到同样的问题,请尝试一下。

【讨论】:

另一种方法是在 TextView 上 WRAP_CONTENT 并更改父对齐 (Gravity.CENTER) 或 alignParent..【参考方案2】:

您可以像这样使用 setGravity 设置多个重力参数。

textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL );

看看How do I center text horizontally and vertical in a TextView in android?

【讨论】:

实际上,在我注意到只有“CENTER”是一个选项(它是按位或垂直和水平的组合)之前,这就是我最初的想法。这不会解决这个问题。不过,我确实弄明白了。 (发布在下面)【参考方案3】:

我也遇到了这个问题。我的问题是,当我通过调用 TextView.setGravity() 在 TextView 上设置重力时,它会默默地影响父视图中自身(Textview)的布局。

这是我为解决方法修复所做的:

TextView schedule = getBubbleTextView (item, hasZeroSpanEvent);
// There's a bug in TextView, we need to use wrapper to fix it   
LinearLayout wrapper = new LinearLayout (getApplicationContext ());
wrapper.addView (schedule); 
hourlyBubbleParent.addView (wrapper, llp);

你应该明白应该使用包装器来解决这个问题。

【讨论】:

我很高兴我的一些问题在我问了近 2 年后仍然有用.. ^.^ 如果我再次遇到这个问题,我会考虑这种方法 - 我是不过,想知道它是否是相同的 Android OS 版本,或者即使使用较新的 API 版本,问题是否仍然存在。 (我想我当时在 API 7 编码......可能是 9)

以上是关于自定义视图中相对布局内的文本视图未正确应用重力?的主要内容,如果未能解决你的问题,请参考以下文章

相对布局中的自定义视图问题

自定义文本视图的自动布局支持

自定义 Android 视图在线性和相对布局中显示不同

线性布局内的Android自定义视图与其他视图

自定义视图扩展相对布局

自定义布局未使用约束布局在列表视图中居中