手动填充自定义视图导致ActionBar自定义视图的布局不同

6

从资源中自定义视图:

// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setCustomView(R.layout.custom_action_bar);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);

结果是:
enter image description here 手动充气的自定义视图:
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
LayoutInflater inflater = (LayoutInflater) this .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.custom_action_bar, null);
actionBar.setCustomView(view);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);

结果是:
在这里输入图片描述 custom_action_bar.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" 
    android:weightSum="3">

    <TextView 
        android:id="@+id/bar_title1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textColor="@color/White"
        android:text="title1"/>
    <TextView 
        android:id="@+id/bar_title2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textColor="@color/White"
        android:text="title2"/>
    <TextView 
        android:id="@+id/bar_title3"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textColor="@color/White"
        android:text="title3"/>

</LinearLayout>

这里展示的第一个布局是正确的,因为它在其小部件上有权重。第二次尝试应该产生相同的结果,但它没有。

1
你能否修改 custom_action_bar.xml 文件中的 android:layout_width 属性,将其改为 fill_parent,并删除 android:weightSum=3 属性?<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="match_parent" android:orientation="horizontal"
如果修改成功,你可以分享一下结果吗?
- Roll no1
@Rollno1 我试过了,你的解决方案可行,fill_parent 部分不需要(fill_parent 等同于 match_parent)。移除 weightsum 属性就可以了。 - ilomambo
2个回答

13

实际上,这里的问题在于第二种情况下ActionBar需要添加额外的布局参数:

    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.custom_action_bar, null);
    actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);

所以,它覆盖了所有的ActionBar区域。看起来默认情况下WRAP_CONTENT布局参数会应用于自定义视图。


有趣。我尝试了你的代码,你是对的。即使自定义布局已经定义了宽度和高度的match_parent。 - ilomambo
没错,但为了应用它,父ViewGroup应该被传递给inflate()。实际上,在setCustomView(int resId)方法中,ActionBarImpl在膨胀过程中使用内部ViewGroup - 例如:setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false)); - sandrstar
我为了将所有空间与我的自定义操作栏匹配而感到非常疯狂。最终,我按照sandrstar所说的添加了LayoutParams来解决了这个问题。 - rolgalan

9

另一个选择是让ActionBar为您完成工作(在这种情况下,我将展示如何使用支持版本来实现)。

// Set your custom view
getSupportActionBar().setCustomView(R.layout.custom_action_bar);

// Get the inflated view
View view = getSupportActionBar().getCustomView();

// Do what you want with the view (set the title, custom font etc.)
TextView actionBarTitle = (TextView) view.findViewById(R.id.action_bar_title);
...

// set the custom flag
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM)

3
聪明的做法先生!在我看来,这应该是被接受的答案。使用Layout Inflater时,将'null'作为根视图是许多布局问题的“万恶之源”,因为与父级相关的layout_*参数在膨胀时会被忽略。 - Maciej Pigulski
好的答案!立刻解决了我的布局问题。 - Matthias Robbers
@MaciejPigulski 在根目录中的“null”不是根本原因,根本原因在于对为什么需要“根”存在的理解不足。唯一修复方法是阅读文档。 - sandrstar
@sandrstar,感谢您宝贵的见解,特别是RTFM部分,非常有帮助! - Maciej Pigulski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接