我正在开发一个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();
}
感谢您的帮助!!