导航抽屉Android最佳实践

时间:2015-07-22 10:37:56

标签: android performance android-fragments navigation-drawer

我正在寻找关于android中导航模式的建议。在我正在使用的应用程序的当前状态中,我有一个导航抽屉,可以访问一些主要动态更改的元素。当我从导航抽屉中单击某个项目时,我会显示一个片段。所以我想要的任何时候都回到左侧菜单。现在,我必须以相同的模式从图片中移动“新屏幕”活动,以便能够访问抽屉。进入“新屏幕”活动的唯一方法是从其中一个片段。

片段0有一个项目列表。点击它打开“新屏幕”。我应该如何处理这个活动中的抽屉呢? 我不想有太多的锅炉代码。 它已经在android 4.2.2上出现了问题,我现在只能想象这些修改会如何影响性能。 我需要了解什么是最佳解决方案,没有经验。我想要的只是想法,也许在这个模式上获得一些技巧,所以我不会导致内存泄漏,也不会重复代码。

感谢您的时间。

enter image description here

1 个答案:

答案 0 :(得分:4)

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

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

<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-然后在基础活动中,我们将拥有添加和替换片段的所有基本功能,以及2个处理抽屉菜单图标可见性的功能,即lockDrawerMenu()&amp; unlockDrawerMenu()

4-将以下代码放在基本活动中(在我的情况下为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-现在创建一个Sliding抽屉活动,它扩展您的基本活动并在此主片段中启动您的主片段,打开您在滑动抽屉中单击的项目的其他片段基础。 现在你有两个处理滑动抽屉的功能,如果滑动抽屉图标可见,那么它可以用于点击项目的基础知识,否则它将是带有操作栏的正常片段。

希望这会对你有所帮助。 !