0

私のアプリには、DrawerLayoutNavigationView(android.support.design.widget.NavigationView) を使用した 2 つのアクティビティがあります。

Theme.AppCompat.Light.DarkActionBarでアプリのテーマを使用していますが、Lollipop エミュレーターでは問題ありません。

しかし、私の Jellybean デバイスとエミュレーターでは、非常に奇妙な動作をします。

アイテムの背景は、NavigationView明るい灰色 (私には問題ありません) でレンダリングされることもあれば、明るい青色の色合いでレンダリングされることもあります (テーマ ホロのデフォルトだと思います)。

私の「実際の」アプリでは、灰色の色合いは常に最初の引き出しに表示され、青い色合いは常に他の引き出しに表示されます。最初は違いは、最初のものは anActionBarDrawerToggleを使用し、他のものは使用しないなどの詳細が原因である可能性があると考えていたので、何らかの方法でandroid:listSelectorを 2 番目のもののみに設定する必要があったのかもしれません。

そこで、MCVE のようなサンプルを作成したところ、両方の引き出しが時々両方の色合いを示していることに気付きました。これはバグですか、それとも何か不足していますか?

Theme Holo を取り除くにはどうすればよいですか?

スクリーンショット:

メイン ドロワー ブルーとグレーの色合い

ところで、私はActionButton背景に対して同じランダムな振る舞いをしています:

MainActivity 青と灰色のアクション ボタン

私のコード(独自のテストを実行したい人のための〜95%):

activity_main.xmlは、中央に大きな「Hello World」がある単なる「空白のアクティビティ」です。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true">

    <TextView
        android:text="@string/hello_world"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>

activity_main_decor.xml

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"/>

    <android.support.design.widget.NavigationView
        android:id="@+id/main_drawer"
        android:layout_width="@dimen/nav_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/menu_main_drawer"/>
</android.support.v4.widget.DrawerLayout>

activity_other.xml

<merge>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    <TextView
        android:text="Hello again!"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>
</merge>

activity_other_decor.xml

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout android:id="@+id/container"
             android:orientation="vertical"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent">
        <include layout="@layout/activity_other"/>
    </FrameLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/other_drawer"
        android:layout_width="@dimen/nav_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="end"
        app:menu="@menu/menu_other_drawer" />

</android.support.v4.widget.DrawerLayout>

MainActivity - ナビゲーション ドロワーは、左と上から表示する必要があります(非常に便利な行ActionBarについて @Peter Cai に感謝します) 。

public class MainActivity extends AppCompatActivity
{
private static final String             TAG = "StyleForDrawers main";
private static final String             DRAWER_OPEN = "main_drawer_open";

private DrawerLayout                    drawerLayout;
private NavigationView                  navigationView;
private ActionBarDrawerToggle           drawerToggle;
private boolean                         isDrawerOpen;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initNavDrawer();
}

private void initNavDrawer()
{
    final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(this);

    LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    drawerLayout = (DrawerLayout) inflater.inflate(R.layout.activity_main_decor, null);

    ViewGroup decor = (ViewGroup)activity.getWindow().getDecorView();
    View child = decor.getChildAt(0);
    decor.removeView(child);

    FrameLayout container = (FrameLayout)drawerLayout.findViewById(R.id.container);
    container.addView(child);
    decor.addView(drawerLayout);

    navigationView = (NavigationView) findViewById(R.id.main_drawer);
    navigationView.setItemTextColor(ContextCompat.getColorStateList(this, R.color.nav_item));
    navigationView.setItemTextAppearance(R.style.MyNavdrawerTextAppearance);
    View headerView = navigationView.inflateHeaderView(R.layout.navdrawer_list_header);

    // header View should appear below status bar, so set padding:
    (headerView.findViewById(R.id.nav_header_root)).setPadding(0, getStatusbarHeight(), 0, (int) getResources().getDimension(R.dimen.activity_vertical_margin));

    navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener()
    {
        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem)
        {
            Intent intent = null;
            int id = menuItem.getItemId();

            if (id == R.id.action_other_activity)
            {
                intent = new Intent(MainActivity.this, OtherActivity.class);
            }
            // -- skipped some code for Help etc. --

            drawerLayout.closeDrawer(navigationView);
            isDrawerOpen = false;

            if (intent != null)
            {
                intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                startActivity(intent);
            }

            return true;
        }
    });

    drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.sDrawerOpen, R.string.sDrawerClose)
    {

        @Override
        public void onDrawerClosed(View drawerView)
        {
            super.onDrawerClosed(drawerView);
            sPrefs.edit().putBoolean(DRAWER_OPEN, false).apply();
        }

        @Override
        public void onDrawerOpened(View drawerView)
        {
            isDrawerOpen = true;
            super.onDrawerOpened(drawerView);
            sPrefs.edit().putBoolean(DRAWER_OPEN, true).apply();
        }
    };

    drawerLayout.setDrawerListener(drawerToggle);

    if (getSupportActionBar() != null)
    {
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setHomeAsUpIndicator(R.drawable.nav_drawer);
    }

    if (sPrefs.getBoolean(DRAWER_OPEN, true)) // open at first launch
    {
        drawerLayout.openDrawer(navigationView);
    }
    else
    {
        drawerLayout.closeDrawer(navigationView);
    }
}

