Android Lollipop、AppCompat ActionBar 自定义视图不占用整个屏幕宽度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26433409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:25:24  来源:igfitidea点击:

Android Lollipop, AppCompat ActionBar custom view doesn't take up whole screen width

androidandroid-actionbarandroid-appcompatandroid-5.0-lollipop

提问by Stevie Kideckel

So, I just updated my codebase to Lollipop, and I'm having issues with the Action Bar. I'm using AppCompat and ActionBarActivity, and inflating a custom view. It seems that the custom view no longer takes up the whole width of the screen, leaving a thin strip on the left

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

Building with 19Way it used to look

19楼过去的样子

Building with 21Way it looks now

21楼现在的样子

This is the code I'm using to set up the Action Bar. Anyone have any ideas?

这是我用来设置操作栏的代码。谁有想法?

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();
        }
    });
}

Edit

编辑

Taking out the custom view and changing the background now takes up the whole width. So the issue is, how can we make a CustomView take up the whole width of the ActionBar?

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

回答by Muzikant

Looks like this is caused by the latest changes to the ActionBarin the recent appcompat-v7update. It seems like that there are significant changes to how you should handle action bars.

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

I faced the same issue and after reading the ActionBardocumentation, and especially the following quote I found a solution.

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

Beginning with Android L (API level 21), the action bar may be represented by any Toolbar widget within the application layout. The application may signal to the Activity which Toolbar should be treated as the Activity's action bar. Activities that use this feature should use one of the supplied .NoActionBar themes, set the windowActionBar attribute to false or otherwise not request the window feature.

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

The way I see it, the AppCompatthemes were changed and on one hand seemed to break a few things but provide much more flexibility on the other. I recommend following these steps:

在我看来,AppCompat主题发生了变化,一方面似乎打破了一些事情,但另一方面提供了更多的灵活性。我建议遵循以下步骤:

  1. Use .NoActionBarstyle in your activity as described in the above quote
  2. Add a android.support.v7.widget.Toolbarto your Activity layout
  3. Set the app:contentInsetStart="0dp"attribute. This is the main issue with the margin that you describe in your question
  1. 使用.NoActionBar您的活动风格如上面所描述报价
  2. 将 a 添加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>

It's usually recommended that you do that in a separate layout file and use includein your activity layout so you will only need to customize the Toolbar in one place if used in multiple activities

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

<include layout="@layout/view_action_bar" />
  1. Use findViewByIdand setSupportActionBarin your Activity onCreateto signal to the Activity which Toolbar should be treated as the Activity's action bar
  1. 使用findViewByIdsetSupportActionBar您的活动onCreate,以signal to the Activity which Toolbar should be treated as the Activity's action bar
Toolbar actionBar = (Toolbar) findViewById(R.id.actionBar);
setSupportActionBar(actionBar);
  1. Once you do that, all actions added in onCreateOptionsMenuwill be added to the toolbar and it will be treated as the activity action bar.
  2. Further customize the Toolbar as desired (Add child views etc.)
  1. 完成此操作后,添加的所有操作onCreateOptionsMenu都将添加到工具栏,并将被视为活动操作栏。
  2. 根据需要进一步自定义工具栏(添加子视图等)

回答by Amrut Bidri

Instead of doing so much of work as mentioned by Muzikantand like this answer

而不是像Muzikant提到的那样做这么多工作,喜欢这个答案

    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

You have to add only the last two lines of code to solve your problem.

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

I hope this might help you and anyone else.

我希望这可以帮助您和其他任何人。

UPDATE:After making some research on it, i found that this solution will not work in some cases. The left side gap (HOME or BACK) will be removed with this but the right side gap (MENU) will remain as is. Below is the solution in these cases.

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

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

Add these four lines to above code, so that the right side gap is also removed from support action bar.

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

回答by GDA

I think you can also do that in styles. try this. tested it on kitkat

我认为你也可以在样式中做到这一点。尝试这个。在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>

回答by Justin

None of the other answers worked for me, so I took a look at the actual AppCompat v7 styles, found here.

其他答案都不适合我,所以我查看了实际的 AppCompat v7 样式,在此处找到。

If you look at the Base.Widget.AppCompat.ActionBar style, it has:

如果您查看 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>

So obviously we just need to override those properties in our own action bar style:

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

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

This worked great for me, hope it helps others too.

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

回答by user330844

After much beating my head against the monitor, this worked for me

在我的头撞在显示器上很多次之后,这对我有用

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

The getCustomView().getParent() is what did the trick

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

回答by Salman Anjum

to the point:

重点:

 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);

make sure importing the right toolbar - android.support.v7.widget.Toolbar;

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

回答by Anisuzzaman Babla

Write these two line in addition with your code

将这两行与您的代码一起编写

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

回答by Leo

I just encountered this problem today as well, then I found out I was having res/values-v21/styles.xmlinside my project which was generated automatically by Android Studio and that's the cause.

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

Why?

为什么?

Because my res/values-v21/styles.xml's content was:

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

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

And my res/values/styles.xmlcontained something like:

我的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>

Then when I ran my app on Lollipop, the res/values-v21/styles.xmlwas used, and that caused exact problem that OP had. So I came to a simple fix is just deleting:

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

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

in res/values-v21/styles.xml

res/values-v21/styles.xml