ViewPager / RecyclerView初始化最佳实践

时间:2017-09-19 14:00:09

标签: android android-fragments android-recyclerview android-viewpager fragmentstatepageradapter

我正在开发一个Android天气应用程序,其中包含一个包含3页的Tablelayout。适配器是FragmentStatePagerAdaptater,它们中的每一个都是包含RecyclerView的Fragment。 应用程序在asynctask中接收并处理天气数据,然后使用接收的数据更新ViewPager。

我的问题是要知道这是初始化ViewPager时的最佳做法,即我在Fragment中使用空数据初始化MainActivity OnCreate()中的ViewPager,因为此时我还没有天气数据。 收到数据后,我通知ViewPager数据已更改,然后在getItemPosition()方法的FragmentStatePagerAdapter中,我执行片段的RecyclerView更新。 RecyclerView使用等效的方法进行更新,该方法在RecyclerViewAdaptater中传递新数据,并通知notifyDataSetChanged()以通知数据已更改。

但也许最好的做法是等待接收天气数据然后用数据初始化Viewpager适配器。 如果用户请求数据更新,则仅通知ViewPager数据已更改,就像我的应用程序中的情况一样。

这是我的方法的代码:

MainActivity OnCreate():

    viewPager = (ViewPager)findViewById(R.id.viewpager);
    viewPager.setOffscreenPageLimit(2);
    SampleFragmentPagerAdapter adapter = new SampleFragmentPagerAdapter(getSupportFragmentManager());
    adapter.addFrag(PageFragment.newInstance(0), "today");
    adapter.addFrag(PageFragment.newInstance(1), "tomorrow");
    adapter.addFrag(PageFragment.newInstance(2), "7 days");
    viewPager.setAdapter(adapter);

Asynctask onPostExecute(Climat climat)

    mSwipeRefreshLayout.setRefreshing(false);

    if (climat != null) {

        MainActivity.climat = climat;
        viewPager.getAdapter().notifyDataSetChanged();

        // Set page 1
        viewPager.setCurrentItem(0);
  }

FragmentStatePagerAdaptater:

class SampleFragmentPagerAdapter extends FragmentStatePagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>(3);
    private final List<String> mFragmentTitleList = new ArrayList<>(3);

    SampleFragmentPagerAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    // Returns total number of pages
    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    // Returns the fragment to display for that page
    @Override
    public Fragment getItem(int position) {
        Log.i(TAG, "Fragment getItem position " + position);
        return mFragmentList.get(position);
    }

    void addFrag(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    // Refresh fragment
    @Override
    public int getItemPosition(Object object) {
        PageFragment f = (PageFragment ) object;
        if (f != null) {
            f.update();
        }
        return super.getItemPosition(object);
    }

    // Returns the page title for the top indicator
    @Override
    public CharSequence getPageTitle(int position) {
        // Generate title based on item position
        return mFragmentTitleList.get(position);
    }
}

PageFragment:

public class PageFragment extends Fragment implements Updateable {
    private static final String ARG_PAGE = "ARG_PAGE";
    private int mPage;
    private Climat climat = null;
    private RecyclerView rv1;
    private RecyclerView rv2;
    private RecyclerView rv3;
    private ClimatAdaptateurToday climatAdaptateurTodayRv1;
    private ClimatAdaptateurToday climatAdaptateurTodayRv2;
    private ClimatAdaptateur climatAdaptateur;

    // newInstance constructor for creating fragment with arguments
    public static PageFragment newInstance(int page) {
        PageFragment fragment = new PageFragment();
        // Supply num input as an argument.
        Bundle args = new Bundle();
        args.putInt(ARG_PAGE, page);
        fragment.setArguments(args);
        return fragment;
    }

    /**
     * When creating, retrieve this instance's number from its arguments.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPage = getArguments() != null ? getArguments().getInt(ARG_PAGE) : 0;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        switch (mPage) {
            case 0: 
                rv1 = (RecyclerView) view.findViewById(R.id.recyclerView);
                // use this setting to improve performance if you know that changes
                // in content do not change the layout size of the RecyclerView
                rv1.setHasFixedSize(true);
                // use a linear layout manager
                RecyclerView.LayoutManager layoutRv1 = new LinearLayoutManager(getActivity());
                rv1.setLayoutManager(layoutRv1);
                rv1.setItemAnimator(new DefaultItemAnimator());
                climatAdaptateurTodayRv1 = new ClimatAdaptateurToday(climat, mPage);
                climatAdaptateurTodayRv1.setHasStableIds(true);
                rv1.setAdapter(climatAdaptateurTodayRv1);
                break;
            case 1:
                rv2 = (RecyclerView) view.findViewById(R.id.recyclerView);
                // use this setting to improve performance if you know that changes
                // in content do not change the layout size of the RecyclerView
                rv2.setHasFixedSize(true);
                // use a linear layout manager
                RecyclerView.LayoutManager layoutRv2 = new LinearLayoutManager(getActivity());
                rv2.setLayoutManager(layoutRv2);
                rv2.setItemAnimator(new DefaultItemAnimator());
                climatAdaptateurTodayRv2 = new ClimatAdaptateurToday(climat, mPage);
                climatAdaptateurTodayRv2.setHasStableIds(true);
                rv2.setAdapter(climatAdaptateurTodayRv2);
                break;
            case 2:
                rv3 = (RecyclerView) view.findViewById(R.id.recyclerView);
                // use this setting to improve performance if you know that changes
                // in content do not change the layout size of the RecyclerView
                rv3.setHasFixedSize(true);
                // use a linear layout manager
                RecyclerView.LayoutManager layoutRv3 = new LinearLayoutManager(getActivity());
                rv3.setLayoutManager(layoutRv3);
                rv3.setItemAnimator(new DefaultItemAnimator());
                climatAdaptateur = new ClimatAdaptateur(null,
                        null, null);
                climatAdaptateur.setHasStableIds(true);
                rv3.setAdapter(climatAdaptateur);
                break;
        }
    }

    // Inflate the view for the fragment based on layout XML
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
        return inflater.inflate(R.layout.content_main, container, false);
    }

    // To update fragment in ViewPager, we should implement a public method for the fragment,
    // and do updating stuff in this method.
    @Override
    public void update() {
        this.climat = MainActivity.climat;
        if (climat != null) {
            switch (mPage) {
                case 0:
                    climatAdaptateurTodayRv1.updateData(climat, mPage);
                    climatAdaptateurTodayRv1.notifyDataSetChanged();
                    rv1.smoothScrollToPosition(0);
                    break;
                case 1:
                    climatAdaptateurTodayRv2.updateData(climat, mPage);
                    climatAdaptateurTodayRv2.notifyDataSetChanged();
                    rv2.smoothScrollToPosition(0);
                    break;
                case 2:
               climatAdaptateur.updateData(climat.getClimatInfoDailyArray(),
                climat.getTempsArray(), climat.getLieux());
                    climatAdaptateur.notifyDataSetChanged();
                    rv3.smoothScrollToPosition(0);
                break;
            }
        }
    }
}

interface Updateable {
    void update();
}

感谢您的帮助!!

0 个答案:

没有答案