@Override
protected void onPause()
{
    super.onPause();
    SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(this);
    sPrefs.edit().putBoolean(DRAWER_OPEN, isDrawerOpen).apply();
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    return drawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
}

public static int getStatusbarHeight()
{
    int retValue = 0;
    int resID = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resID > 0) {
        retValue = getResources().getDimensionPixelSize(resID);
    }
    return retValue;
}

}

OtherActivity - ドロワーはコンテキスト メニューのようなもので、次のものと重なることなく右から表示されますActionBar

public class OtherActivity extends AppCompatActivity
{
    private static final String             TAG = "StyleForDrawers other";
    private static final String             DRAWER_OPEN = "other_drawer_open";

    private DrawerLayout                    mDrawerLayout;
    private NavigationView                  mNavigationView;
    private boolean                         mIsDrawerOpen;


@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_other_decor);
    initMenuDrawer();
}

private void initMenuDrawer()
{
    final SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(this);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    mNavigationView = (NavigationView) findViewById(R.id.other_drawer);
    mNavigationView.setItemTextColor(ContextCompat.getColorStateList(this, R.color.nav_item));
    mNavigationView.setItemTextAppearance(R.style.MyNavdrawerTextAppearance);

    mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener()
    {
        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem)
        {
            int id = menuItem.getItemId();

            if (id == R.id.action_back_to_main)
            {
                finish();
            }
            // -- skipped some code for doing something (else) --
            mDrawerLayout.closeDrawer(mNavigationView);
            mIsDrawerOpen = false;
            return true;
        }
    });

    mDrawerLayout.setDrawerListener(new DrawerLayout.SimpleDrawerListener()
    {
        @Override
        public void onDrawerOpened(View drawerView)
        {
            super.onDrawerOpened(drawerView);
            mIsDrawerOpen = true;

            sPrefs.edit().putBoolean(DRAWER_OPEN, true).apply();
        }

        @Override
        public void onDrawerClosed(View drawerView)
        {
            super.onDrawerClosed(drawerView);
            mIsDrawerOpen = false;
            sPrefs.edit().putBoolean(DRAWER_OPEN, false).apply();
        }

    });

    if (sPrefs.getBoolean(DRAWER_OPEN, false)) // don't open at first launch
    {
        mDrawerLayout.openDrawer(mNavigationView);
    }
    else
    {
        mDrawerLayout.closeDrawer(mNavigationView);
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    getMenuInflater().inflate(R.menu.menu_other, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    int id = item.getItemId();

    if (id == R.id.action_opendrawer)
    {
        if (mIsDrawerOpen)
        {
            mDrawerLayout.closeDrawer(mNavigationView);
        }
        else
        {
            mDrawerLayout.openDrawer(mNavigationView);
        }
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}

menu_main.xml不要

menu_other.xmlには、ドロワーを開閉するためのアクション ボタンが含まれています。

<menu xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto">

  <item android:id="@+id/action_opendrawer"
      android:title="open/close drawer"
      android:icon="@drawable/nav_drawer"
      android:orderInCategory="100"
      app:showAsAction="always"/>
</menu>

スタイル.xml

<resources>
    <color name="accent_orange">#ff6d00</color>
    <color name="my_background">#eeeeee</color>
    <color name="my_text">#311b92</color>
    <color name="my_sec_text">#B1311b92</color>
    <color name="my_actionbar">#1a237e</color>
    <color name="my_statusbar">#1a237e</color>

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

    <item name="colorPrimary">@color/my_actionbar</item>
    <item name="colorPrimaryDark">@color/my_statusbar</item>
    <item name="colorAccent">#ffc400</item>
    <item name="android:windowBackground">@color/my_background</item>
    <item name="android:textColorPrimary">@color/my_text</item>
    <item name="android:textColor">@color/my_text</item>
    <item name="android:textColorSecondary">@color/my_sec_text</item>
</style>

<style name="MyNavdrawerTextAppearance" parent="TextAppearance.AppCompat.Small">
    <item name="android:textStyle">bold</item>
</style>
</resources>

更新 (2016 年 5 月)

その間、NavigationViewアイテムの独自の背景を設定することも試みました。背景が変更されましたが、タッチすると、ロリポップ以上のリップルが表示されます (これは問題ありません)。残念ながら、おそらく操作方法がわからないある種のリストセレクターから、ジェリービーンに交互の効果が得られます。

更新 2 (2016 年 9 月)

Android Studio の新しいバージョンをインストールし、最新バージョンのビルド ツールとすべてのライブラリ (それぞれ 24.0.2 24.2.0) を使用ActionBarし、Toolbar. 最後の手段は、メインでハックを使用してナビゲーション ドロワーをカバーする必要がないことを意味するためActionBar、コードで LayoutInflater を使用しなくなりました。

しかし、まだ運がありません:(

これはバグであると確信しています。同じコードがアプリの実行ごとに異なる動作をし、同じ実行中に Main アクティビティと Other アクティビティの間一貫性がありません。

4

0 に答える 0