Android Lollipop, AppCompat ActionBar пользовательский вид не занимает всю ширину экрана
Итак, я просто обновил свою кодовую базу до 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();
}
});
}
Edit
Извлечение пользовательского представления и изменение фона теперь занимает всю ширину. Таким образом, проблема заключается в том, как мы можем сделать CustomView занимать всю ширину ActionBar?
Ответы
Ответ 1
Похоже, что это вызвано последними изменениями в ActionBar
в недавнем обновлении appcompat-v7
.
Похоже, что есть существенные изменения в том, как вы должны обрабатывать панели действий.
У меня возникла такая же проблема, и после прочтения ActionBar
документации, и особенно следующая цитата, я нашел решение.
Начиная с Android L (уровень API 21), панель действий может быть представлена любым виджнем панели инструментов в макете приложения. Приложение может сигнализировать о том, какую панель инструментов следует рассматривать как панель действий "Действие". Действия, в которых используется эта функция, должны использовать одну из предоставленных тем .NoActionBar, установить атрибут windowActionBar в false или иначе не запрашивать функцию окна.
То, как я это вижу, темы AppCompat
были изменены и, с одной стороны, казалось, сломал несколько вещей, но обеспечил гораздо большую гибкость с другой.
Я рекомендую выполнить следующие действия:
- Используйте стиль
.NoActionBar
в своей деятельности, как описано в приведенной выше цитате.
- Добавить
android.support.v7.widget.Toolbar
в макет вашей деятельности
- Установите атрибут
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" />
- Используйте
findViewById
и setSupportActionBar
в вашей деятельности onCreate
- signal to the Activity which Toolbar should be treated as the Activity action bar
Toolbar actionBar = (Toolbar) findViewById(R.id.actionBar);
setSupportActionBar(actionBar);
- После этого все действия, добавленные в
onCreateOptionsMenu
, будут добавлены на панель инструментов и будут рассматриваться как панель действий.
- Далее настройте панель инструментов по желанию (добавьте дочерние представления и т.д.).
Ответ 2
Вместо того, чтобы выполнять такую большую работу, как упоминалось 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);
Добавьте эти четыре строки в код выше, так что правый боковой зазор также будет удален из панели действий.
Ответ 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>
Ответ 4
Ни один из других ответов не работал у меня, поэтому я взглянул на фактические стили 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>
Это отлично поработало для меня, надеюсь, что это тоже поможет другим.
Ответ 5
Я тоже столкнулся с этой проблемой сегодня, тогда я узнал, что у меня есть 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>
in res/values-v21/styles.xml
Ответ 6
После того, как я сильно ударил головой о монитор, это сработало для меня.
Toolbar toolbar = (Toolbar) actionBar.getCustomView().getParent();
toolbar.setContentInsetStartWithNavigation(0);
toolbar.setContentInsetEndWithActions(0);
toolbar.setContentInsetsAbsolute(0, 0);
toolbar.setPadding(0, 0, 0, 0);
getCustomView(). getParent() - вот что сделал трюк