Android Lollipop、AppCompat ActionBarカスタムビューが画面全体の幅を占めない


97

そのため、コードベースをLollipopに更新しましたが、アクションバーで問題が発生しています。AppCompatとActionBarActivityを使用しており、カスタムビューを拡張しています。カスタムビューが画面の幅全体を占めることがなくなり、左側に細いストリップが残っているようです

19の建物 見た目通り

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の幅全体を占めるようにするにはどうすればよいですか?


カスタムビューパーツを一時的にコメントアウトした場合、動作は向上しますか?そうでない場合、私はおそらくあなたのテーマに由来するこれに傾くでしょう。
CommonsWare 2014年

カスタムビューを削除し、その背景をActionBarの背景ドローアブルとして設定しました。背景は今では幅全体を占めています
Stevie Kideckel '17 / 10/17

カスタムビューがある場合とない場合の両方で、階層ビューのアクティビティをのぞいて、カスタムビューの結果としてどのレイアウトルールがシフトしているかを確認できるかどうかを確認します。これは新しいのバグである可能性がありappcompat-v7ます。
CommonsWare 2014年

upのために予約されている場所ImageViewです。まず、それを無効にしてみてください。
Nikola Despotoski 2014年

1
こんにちは、これはカスタムビューに幅全体を表示させるための良い解決策のようです。レイアウトの重みが設定されていても、拡張されないことがありました。こちらをご覧ください: stackoverflow.com/a/20794736/581574
ratana 2014年

回答:


111

これはActionBar、最近のappcompat-v7更新でのに対する最新の変更が原因であるようです。アクションバーの処理方法に大きな変更があるようです。

私は同じ問題に直面し、ActionBarドキュメントを読んだ後、特に次の引用で解決策を見つけました。

Android L(APIレベル21)以降、アクションバーは、アプリケーションレイアウト内の任意のツールバーウィジェットで表すことができます。アプリケーションは、どのツールバーをアクティビティのアクションバーとして扱うかをアクティビティに通知する場合があります。この機能を使用するアクティビティでは、提供されている.NoActionBarテーマのいずれかを使用するか、windowActionBar属性をfalseに設定するか、ウィンドウ機能を要求しないようにする必要があります。

私の見方では、AppCompatテーマが変更され、一方ではいくつかの問題が解決されているように見えますが、他方では柔軟性が大幅に向上しています。次の手順に従うことをお勧めします。

  1. .NoActionBar上記の引用で説明されているように、アクティビティでスタイルを使用してください
  2. 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. 必要に応じてツールバーをさらにカスタマイズします(子ビューを追加するなど)。

1
ナビゲーションドロワーでツールバーを使用しようとしていますが、エラーが発生しますError inflating class fragment
Ahmed Nawaz 2014年

関連するすべてのコードが回答で共有されます。別の問題のように思われるため、ケースに対して新しい質問を開始する必要があるようです。
ムジカント2014年

ありがとう。actionbarをToolbarに置き換えることで問題を解決しました。
Ahmed Nawaz、2014年

9
名前空間宣言では、明示的なパッケージ名を使用しないでください。使用xmlns:app="http://schemas.android.com/apk/res-auto"
リミナル2014年

1
の必要はありませんsetCustomView。ツールバーに含めるウィジェットを使用してレイアウトファイルを作成するだけです(たとえば、回答のセクション3で説明されているレイアウトファイルに子ビューを追加します)
Muzikant

51

ムジカントが言ったように多くの仕事をする代わりに、この答えのように

    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

問題を解決するには、コードの最後の2行だけを追加する必要があります。

これがあなたや他の誰にも役立つことを願っています。

更新:いくつかの調査を行った後、このソリューションが機能しない場合があることを発見しました。これにより、左側のギャップ(HOMEまたはBACK)は削除されますが、右側のギャップ(MENU)はそのまま残ります。以下は、これらの場合の解決策です。

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

これらの4行を上記のコードに追加して、右側のギャップもサポートアクションバーから削除されるようにします。


ありがとう!ありがとう!最後の2行は私が探していたものでした!
digitalmidges 2015年

これらの行はどこに追加しますか?ツールバー部分の後?
Zen

1
@summersはい、ツールバーのコードの直後に追加します。
Amrut Bidri

31

スタイル的にもできると思います。これを試して。キットカットでテストした

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

1
この答えは間違っています:android:contentInsetStartにはAPIレベル21(現在の最小値は14)が必要です
mr.boyfox 2014年

しかし、イディオムはとても良いです!API 21と古いバージョンでは、スタイルを個別に記述する必要があります。
mr.boyfox 2014年

これは、デフォルトのアクションバーをまだ使用している場合に、左マージンを削除する正しい答えです。
Tooroop、2014

これは確かに機能します!サポートライブラリの最新バージョンでは、属性を2回宣言する必要はないと思います(android:1は必要ありません)。
BoDの

私はこの問題を探していましたが、あなたの答えを見つけたとき、私はすでにそれを支持していることがわかりました!2回ありがとう。
user1732313

8

他の答えはどれもうまくいかなかったので、ここにある実際の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>

これは私にとってはうまくいきました。他の人にも役立つことを願っています。


ええ、選択された回答が述べるように、キーはActionBar / ToolbarのcontentInsetStartおよびcontentInsetEnd属性です。独自のスタイルを定義することは有効ですが、XMLのツールバーの属性でそれらを0dpに設定することもできます
Stevie Kideckel

1

モニターに対して頭を何度も叩いた後、これは私のために働いた

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

getCustomView()。getParent()はトリックをしたものです


0

今日もこの問題に遭遇したばかりですが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

ポイントへ:

 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

あなたのコードに加えてこれらの2行を書きます

Toolbar toolbar=(Toolbar)viewActionBar.getParent();
toolbar.setContentInsetsAbsolute(0,0);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.