it-swarm.com.ru

Android Lollipop, AppCompat Пользовательское представление ActionBar не занимает всю ширину экрана

Итак, я только что обновил свою кодовую базу до Lollipop, и у меня возникли проблемы с панелью действий. Я использую AppCompat и ActionBarActivity и раздуваю собственное представление. Кажется, что пользовательский вид больше не занимает всю ширину экрана, оставляя тонкую полосу слева

Building with 19 Как это выглядело раньше

Building with 21 Как это выглядит сейчас

Это код, который я использую для настройки панели действий. У кого-нибудь есть идеи?

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?

96
Stevie Kideckel

Похоже, что это вызвано последними изменениями ActionBar в недавнем обновлении appcompat-v7 . Похоже, что есть значительные изменения в том, как вы должны обрабатывать панели действий.

Я столкнулся с той же проблемой, и после прочтения ActionBar документации , и особенно в следующей цитате, я нашел решение.

Начиная с Android L (уровень API 21), панель действий может быть представлена ​​любым виджетом панели инструментов в макете приложения. Приложение может сигнализировать Деятельности, какая Панель инструментов должна рассматриваться как панель действий Деятельности. Действия, которые используют эту функцию, должны использовать одну из предоставленных тем .NoActionBar, установить атрибут windowActionBar в false или иначе не запрашивать функцию окна.

На мой взгляд, темы AppCompat были изменены, и, с одной стороны, казалось, что они сломали несколько вещей, но с другой стороны, обеспечивают гораздо большую гибкость .... Я рекомендую выполнить следующие шаги:

  1. Используйте стиль .NoActionBar в своей деятельности, как описано в приведенной выше цитате
  2. Добавьте Android.support.v7.widget.Toolbar в свой макет Activity
  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. Используйте findViewById и setSupportActionBar в своей деятельности от 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. После этого все действия, добавленные в onCreateOptionsMenu, будут добавлены на панель инструментов и будут рассматриваться как панель действий.
  2. Далее настройте панель инструментов по своему усмотрению (добавьте дочерние представления и т.д.)
109
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

Вы должны добавить только последние две строки кода, чтобы решить вашу проблему.

Я надеюсь, что это может помочь вам и кому-либо еще.

ОБНОВЛЕНИЕ: После некоторых исследований я обнаружил, что это решение не будет работать в некоторых случаях. При этом будет удален левый боковой зазор (HOME или BACK), но правый боковой зазор (MENU) останется как есть. Ниже приведено решение в этих случаях.

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

Добавьте эти четыре строки в приведенный выше код, чтобы правая боковая щель также была удалена из панели действий поддержки. 

51
Amrut Bidri

Я думаю, что вы также можете сделать это в стилях. попробуй это. проверил это на 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>
30
GDA

Ни один из других ответов не помог мне, поэтому я взглянул на стили AppCompat v7, найденные здесь .

Если вы посмотрите на стиль 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>

Это отлично сработало для меня, надеюсь, это поможет и другим.

8
Justin

После того, как я сильно ударился головой о монитор, это сработало для меня

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

GetCustomView (). GetParent () - это то, что сработало

1
user330844

Запишите эти две строки в дополнение к вашему коду

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

Я только что столкнулся с этой проблемой и сегодня, а потом обнаружил, что внутри моего проекта есть 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

0
Leo

к точке: 

 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;

0
Salman Anjum