【问题标题】:Android Lollipop, AppCompat ActionBar custom view doesn't take up whole screen widthAndroid Lollipop、AppCompat ActionBar 自定义视图不占用整个屏幕宽度
【发布时间】:2014-12-13 12:46:34
【问题描述】:

所以,我刚刚将我的代码库更新为 Lollipop,但我遇到了操作栏的问题。我正在使用 AppCompat 和 ActionBarActivity,并为自定义视图充气。好像自定义视图不再占据整个屏幕宽度,在左边留下一条细长条

以前的样子

现在的样子

这是我用来设置操作栏的代码。有人有什么想法吗?

final ActionBar actionBar = getSupportActionBar();
if(actionBar != null) {
    actionBar.setDisplayHomeAsUpEnabled(false);
    actionBar.setDisplayShowHomeEnabled(false);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setDisplayShowCustomEnabled(true);
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    actionBar.setCustomView(R.layout.action_bar_content_search_custom_view);
    actionBar.setBackgroundDrawable(null);
    // actionBar.setStackedBackgroundDrawable(null);
    TextView title = (TextView) actionBar.getCustomView().findViewById(R.id.action_bar_title);
    title.setText(R.string.youtube);
    ImageView back = (ImageView) actionBar.getCustomView().findViewById(R.id.action_bar_back);
    back.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });
}

编辑

取出自定义视图并更改背景现在占据了整个宽度。那么问题来了,我们如何才能让 CustomView 占据整个 ActionBar 的宽度呢?

【问题讨论】:

  • 如果暂时注释掉自定义视图部分,是不是表现更好?如果不是,我会倾向于这可能来自您的主题。
  • 我删除了自定义视图,并将其背景设置为 ActionBar 的背景可绘制对象,并且背景现在确实占据了整个宽度
  • 您可能会在层次视图中查看您的活动,无论是否使用自定义视图,看看您是否可以确定哪些布局规则会因自定义视图而发生变化。这可能是新的appcompat-v7 中的一个错误。
  • 在我看来,这是为 up ImageView 保留的位置。尝试为初学者禁用它。
  • 嗨,让自定义视图占据整个宽度似乎是一个很好的解决方案。即使设置了布局权重,我也遇到了它没有扩展的情况。看这里:stackoverflow.com/a/20794736/581574

标签: android android-actionbar android-appcompat android-5.0-lollipop


【解决方案1】:

这似乎是由最近的 appcompat-v7 更新中的 ActionBar 的最新更改引起的。 处理操作栏的方式似乎发生了重大变化。

我遇到了同样的问题,在阅读了ActionBar documentation,尤其是下面的引用之后,我找到了解决方案。

从 Android L(API 级别 21)开始,操作栏可以由应用程序布局中的任何工具栏小部件表示。应用程序可以向 Activity 发出信号,哪个 Toolbar 应该被视为 Activity 的操作栏。使用此功能的活动应使用提供的 .NoActionBar 主题之一,将 windowActionBar 属性设置为 false 或不请求窗口功能。

在我看来,AppCompat 主题发生了变化,一方面似乎破坏了一些东西,但另一方面提供了更多的灵活性。 我建议按照以下步骤操作:

  1. 在您的活动中使用.NoActionBar 样式,如上述引用所述
  2. 在您的 Activity 布局中添加 android.support.v7.widget.Toolbar
  3. 设置app:contentInsetStart="0dp" 属性。 这是您在问题中描述的边距的主要问题
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/actionBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:contentInsetEnd="0dp"
    app:contentInsetStart="0dp" >
</android.support.v7.widget.Toolbar>

通常建议您在单独的布局文件中执行此操作,并在活动布局中使用include,这样如果在多个活动中使用,您只需在一处自定义工具栏

<include layout="@layout/view_action_bar" />
  1. 在您的活动中使用findViewByIdsetSupportActionBar onCreatesignal to the Activity which Toolbar should be treated as the Activity's action bar
Toolbar actionBar = (Toolbar) findViewById(R.id.actionBar);
setSupportActionBar(actionBar);
  1. 执行此操作后,onCreateOptionsMenu 中添加的所有操作都将添加到工具栏中,并将被视为活动操作栏。
  2. 根据需要进一步自定义工具栏(添加子视图等)

【讨论】:

  • 我正在尝试使用带有导航抽屉的工具栏但是我收到错误Error inflating class fragment
  • 所有相关代码都在答案上共享。看起来您应该为您的案例提出一个新问题,因为这似乎是一个不同的问题。
  • 谢谢。我通过用 Toolbar 替换 actionbar 解决了这个问题。
  • 您不应该在命名空间声明中使用明确的包名。使用xmlns:app="http://schemas.android.com/apk/res-auto"
  • 不需要setCustomView。只需使用要包含在工具栏中的小部件构建一个布局文件(例如,将子视图添加到答案第 3 节中描述的布局文件)
【解决方案2】:

