web-dev-qa-db-ja.com

フラグメントの代わりにアクティビティを切り替えるナビゲーションドロワー

Androidでナビゲーションドロワーを使用することはできますが、フラグメントを更新する代わりに、アプリ内のナビゲーションの手段としてアクティビティを切り替えたいと思います。

46
Little Tiny Dev

はい、可能です-それは私がアプリのためにしたことです。すでに多くのアクティビティが設定されており、それらをすべてフラグメントに変換するのではなく、ナビゲーションドロワーを調整してすべてのアクティビティで機能するようにしたいと考えました。残念ながら、それは簡単な回避策ではないので、フラグメントを使用するオプションがあれば、それでいいでしょう。しかし、ここで私がそれをした方法に関係なく:

たとえば、2つのアクティビティがあり、どちらもNavigation Drawerが必要だとします。それぞれのlayout.xmlで、ナビゲーションオプションを保持するために、適切なDrawerLayoutとともにListViewを指定しました。基本的に、アクティビティを切り替えるたびにナビゲーションドロワーが作成され、永続化されているように見えます。生活をずっと楽にするために、ナビゲーションドロワーのセットアップに必要な一般的なメソッドを使用して、独自のクラスNavigationDrawerSetup.Javaに配置しました。そうすれば、私のアクティビティは同じカスタムアダプタなどを使用できます。

このNavigationDrawerSetup.Javaクラス内には、次のものがあります。

  • configureDrawer()-これは、ActionBarActionBarDrawerToggle、および必要なリスナーを設定します
  • カスタムアレイアダプター(リスト内のナビゲーションオプションを設定するため)
  • 引き出しアイテムのクリックを処理するselectOptions()メソッド

アクティビティの1つにナビゲーションドロワーを設定するとき、新しいNavigationDrawerSetupオブジェクトを作成し、必要なレイアウトパラメーター(DrawerLayoutListViewなど)を渡すだけです。次に、configureDrawer()を呼び出します。

        navigationDrawer = new NavigationDrawerSetup(mDrawerView, mDrawerLayout,
            mDrawerList, actionBar, mNavOptions, currentActivity);

    navigationDrawer.configureDrawer();

ナビゲーションドロワーは現在のアクティビティに関連付けられているため、currentActivityが渡されます。 ActionBarDrawerToggleをセットアップするときに使用する必要があります。

mDrawerToggle = new ActionBarDrawerToggle(currentActivity, // Host Activity
        mDrawerLayout, /* DrawerLayout object */
        R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
        R.string.drawer_open, /* "open drawer" description for accessibility */
        R.string.drawer_close /* "close drawer" description for accessibility */
        )

また、カスタムcurrentActivityをセットアップするときにAdapterを使用する必要があります。

ナビゲーションドロワーを介してアクティビティを切り替える方法については、selectItem()メソッド内で新しいインテントを設定するだけです。

private void selectItem(int position) {

    // Handle Navigation Options
    Intent intent;
    switch (position) {
        case 0:
            intent = new Intent(currentActivity, NewActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            currentActivity.startActivity(intent);
            break;
        case 1: 
            // etc.
    }

新しいActivityにもナビゲーションドロワーのセットアップがあり、表示されることを確認してください。

このメソッドを自分のニーズに合わせてカスタマイズするためにできることは山ほどありますが、これは私がやった方法の一般的な構造です。お役に立てれば!

48
David Crozier

Navigation Drawerを実装するBaseDrawerActivityが必要で、Navigation Drawerが必要な各アクティビティでBaseDrawerActivityを拡張します。

最初にBaseDrawerActivity.Javaを作成します:

public class BaseDrawerActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{

    DrawerLayout drawerLayout;
    Toolbar toolbar;
    FrameLayout frameLayout;
    NavigationView navigationView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.activity_base_drawer);;

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        frameLayout = (FrameLayout) findViewById(R.id.content_frame);

        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawerLayout.setDrawerListener(toggle);
        toggle.syncState();

        navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
    }

    @Override
    public void onBackPressed() {
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
            drawerLayout.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

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

        //to prevent current item select over and over
        if (item.isChecked()){
            drawerLayout.closeDrawer(GravityCompat.START);
            return false;
        }

        if (id == R.id.nav_camera) {
            // Handle the camera action
            startActivity(new Intent(getApplicationContext(), CameraActivity.class));
        } else if (id == R.id.nav_gallery) {
            startActivity(new Intent(getApplicationContext(), GalleryActivity.class));
        } else if (id == R.id.nav_slideshow) {
            startActivity(new Intent(getApplicationContext(), SlideshowActivity.class));
        } else if (id == R.id.nav_manage) {
            startActivity(new Intent(getApplicationContext(), ManageActivity.class));
        } else if (id == R.id.nav_share) {
            startActivity(new Intent(getApplicationContext(), ShareActivity.class));
        } else if (id == R.id.nav_send) {
            startActivity(new Intent(getApplicationContext(), SendActivity.class));
        }
        drawerLayout.closeDrawer(GravityCompat.START);
        return true;
    }
}

