我有一個MainActivity它首先打電話給我的服務器並獲得響應。然後,在第一個響應的成功,我開始viewPager。ViewPager片段不同步更新?
下面調用代碼來啓動viewPager及其適配器,它只在第一個響應成功後才被調用。
mShowTimeViewPageAdapter = new ShowTimeViewPageAdapter(getSupportFragmentManager(), getApplicationContext(), this, mDateStringList, showDateCodesList, venueHashMap);
mVenueHashMap = venueHashMap;
mRequestedDateCodes = requestedDateCodes;
mViewPager.setAdapter(mShowTimeViewPageAdapter);
mShowTimeTabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < range; i++) {
TabLayout.Tab tab = mShowTimeTabLayout.getTabAt(i);
tab.setCustomView(mShowTimeViewPageAdapter.getTabView(i));
}
這是我的viewPagerAdapter。
public class ShowTimeViewPageAdapter extends FragmentStatePagerAdapter {
private static final String TAG = ShowTimeViewPageAdapter.class.getSimpleName();
private Map<Integer, String> mFragmentTags;
private Context mContext;
private List<String> mDateStringList;
private FragmentManager fragmentManager;
private IShowTimeActivity mIShowTimeActivity;
private List<String> mDateCodes;
private LinkedHashMap<String, List<Venue>> mVenueHashMap;
public ShowTimeViewPageAdapter(FragmentManager fm, Context context, IShowTimeActivity showTimeActivity, List<String> createdDates, List<String> dateCodes, LinkedHashMap<String, List<Venue>> venueHashMap) {
super(fm);
this.mContext = context;
this.mIShowTimeActivity = showTimeActivity;
this.fragmentManager = fm;
this.mDateCodes = dateCodes;
this.mVenueHashMap = venueHashMap;
this.mDateStringList = createdDates;
mFragmentTags = new HashMap<Integer, String>();
}
private List<Venue> getVenuesList(String dateCode) {
return mVenueHashMap.get(dateCode);
}
@Override
public Fragment getItem(int position) {
String stringDate = mDateStringList.get(position).split(";")[2];
if (mDateCodes.contains(stringDate)) {
if (getVenuesList(stringDate) == null) {
mIShowTimeActivity.requestForTheVenueListByDateCode(stringDate, position);
}
}
ShowTimeFragment showTimeFragment = ShowTimeFragment.newInstance(stringDate);
showTimeFragment.setVenueList(mVenueHashMap.get(stringDate));
// fragmentManager.beginTransaction().add(showTimeFragment, ""+position);
return showTimeFragment;
}
@Override
public int getCount() {
return mDateStringList.size();
}
public View getTabView(int position) {
String[] dateStr = mDateStringList.get(position).split(";");
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View tabView = layoutInflater.inflate(R.layout.show_time_tab_layout, null, false);
TextViewRoboto day = (TextViewRoboto) tabView.findViewById(R.id.show_time_tab_day);
TextViewRoboto date = (TextViewRoboto) tabView.findViewById(R.id.show_time_tab_date);
day.setText(dateStr[0]);
date.setText(dateStr[1]);
return tabView;
}
}
在這裏,上getItem()時viewPager的方法回調,它會爲每個位置,並檢查新的片段如果所選位置處的數據是可用的或沒有。如果是的話,這顯然會出現在第一個位置,因爲它是在第一個響應成功之後調用的,它會將數據傳遞給片段。
如果不是,它會向服務器發出一個新的api請求來獲取數據。 由於viewPager緩存2頁,提前,它會發出2個請求並緩存數據。
在每個請求中,我正在用數據更新hashMap。
這是我的片段,始終爲每個位置啓動。
public class ShowTimeFragment extends Fragment {
private static final String KEY_CODE = "date_key";
public ShowTimeRecyclerViewAdapter mShowTimeRecyclerViewAdapter;
@Bind(R.id.show_time_fragment_recycler_view) RecyclerView mShowTimeRecyclerView;
@Bind(R.id.show_time_fragment_no_data_text_view) TextViewRoboto mShowTimeNoDataTextView;
List<Venue> venueList = new ArrayList<Venue>();
public List<Venue> getVenueList() {
return venueList;
}
public void setVenueList(List<Venue> venueList) {
this.venueList = venueList;
}
private View view;
public ShowTimeFragment() {
}
public static ShowTimeFragment newInstance(String dateCode) {
Bundle bundle = new Bundle();
bundle.putString(KEY_CODE, dateCode);
ShowTimeFragment showTimeFragment = new ShowTimeFragment();
showTimeFragment.setArguments(bundle);
return showTimeFragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.show_time_fragment, container, false);
ButterKnife.bind(this, view);
mShowTimeRecyclerViewAdapter = new ShowTimeRecyclerViewAdapter(venueList, getContext());
mShowTimeRecyclerView.setAdapter(mShowTimeRecyclerViewAdapter);
if (venueList != null && venueList.size() > 0) {
mShowTimeRecyclerView.setVisibility(View.VISIBLE);
mShowTimeNoDataTextView.setVisibility(View.GONE);
CustomLinearLayoutManager cl = new CustomLinearLayoutManager(getActivity(), 1, false);
mShowTimeRecyclerView.setLayoutManager(cl);
}
else{
mShowTimeNoDataTextView.setVisibility(View.VISIBLE);
mShowTimeRecyclerView.setVisibility(View.GONE);
mShowTimeNoDataTextView.setText("NO Data Available");
}
return view;
}
}
而下面是我的recyclerViewAdapter,它從片段中調用。
public class ShowTimeRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_RECOMMENDED = 0;
private static final int TYPE_GENERIC = 1;
public List<Venue> mVenueList;
private Context mContext;
public ShowTimeRecyclerViewAdapter(List<Venue> venueList, Context context) {
this.mVenueList = venueList;
this.mContext = context;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_RECOMMENDED) {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View view = layoutInflater.inflate(R.layout.show_time_recycler_view_header_item_view, parent, false);
final RecommendedViewHolder recyclerViewHolder = new RecommendedViewHolder(view);
return recyclerViewHolder;
}
else if (viewType == TYPE_GENERIC) {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View view = layoutInflater.inflate(R.layout.show_time_recycler_view_item, parent, false);
final ChildViewHolder viewHolder = new ChildViewHolder(view);
return viewHolder;
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Venue venue = mVenueList.get(position);
if (holder instanceof RecommendedViewHolder) {
TextViewRoboto cinemaHallName = ((RecommendedViewHolder) holder).mRecommendedShowTimeCinemaHallName;
cinemaHallName.setText(venue.getVenueName());
CustomGridView movieTimingGridView = ((RecommendedViewHolder) holder).mRecommendedMovieTimingGridView;
ImageView reserveIcon = ((RecommendedViewHolder) holder).mRecommendedMovieReserveImage;
if (venue.getCinemaUnpaidFlag().equals("Y")) {
reserveIcon.setVisibility(View.VISIBLE);
}
else {
reserveIcon.setVisibility(View.GONE);
}
ImageView mTicketIcon = ((RecommendedViewHolder) holder).mRecommendedMovieMTicketImage;
if (venue.getMTicket().equals("Y")) {
mTicketIcon.setVisibility(View.VISIBLE);
}
else {
mTicketIcon.setVisibility(View.GONE);
}
List<ShowTime> currShowTimesList = new ArrayList<ShowTime>(venue.getShowTimes());
movieTimingGridView.setAdapter(new ShowMovieTimeAdapter(mContext, currShowTimesList, true));
movieTimingGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}
else if (holder instanceof ChildViewHolder) {
((ChildViewHolder) holder).mShowTimeCinemaHallName.setText(venue.getVenueName());
if (venue.getMTicket().toUpperCase().equals("Y") || venue.getCinemaUnpaidFlag().toUpperCase().equals("Y")) {
if (venue.getCinemaUnpaidFlag().toUpperCase().equals("N")) {
((ChildViewHolder) holder).mMovieReserveImage.setVisibility(View.GONE);
}
else if (venue.getCinemaUnpaidFlag().toUpperCase().equals("Y")) {
((ChildViewHolder) holder).mMovieReserveImage.setVisibility(View.VISIBLE);
((ChildViewHolder) holder).mMovieReserveImage.setImageResource(R.drawable.show_time_reserve_seat_icon);
}
if (venue.getMTicket().toUpperCase().equals("N")) {
((ChildViewHolder) holder).mMovieMTicketImage.setVisibility(View.GONE);
}
else if (venue.getMTicket().toUpperCase().equals("Y")) {
((ChildViewHolder) holder).mMovieMTicketImage.setVisibility(View.VISIBLE);
((ChildViewHolder) holder).mMovieMTicketImage.setImageResource(R.drawable.show_time_m_ticket_icon);
}
}
else {
((ChildViewHolder) holder).mShowTimeFragImagesLinearLayout.setVisibility(View.GONE);
}
CustomGridView movieTimingGridView = ((ChildViewHolder) holder).mMovieTimingGridView;
List<ShowTime> currShowTimesList = new ArrayList<ShowTime>(venue.getShowTimes());
movieTimingGridView.setAdapter(new ShowMovieTimeAdapter(mContext, currShowTimesList, false));
movieTimingGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
}
}
public static class ChildViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.show_time_fragment_cinema_hall_name)
TextViewRoboto mShowTimeCinemaHallName;
@Bind(R.id.show_movie_timings_grid_view)
CustomGridView mMovieTimingGridView;
@Bind(R.id.show_time_fragment_reserve_image)
ImageView mMovieReserveImage;
@Bind(R.id.show_time_fragment_m_ticket_image)
ImageView mMovieMTicketImage;
@Bind(R.id.show_time_fragment_images_lin_layout)
LinearLayout mShowTimeFragImagesLinearLayout;
public ChildViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
public void swap(List<Venue> venueList){
if(mVenueList!=null){
mVenueList.clear();
mVenueList.addAll(venueList);
} else {
mVenueList = venueList;
}
}
class RecommendedViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.show_time_recommendation_fragment_cinema_hall_name)
TextViewRoboto mRecommendedShowTimeCinemaHallName;
@Bind(R.id.show_movie_recommendation_timings_grid_view)
CustomGridView mRecommendedMovieTimingGridView;
@Bind(R.id.show_time_recommendation_fragment_reserve_image)
ImageView mRecommendedMovieReserveImage;
@Bind(R.id.show_time_recommendation_fragment_m_ticket_image)
ImageView mRecommendedMovieMTicketImage;
@Bind(R.id.show_time_recommendation_for_badge)
ImageView mShowTimeRecommendationBadge;
public RecommendedViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
@Override
public int getItemCount() {
return mVenueList.size();
}
@Override
public int getItemViewType(int position) {
if (isPositionRecommended(position))
return TYPE_RECOMMENDED;
return TYPE_GENERIC;
}
private boolean isPositionRecommended(int position) {
Venue venue = mVenueList.get(position);
return venue.isRecommended();
}
}
我的問題就出在這裏,即使該請求是異步的,我想表明裝載機,如果數據還沒來的及更新上的數據viewPager片段都來自服務器和hideLoading。
它的正常工作,當我重寫getItemPosition()viewPager的,並從那裏返回POSITION_NONE,但我不希望這樣做,因爲它重新創建片段,並讓我的應用程序緩慢。
我試着設置每個片段的標籤和onPositionSelected()回調的viewPager監聽器,我試着交換每個片段的recyclerView內容,但它沒有工作。
令人驚訝的是,它加載所有的數據,如果保持滑動到其他頁面並返回到第1頁或第2頁。
我嘗試了所有可能的解決方案。
任何形式的建議,將不勝感激。
你確定這是你的RecyclerView適配器? –
@MuchOverflow謝謝你的注意,我已經更新了我的問題。請看一看。 – Ritesh
我會通過使用EventBus(例如Square的Otto)來緩解這個問題。最初我會用ProgressBar打開片段。然後我會檢查數據是否加載了特定的片段。如果是這樣,我會隱藏加載器並顯示數據。如果沒有,我將用EventBus註冊片段,並等待它加載數據後作出響應。 –