【问题标题】:switch fragments with button (with NavigationDrawer)使用按钮切换片段(使用 NavigationDrawer)
【发布时间】:2013-08-18 19:25:49
【问题描述】:

我有一个NavigationDrawer,我用它在Fragments 之间切换。我想做的是在我的一个片段中有一个按钮,它充当NavigationDrawer 中另一个Fragment 的“快捷方式”。

NavigationDrawer我这样切换片段:

private class DrawerItemClickListener implements
            ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {

            selectItem(position);
        }
    }

public void selectItem(int position) { 

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager
                .beginTransaction();
        String fragmentTag = String.valueOf(position);

        FragmentBase fragment = (FragmentBase) fragmentManager
                .findFragmentByTag(fragmentTag);
        if (null == fragment) { 
            fragment = createFragmentByPosition(position);
        }
        if (null == fragment)
            return;

        if (fragment.isAdded()) {
            fragmentTransaction.show(fragment);
        } else {
            fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag); 
        }

        if (mCurrentFragment != null) {
            fragmentTransaction.hide(mCurrentFragment);
        }
        mCurrentFragment = fragment;
        fragmentTransaction.commitAllowingStateLoss();

        mDrawerList.setItemChecked(position, true);
        setTitle(mNoterActivities[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    private FragmentBase createFragmentByPosition(int position) { // FragmentBase just extends Fragment
        FragmentBase fragment = null;

        if (position == 0) {
            fragment = new Fragment1();
            Bundle args = new Bundle();
            fragment.setArguments(args);

        } else if (position == 1) { // Reminder
            fragment = new Fragment2();
            Bundle args = new Bundle();
            fragment.setArguments(args);

        }

        return fragment;
    }

我不知道该怎么做。我尝试获取 NavigationDrawer 类的实例,然后使用所需位置调用 selectItem,但这不起作用,因为它给出了错误“找不到视图”。

在 NavigationDrawer 类中:

public Navigation_Drawer getInstance() {
        if (null == instance) {
            instance = new Navigation_Drawer();
        }
        return instance;
    }

在 FragmentB 中(位置 1):

//onClick
    Navigation_Drawer nd = new Navigation_Drawer().getInstance(); 
             nd.selectItem(0); // Try to go to FragmentA 

这似乎太简单了,难怪它不起作用!

【问题讨论】:

    标签: android android-fragments navigation-drawer


    【解决方案1】:

    首先,在selectItem方法上,使用add方法代替replace方法:

    public void selectItem(int position) {
    
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        String fragmentTag = String.valueOf(position);
    
        FragmentBase fragment = (FragmentBase) fragmentManager.findFragmentByTag(fragmentTag);
        if (null == fragment) {
            fragment = createFragmentByPosition(position);
        }
        if (null == fragment)
            return;
    
        if (fragment.isAdded()) {
            fragmentTransaction.show(fragment);
        } else {
            // fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag); 
            fragmentTransaction.add(R.id.content_frame, fragment, fragmentTag);
        }
    
        if (mCurrentFragment != null) {
            fragmentTransaction.hide(mCurrentFragment);
        }
        mCurrentFragment = fragment;
        fragmentTransaction.commitAllowingStateLoss();
    
        mDrawerList.setItemChecked(position, true);
        setTitle(mNoterActivities[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }
    

    第二,Navigation_Drawer中的getInstance方法不应该在instance为null时创建新的Navigation_Drawer,在Navigation_Drawer中的onCreate中设置实例为this,然后调用时返回instance getInstance:

    private static Navigation_Drawer mInstance;
    
    public static Navigation_Drawer getInstance() {
        return mInstance;
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mInstance = this;
        // other codes here:
    }
    

    QuickNoteFragment的id为0,PendViewPager的id为1。可以在QuickNoteFragment中转PendViewPager

    Navigation_Drawer.getInstance().selectItem(1);
    

    -

    update1:​​如何将数据传递给片段:

    QuickNoteFragmentHistoryFragement有相同的父类:FragmentBase,我们添加一个名为onDataIn的方法来接收数据:

    public class FragmentBase extends Fragment {
    
        public void function onDataIn(Object data) {
        }
    }
    

    我们应该更改selectItem,添加一个参数来接收数据:

    public void selectItem(int position, Object data) {
    
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        String fragmentTag = String.valueOf(position);
    
        FragmentBase fragment = (FragmentBase) fragmentManager.findFragmentByTag(fragmentTag);
        if (null == fragment) {
            fragment = createFragmentByPosition(position);
        }
        if (null == fragment)
            return;
    
        // call onDataIn() method.
        fragment.onDataIn(data);
    
        if (fragment.isAdded()) {
            fragmentTransaction.show(fragment);
        } else {
            // fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag); 
            fragmentTransaction.add(R.id.content_frame, fragment, fragmentTag);
        }
    
        if (mCurrentFragment != null) {
            fragmentTransaction.hide(mCurrentFragment);
        }
        mCurrentFragment = fragment;
        fragmentTransaction.commitAllowingStateLoss();
    
        mDrawerList.setItemChecked(position, true);
        setTitle(mNoterActivities[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    }
    

    为了使selectItem兼容,我们应该添加一个重载的selectItem方法。

    public void selectItem(int postion) {
        selectItem(position, null);
    }
    

    这样,我们不需要更改旧代码selectItem,也不需要向fragment传递数据。

    【讨论】:

    • 谢谢 srain。我还有一个小问题——如果我在按下按钮时使用它,我会通过按钮将数据从片段传递到我想要的片段。在 start() 上,在 resume() 上没有被调用,所以我无法接收意图。也许 ifVisibleToUser 会起作用。我会试试的。
    • 我给出了一些关于将数据传递给片段的代码,希望对您有所帮助。
    • 谢谢 - 我正在运行它,但是当我在另一个片段中时,我不知道如何检索数据。我在 HistoryFragment 中添加了Navigation_Drawer.getInstance().selectItem(0, "mytext");
    • 您可以覆盖onDataIn方法来处理您要在其中检索数据的片段中的数据。
    猜你喜欢
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    相关资源
    最近更新 更多