导航抽屉和片段后台处理程序

时间:2013-09-19 12:14:01

标签: android android-fragments navigation-drawer

我一直在阅读有关片段和片段后退处理的内容,但仍然无法找到最佳解决方案。

我有导航抽屉。

让我假装我的导航抽屉列表中有2个项目(item1,item2) 当我点击item1时,它会打开一个片段。单击按钮后在片段中打开B片段。所以当打开B片段并从导航抽屉中选择item2时会打开C Fragment。

现在当我按下后退按钮它应该完成活动而不是去B片段。

所以在我选择item1的时候,item2打开一个片段或C片段,按下后退按钮后应该完成活动但是当打开B片段(在item1下面)时它必须返回到片段

请帮助我对我来说非常困难。感谢

public class MainActivity extends DefaultActivity {
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggleWrapper mDrawerToggle;
    private ListView mDrawerListView;
    private TextView mTitle;
    private Runnable mPendingRunnable;
    private Handler mHandler;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mDrawerListView = (ListView) findViewById(R.id.left_drawer);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mFragmentManager = getSupportFragmentManager();
        mHandler = new Handler();

        LayoutInflater inflator = (LayoutInflater) this .getSystemService(LAYOUT_INFLATER_SERVICE);
        View v = inflator.inflate(R.layout.custom_view, null);
        mTitle = (TextView)v.findViewById(R.id.title);

        getSupportActionBar().setBackgroundDrawable(null);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        getSupportActionBar().setDisplayShowCustomEnabled(true);
        getSupportActionBar().setDisplayUseLogoEnabled(false);
        getSupportActionBar().setDisplayShowHomeEnabled(false);
        getSupportActionBar().setIcon(R.drawable.button_indicator_menu);
        getSupportActionBar().setCustomView(v);

        v.findViewById(R.id.menu).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!mDrawerLayout.isDrawerOpen(GravityCompat.START)){
                    mDrawerLayout.openDrawer(GravityCompat.START);
                }else {
                    mDrawerLayout.closeDrawers();
                }
            }
        });

        mDrawerToggle = new ActionBarDrawerToggleWrapper(this, mDrawerLayout, R.drawable.transparent_gic, R.string.drawer_open, R.string.drawer_close){
            public void onDrawerClosed(View view) {
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                if (mPendingRunnable != null) {
                    mHandler.post(mPendingRunnable);
                    mPendingRunnable = null;
                }
            }

            public void onDrawerOpened(View drawerView) {
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };
        mDrawerToggle.addPartnerToggle(new ContentDisplaceDrawerToggle(this, mDrawerLayout, R.id.content_frame));
        mDrawerToggle.setDrawerIndicatorEnabled(true);
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        setLeftDrawerLeftMenu();

        getFragment(getString(R.string.home));
        setTitle(getString(R.string.home));
    }

    private void setLeftDrawerLeftMenu(){
        final ArrayList<Item> items = new ArrayList<Item>();
        items.add(new SectionItem(this,"icons_small_home",getString(R.string.home)));

        items.add(new SectionItem(this,"icons_small_myacounts",getString(R.string.my_account)));
        items.add(new EntryItem(getString(R.string.bonuses)));
        items.add(new EntryItem(getString(R.string.account_recharge)));
        items.add(new EntryItem(getString(R.string.tariff_plans)));
        items.add(new EntryItem(getString(R.string.languages)));


        EntryAdapter adapter = new EntryAdapter(MainActivity.this, items);

        mDrawerListView.setAdapter(adapter);

        mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                EntryItem item = (EntryItem) items.get(i);
                    setTitle(item.getTitle());
            }
        });
    }


    public void setTitle(final String title){
        mTitle.setText(title);
        mPendingRunnable = new Runnable() {
            @Override
            public void run() {
                getFragment(title);
            }
        };

        mDrawerLayout.closeDrawers();
    }

    public void getFragment(String name){
        if(getString(R.string.orange_shops).equalsIgnoreCase(name)){
            if (!(mSelectedFragment instanceof OrangeShopsFragment)){
                addPage(new MyFragment(MainActivity.this),true);
            }
        }else if(getString(R.string.home).equals(name)){
            addPage(new HomeFragment(MainActivity.this),false);
        }else{
            throw new RuntimeException("unknown fragment "+ name);
        }
    }

 public void addPage(final DefaultFragment pDefaultFragment, final boolean isAddToBackStack){
        FragmentTransaction transaction = mFragmentManager.beginTransaction();
        transaction.replace(R.id.content_frame, pDefaultFragment);
        if (isAddToBackStack) transaction.addToBackStack(null);
        transaction.commitAllowingStateLoss();
    }
}

2 个答案:

答案 0 :(得分:3)

清除后桅并不是那么困难。

每当用户点击抽屉上的任何项目时,只需致电

while(getSupportFragmentManager.popBackStackImmediate()){}

清除之前的内容。

修改

我知道这是一个老问题,但我找到了一种更好/更有效的方法:

fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

这是由一位Android工程师在groups.google.com中回答的,我在我的应用上替换了它,而“clear stack”命令现在的工作速度要快得多。希望它有所帮助。

答案 1 :(得分:1)

我在使用片段和导航抽屉时也遇到了这个问题。当我们从一个片段导航到另一个片段时,它们都被添加到相同的后台堆栈中。这就是你遇到这个问题的原因。为了克服这个问题,我自己维护了堆栈并处理了背压方法

如果你发布你的代码,我会为你的问题提出一个很好的解决方案