导航抽屉 Android 最佳实践

Navigation Drawer Android best practice

我正在 android 中寻找有关导航模式的建议。在我正在使用的应用程序的当前状态下,我有一个导航抽屉,可以访问一些大部分动态更改的元素。当我从导航抽屉中单击一个项目时,我会显示一个片段。所以任何时候我想回到左边的菜单。现在,我必须以相同的方式从图片中移动 "New screen" activity 才能访问抽屉。到达 "New screen" activity 的唯一方法是从其中一个片段。

片段 0 有一个项目列表。单击它会打开 "New screen"。我应该如何处理这个 activity 中的抽屉? 我不想有太多的锅炉代码。 它在 android 4.2.2 上已经有问题,我现在只能想象这种修改将如何影响性能。 我需要了解什么是最佳解决方案,对此没有经验。我想要的只是想法,并且可能会获得一些关于此模式的专业知识,这样我就不会导致内存泄漏并且不会重复代码。

感谢您的宝贵时间。

1-我建议创建一个 Base Activity,它将进一步扩展您的 ActionBarActivity。

2-activity_sliding_drawer 此 activity 的布局文件将包含用于添加片段的 main_container 和 DrawerLayout:-

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

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <FrameLayout
        android:layout_gravity="bottom"
        android:id="@+id/bottom_container"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:background="@color/white">
     </FrameLayout>
</FrameLayout>

<fragment
    android:id="@+id/slidingMenuFragment"
    android:name="om.ooredoo.fragments.SlidingMenuFragment"
    android:layout_width="@dimen/slidingmenu__parent_width"
    android:layout_height="fill_parent"
    android:layout_gravity="start" />

3- 然后在基础 activity 中,我们将拥有添加和替换片段的所有基本功能以及 2 个处理抽屉菜单图标可见性的功能,即 lockDrawerMenu()unlockDrawerMenu().

4- 将以下代码放入您的基础 activity(在我的例子中是 AbstractActivity):-

public abstract class AbstractActivity extends ActionBarActivity {
public DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
private boolean bSupportActionBar = true;
private boolean mSlidingMenuLocked = false;
private BackPressListener mBackPressListener;
private String title;


boolean ismSlidingMenuLocked() {
    return mSlidingMenuLocked;
}


@Override
protected void onCreate(final Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    requestWindowFeature(Window.FEATURE_PROGRESS);
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_sliding_drawer);

    if (bSupportActionBar) {
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerLayout.setScrimColor(getResources().getColor(android.R.color.transparent));

        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_navigation_drawer, //nav menu toggle icon
                R.string.drawer_open, // nav drawer open - description for accessibility
                R.string.drawer_close // nav drawer close - description for accessibility
        ) {

            public void onDrawerClosed(View view) {
                if (getSupportActionBar().getTitle().equals(getString(R.string.app_name)))
                    getSupportActionBar().setTitle(title);
                invalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView) {
                title = (String) getSupportActionBar().getTitle();
                getSupportActionBar().setTitle(getString(R.string.app_name));

                // calling onPrepareOptionsMenu() to hide action bar icons
                invalidateOptionsMenu();
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        unlockDrawerMenu();
    }
}

@Override
protected void onStart() {
    super.onStart();
    setSupportProgressBarIndeterminateVisibility(false);

}


@Override
protected void onDestroy() {
    super.onDestroy();
    if (mHandler != null) {
        mHandler.removeCallbacksAndMessages(null);
        mHandler = null;
    }
}


public void addNewFragmentWithBackStack(Fragment fragment) {
    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.frame_container, fragment, fragment.getClass().getSimpleName())
                .addToBackStack(fragment.getClass().getSimpleName())
                .commit();
    } else {
        Log.e("AbstractActivity", "Error in creating fragment");
    }
}

public void addNewFragmentWithBackStack(Fragment fragment, boolean animation) {
    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.setCustomAnimations(R.anim.slide_up_anim, 0);
        fragmentTransaction.replace(R.id.frame_container, fragment, fragment.getClass().getSimpleName())
                .addToBackStack(fragment.getClass().getSimpleName())
                .commit();
    } else {
        Log.e("AbstractActivity", "Error in creating fragment");
    }
}

public void addNewBottomFragmentWithBackStack(Fragment fragment) {
    if (fragment != null) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.setCustomAnimations(R.anim.slide_up_anim, 0);
        fragmentTransaction.replace(R.id.bottom_container, fragment)
                .addToBackStack(fragment.getClass().getSimpleName())
                .commit();
    } else {
        Log.e("AbstractActivity", "Error in creating fragment");
    }
}






public void replaceAndClearBackStack(Fragment fragment) {
    //clear backStack
    FragmentManager fm = getSupportFragmentManager();
    fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

    FragmentTransaction transaction = fm.beginTransaction();
    transaction.replace(R.id.frame_container, fragment)
            .addToBackStack(fragment.getClass().getSimpleName());
    transaction.commit();
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    if (bSupportActionBar)
        mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggles
    if (bSupportActionBar)
        mDrawerToggle.onConfigurationChanged(newConfig);
}


public void lockDrawerMenu() {
    ((DrawerLayout) findViewById(R.id.drawer_layout)).setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    if (bSupportActionBar) {
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        mDrawerToggle.setDrawerIndicatorEnabled(false);
    }
    mSlidingMenuLocked = true;


}

public void unlockDrawerMenu() {
    ((DrawerLayout) findViewById(R.id.drawer_layout)).setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    mSlidingMenuLocked = false;
    mDrawerToggle.setDrawerIndicatorEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // toggle nav drawer on selecting action bar app icon/title
    if (!ismSlidingMenuLocked() && mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }

    // Handle action bar actions click
    switch (item.getItemId()) {
        case android.R.id.home:
            if (ismSlidingMenuLocked()) {
                onBackPressed();
                return true;
            }
            return true;
        default: {
            return super.onOptionsItemSelected(item);
        }
    }
}

public BackPressListener getBackPressListener() {
    return mBackPressListener;
}

public void setBackPressListener(BackPressListener mBackPressListener) {
    this.mBackPressListener = mBackPressListener;
}

@Override
public void onBackPressed() {
    if (getSupportFragmentManager().getFragments().size() > 0) {
        for (Fragment frag : getSupportFragmentManager().getFragments()) {
            if (frag != null && frag.isAdded() && frag instanceof AbstractParentFragment) {
                if (frag.getChildFragmentManager().getBackStackEntryCount() > 0) {
                    frag.getChildFragmentManager().popBackStack();
                    return;
                }
            }

        }
    }

    if (mBackPressListener != null) {
        if (mBackPressListener.onBackPress())
            return;
    } else {
        if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
            this.finish();
            return;
        }

        super.onBackPressed();
    }
}

void supportActionBar(boolean support) {
    bSupportActionBar = support;
}}

5- 现在创建一个滑动抽屉 activity 来扩展您的基础 activity 并在该主要片段中启动您的主要片段 打开您在滑动抽屉中单击项目的其他片段基础知识。 现在你有两个函数来处理滑动抽屉,如果滑动抽屉图标可见,那么它在点击项目的基础上工作,否则它将是一个带有操作栏的普通片段。

希望这对您有所帮助。 !!!