而不是像Muzikantthis answer 提到的那样做那么多工作

    getSupportActionBar().setDisplayShowHomeEnabled(false);
    getSupportActionBar().setDisplayShowTitleEnabled(false);
    getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
    LayoutInflater mInflater = LayoutInflater.from(this);

    View mCustomView = mInflater.inflate(R.layout.action_bar_home, null);
    getSupportActionBar().setCustomView(mCustomView);
    getSupportActionBar().setDisplayShowCustomEnabled(true);
    Toolbar parent =(Toolbar) mCustomView.getParent();//first get parent toolbar of current action bar 
    parent.setContentInsetsAbsolute(0,0);// set padding programmatically to 0dp

您只需添加最后两行代码即可解决您的问题。

我希望这可以帮助你和其他人。

更新:在对其进行一些研究后,我发现此解决方案在某些情况下不起作用。左侧间隙(HOME 或 BACK)将被移除,但右侧间隙(MENU)将保持原样。以下是这些情况下的解决方案。

View v = getSupportActionBar().getCustomView();
LayoutParams lp = v.getLayoutParams();
lp.width = LayoutParams.MATCH_PARENT;
v.setLayoutParams(lp);

将这四行添加到上面的代码中,这样右侧的间隙也会从支撑操作栏上移除。

【讨论】:

  • 谢谢!谢谢!最后两行是我一直在寻找的!
  • 我们在哪里添加这些行?在工具栏部分之后?
  • @summers 是的,在工具栏代码之后立即添加它们。
【解决方案3】:

我认为您也可以在样式中做到这一点。尝试这个。在 kitkat 上测试过

<style name="AppTheme" parent="Theme.AppCompat">
  <item name="toolbarStyle">@style/AppThemeToolbar</item>
</style>

<style name="AppThemeToolbar" parent="Widget.AppCompat.Toolbar" >
  <item name="contentInsetStart">0dp</item>
</style>

【讨论】:

  • 这个答案是错误的:android:contentInsetStart requires API level 21 (current min is 14)
  • 但是,成语很好! api 21 和旧版本需要单独编写样式。
  • 如果您仍在使用默认操作栏,这是删除左边距的正确答案。
  • 这确实有效!使用最新版本的支持库,我认为您不需要两次声明属性(android: 不是必需的)。
  • 我一直在寻找这个问题,当我找到你的答案时,我发现我已经投票了!非常感谢。
【解决方案4】:

其他答案都不适合我,所以我查看了实际的 AppCompat v7 样式,发现 here

如果你看一下 Base.Widget.AppCompat.ActionBar 样式,它有:

<item name="contentInsetStart">@dimen/abc_action_bar_content_inset_material</item>
<item name="contentInsetEnd">@dimen/abc_action_bar_content_inset_material</item>

显然我们只需要在我们自己的操作栏样式中覆盖这些属性:

<style name="ActionBar" parent="@style/Base.Widget.AppCompat.ActionBar">
        <item name="contentInsetStart">0dp</item>
        <item name="contentInsetEnd">0dp</item>
</style>

这对我很有用,希望对其他人也有帮助。

【讨论】:

  • 是的,正如所选答案所述,关键是 ActionBar/Toolbar 的 contentInsetStart 和 contentInsetEnd 属性。定义自己的样式是有效的,但是你也可以在你的xml中工具栏的属性上将它们设置为0dp
【解决方案5】:

在我的头撞到显示器之后,这对我有用

 Toolbar toolbar = (Toolbar) actionBar.getCustomView().getParent();
        toolbar.setContentInsetStartWithNavigation(0);
        toolbar.setContentInsetEndWithActions(0);
        toolbar.setContentInsetsAbsolute(0, 0);
        toolbar.setPadding(0, 0, 0, 0);

getCustomView().getParent() 的诀窍是什么

【讨论】:

    【解决方案6】:

    我今天也遇到了这个问题,然后我发现我的项目中有res/values-v21/styles.xml,这是由Android Studio自动生成的,这就是原因。

    为什么?

    因为我res/values-v21/styles.xml的内容是:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <style name="BaseAppTheme" parent="android:Theme.Material.Light">
        </style>
    </resources>
    

    而我的res/values/styles.xml 包含以下内容:

    <style name="BaseAppTheme" parent="android:Theme.Holo.Light">
        <!-- Customize your theme here. -->
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:soundEffectsEnabled">false</item>
    </style>
    

    然后,当我在 Lollipop 上运行我的应用程序时,使用了 res/values-v21/styles.xml,这导致了 OP 遇到的确切问题。 所以我来了一个简单的修复就是删除:

        <style name="BaseAppTheme" parent="android:Theme.Material.Light">
        </style>
    

    res/values-v21/styles.xml

    【讨论】:

      【解决方案7】:

      切入正题:

       ActionBar actionBar = getSupportActionBar();
                      actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
                      actionBar.setCustomView(R.layout.actionbar_layout);
                      Toolbar toolbar = (Toolbar) actionBar.getCustomView().getParent();
                          toolbar.setContentInsetsAbsolute(0, 0);
                          toolbar.setPadding(0, 0, 0, 0);
      

      确保导入正确的工具栏 - android.support.v7.widget.Toolbar;

      【讨论】:

        【解决方案8】:

        用你的代码写这两行

        Toolbar toolbar=(Toolbar)viewActionBar.getParent();
        toolbar.setContentInsetsAbsolute(0,0);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-06
          • 2015-02-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多