activity_base_drawer.xmlフォルダーにres/layoutを作成します。

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:openDrawer="start">

    <include layout="@layout/app_bar_home"/>

    <Android.support.design.widget.NavigationView
        Android:id="@+id/nav_view"
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        app:headerLayout="@layout/nav_header_home"
        app:menu="@menu/activity_home_drawer" />

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

ここで、@layout/app_bar_homeは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.CoordinatorLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true">

    <Android.support.design.widget.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:theme="@style/AppTheme.AppBarOverlay">

        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </Android.support.design.widget.AppBarLayout>

    <FrameLayout Android:id="@+id/content_frame"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

</Android.support.design.widget.CoordinatorLayout>

次に、CameraActivity.Javaなどのナビゲーションドロワーを持つアクティビティを入力します。

public class CameraActivity extends BaseDrawerActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getLayoutInflater().inflate(R.layout.activity_camera, frameLayout);

        /**
        * Setting title
        */
        setTitle("Camera");

    }

    @Override
    protected void onResume() {
        super.onResume();
        // to check current activity in the navigation drawer
        navigationView.getMenu().getItem(0).setChecked(true);
    }
}

R.layout.activity_cameraCameraActivity.Javaのレイアウトです。

次に、GalleryActivity.Javaなどのナビゲーションドロワーを持つ他のアクティビティを作成します。

public class GalleryActivity extends BaseDrawerActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getLayoutInflater().inflate(R.layout.activity_gallery, frameLayout);

        // Setting title
        setTitle("Gallery");

    }

    @Override
    protected void onResume() {
        super.onResume();
        navigationView.getMenu().getItem(1).setChecked(true);
    }
}
15
kazi.munshimun

@ David-Crozierが指摘したソリューションの少しの改善として、両方のアニメーションの重複(NavigationDrawerを閉じて新しいアクティビティを開始する)を避けるために、ioschedアプリで行われたようにメソッドに少し遅延を含めることができます。 v2014:

private void onNavDrawerItemClicked(final int itemId) {
    if (itemId == getSelfNavDrawerItem()) {
        mDrawerLayout.closeDrawer(GravityCompat.START);
        return;
    }

    if (isSpecialItem(itemId)) {
        goToNavDrawerItem(itemId);
    } else {
        // launch the target Activity after a short delay, to allow the close animation to play
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                goToNavDrawerItem(itemId);
            }
        }, NAVDRAWER_LAUNCH_DELAY);

        // change the active item on the list so the user can see the item changed
        setSelectedNavDrawerItem(itemId);
        // fade out the main content
        View mainContent = findViewById(R.id.main_content);
        if (mainContent != null) {
            mainContent.animate().alpha(0).setDuration(MAIN_CONTENT_FADEOUT_DURATION);
        }
    }

    mDrawerLayout.closeDrawer(GravityCompat.START);
}

ここに参照用リンク: https://github.com/google/iosched/blob/master/Android/src/main/Java/com/google/samples/apps/iosched/ui/BaseActivity.Java

2
narko

フラグメントマネージャーは、投稿に記載されているように置き換えることができます。

https://guides.codepath.com/Android/fragment-navigation-drawer#alternative-to-fragments

フラグメントマネージャーを使用する代わりに、レイアウトを拡張できます。

0
Logan