使用 recyclerview 的片段,使用 otto 刷新数据

Fragment with recyclerview, refreshing data with otto

我正在尝试使用 Otto 来实现以下用例。

我有一个带有片段的 Viewpager,每个片段包含一个 RecyclerView。回收站视图显示 post 用户 post 使用该应用。这些片段中的每一个都附加了一个新的 post 按钮。单击 post Button 后,用户将被带到一个新的 activity 并且他 post 在那里的内容。当他再次回到 ViewPager 片段屏幕时,我希望片段屏幕刷新并显示更新后的内容。我为此使用奥托。

当只有一个片段存在时,我能够完成这项工作。

public class PlaceholderFragment extends Fragment {

private static final String ARG_SECTION_NUMBER = "section_number";


public static PlaceholderFragment newInstance(int sectionNumber) {
    PlaceholderFragment fragment = new PlaceholderFragment();
    Bundle args = new Bundle();
    args.putInt(ARG_SECTION_NUMBER, sectionNumber);
    fragment.setArguments(args);
    return fragment;
}


public PlaceholderFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    BusProvider.getInstance().register(this);
}

我在 PlaceholderFrame 的 onCreate 方法中调用了注册方法。很明显,当多次加载多个片段时,我会收到以下错误。我该如何处理?

Process: com.four.xxxx.xx, PID: 9934
java.lang.IllegalArgumentException: Object already registered.
        at com.squareup.otto.Bus.register(Bus.java:222)
        at com.four.xxxx.xx.PlaceholderFragment.onCreateView(PlaceholderFragment.java:94)
        at android.app.Fragment.performCreateView(Fragment.java:2053)

编辑 1:PagerAdapter Class 根据要求:

    public class FourScreenActivity extends Activity {

    SectionsPagerAdapter mSectionsPagerAdapter;
    ViewPager mViewPager;
    static final int POST_DEPT_REQUEST = 1;
    static final int POST_COLLEGE_REQUEST = 2;


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

        mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

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

        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void postInSection1(View view) {
        Intent intent = new Intent(this, PostInSection1.class);
        startActivity(intent);

    }

    public void postInSection2(View view) {
        Intent intent = new Intent(this, PostInSection2.class);
        startActivity(intent);
    }


    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {

            return PlaceholderFragment.newInstance(position + 1);
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {

                case 0:
                    return getString(R.string.title_section1).toUpperCase(l);
                case 1:
                    return getString(R.string.title_section2).toUpperCase(l);
                case 2:
                    return getString(R.string.title_section3).toUpperCase(l);
            }
            return null;
        }
    }

}

您的 Viewpager 看起来不错。在每个 onResumeonPause 处放置 otto registrater/unregister,而不是 onCreateView

@Override
public void onResume() {
    super.onResume();
    BusProvider.getInstance().register(this);
}

@Override
public void onPause() {
    super.onPause();
    BusProvider.getInstance().unregister(this);
}

ViewPager实现如下。

public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
    private SparseArrayCompat<SectionFragmentInterface> fragmentSparseArrayCompat;

    public SectionsPagerAdapter (FragmentManager fm) {
        super(fm);
        fragmentSparseArrayCompat = new SparseArrayCompat<>();
    }

    @Override
    public Fragment getItem(int position) {
        SectionFragmentInterface fragment = fragmentSparseArrayCompat.get(position);

        switch (position) {
            case 0: {
                if (fragment == null) {
                    fragment = SectionOneListFragment.newInstance(position);
                }
            }
            break;
            case 1: {
                if (fragment == null) {
                    fragment = SectionTwoListFragment.newInstance(position);
                }
            }
            break;
        }

        fragmentSparseArrayCompat.put(position, fragment);

        return fragment;
    }

    @Override
    public int getCount() {
        return 2;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "";
    }

}

解决了!

我一直在为所有三个片段传递相同 class 的实例,并在每个片段的 onCreate 方法中注册到总线,因此尝试一次又一次地注册相同的 class。

我现在创建了一个基础 class 并为片段创建了三个不同的子 classes,因此我可以在各自的 classes 注册和注销而无需多次注册.

这是我在 FragmentPagerAdapter class 的 getItem 方法中根据问题中给出的代码段更改的代码。

 @Override
    public Fragment getItem(int position) {

        switch (position){
            case 0:
                return new SectionOneFragment();
            case 1:
                return new SectionTwoFragment();
            case 2:
                return new SectionThreeFragment();
        }

        //return PlaceholderFragment.newInstance(position + 1);
        return null;
    }

现在我在这些新的 class 的 onCreate 方法中调用 bus.register(),订阅的方法也在相应的 classes 中实现。