2

У меня есть 4 фрагмента в ViewPager, который интегрирован с TabLayout. Каждый из этих фрагментов содержит RecyclerView, потому что я показываю неизвестное количество элементов списка. Элементы загружаются по дате, поэтому у меня есть две кнопки, которые позволяют вам менять дни, а затем соответствующие данные в элементах списка загружаются на основании установленной даты. Кнопки являются частью внешнего действия.Фрагмент в ViewPager ничего не отображает в своем RecyclerView при повороте

Все до сих пор отлично работает, НО когда я поворачиваю устройство, фрагменты ничего не нагружают. Во Фрагментах ничего не отображается. Тем не менее, представления во внешнем действии отображаются точными. Странно то, что если я коснусь одной из кнопок, которая меняет дату, то Фрагменты будут загружены и данные будут отображаться правильно. Но мне нужно, чтобы все отображалось сразу после вращения не только при нажатии одной из этих кнопок. Вот мой код:

public class MainActivity extends AppCompatActivity implements DatePickerFragment.DateDialogInterface 
{ 
    private final static String COLOR_CONTROL_CHOSEN = "color_control_chosen"; 
    private static final String DIALOG_DATE = "dialog_date"; 
    private static final String TAG = "MainActivity"; 
    private static final String SET_LOCATION = "set_location"; 
    public static final String LEAGUE_POSITION = "league_position"; 
    private Toolbar mToolbar; 
    private ViewPager mViewPager; 
    private TabLayout mTabLayout; 
    private ImageButton mPrevDateButton, mNextDateButton; 
    private TextView mDateTextView, mLeagueTextView; 
    private String mTodaysDate; 
    private Date mLastSelectedDate, mTodaysDateObj; 
    private ProgressBar mProgressBar; 
    private FragmentPagerAdapter mAdapterViewPager; 

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

     mToolbar = (Toolbar) findViewById(R.id.outnix_toolbar); 
     mViewPager = (ViewPager) findViewById(R.id.main_activity_view_pager); 
     mTabLayout = (TabLayout) findViewById(R.id.main_activity_tab_layout); 
     mDateTextView = (TextView) findViewById(R.id.display_date_text_view); 
     mLeagueTextView = (TextView) findViewById(R.id.league_title_header); 
     mPrevDateButton = (ImageButton) findViewById(R.id.previous_date_button); 
     mNextDateButton = (ImageButton) findViewById(R.id.next_date_button); 
     mProgressBar = (ProgressBar) findViewById(R.id.loading_circle); 
     mProgressBar.setVisibility(View.GONE); 
     setTodaysDate(); 
     mDateTextView.setText("Today"); 

     setSupportActionBar(mToolbar); 
     assert getSupportActionBar() != null; 
     getSupportActionBar().setDisplayShowTitleEnabled(false); 

     NavDrawerFragment navDrawerFrag = (NavDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_nav_drawer); 
     navDrawerFrag.setUp((DrawerLayout) findViewById(R.id.nav_drawer), mToolbar); 

     setUpViewPagerAdapterOnCreate(); 
     mTabLayout.setupWithViewPager(mViewPager); 

     mDateTextView.setOnClickListener(new View.OnClickListener() 
     { 
      @Override 
      public void onClick(View v) 
      { 
       FragmentManager fm = getSupportFragmentManager(); 
       DatePickerFragment dialog = new DatePickerFragment(); 
       Bundle args = new Bundle(); 
       args.putSerializable("ARG_DATE", mLastSelectedDate); 
       dialog.setArguments(args); 
       dialog.show(fm, DIALOG_DATE); 
      } 
     }); 

    THESE TWO LISTENERS ARE WHAT DISPLAY THE DATA AFTER A ROTATION CHANGE 
    ////////////////////////////////////////////////////////////////// 
     mPrevDateButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) 
      { 
       mProgressBar.setVisibility(View.VISIBLE); 
       updateDate(-1); 
       setupViewPagerAdapter(getViewPagerPos()); 
      } 
     }); 

     mNextDateButton.setOnClickListener(new View.OnClickListener() 
     { 
      @Override 
      public void onClick(View v) 
      { 
       mProgressBar.setVisibility(View.VISIBLE); 
       updateDate(1); 
       setupViewPagerAdapter(getViewPagerPos()); 
      } 
     }); 
    } 
    //////////////////////////////////////////////////////////////////// 
/* @Override 
    protected void onResume() 
    { 
     super.onResume(); 
     setupViewPagerAdapter(getViewPagerPos()); 
    }*/ 

    private void setUpViewPagerAdapterOnCreate() //only called when opened from LauncherActivity 
    { 
     setupViewPagerAdapter(0); 

     int touchColorPixel = getIntent().getIntExtra(COLOR_CONTROL_CHOSEN, ContextCompat.getColor(this, R.color.blue)); 

     if(touchColorPixel == ContextCompat.getColor(this, R.color.orange)) 
      mViewPager.setCurrentItem(0); 
     else if(touchColorPixel == ContextCompat.getColor(this, R.color.blue)) 
      mViewPager.setCurrentItem(1); 
     else 
      mViewPager.setCurrentItem(3); 
    } 

    private void setupViewPagerAdapter(int currentPos) 
    { 
     mAdapterViewPager = new MainPagerAdapter(getSupportFragmentManager()); 

     mViewPager.setAdapter(mAdapterViewPager); 
     mViewPager.setOffscreenPageLimit(4); 
     mViewPager.setCurrentItem(currentPos); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) 
    { 
     super.onSaveInstanceState(outState); 
     outState.putSerializable(DIALOG_DATE, mLastSelectedDate);   //save the last date selected (or last date displayed) on rotation change. 
    } 

    @Override 
    protected void onRestoreInstanceState(Bundle savedInstanceState) 
    { 
     super.onRestoreInstanceState(savedInstanceState); 
     setDateFromDialog((Date) savedInstanceState.getSerializable(DIALOG_DATE)); //restore the last date selected to the new rotation change 
    } 

    public ProgressBar getProgressBar() 
    { 
     return mProgressBar; 
    } 

    @Override 
    public void setDateFromDialog(Date date) 
    { 
     String newDate = getFormattedDate(date); 
     updateTodaysDate();  
     mLastSelectedDate = date; 

     setupViewPagerAdapter(getViewPagerPos()); 

     if(newDate.equals(mTodaysDate)) 
      mDateTextView.setText("Today"); 
     else 
      mDateTextView.setText(newDate); 
    } 

    private int getViewPagerPos() 
    { 
     return mViewPager.getCurrentItem(); 
    } 
} 

В 2 кнопки mPrevDateButton и mNextDateButton являются кнопки, которые при нажатии на «исправить» эту проблему. Внутри своих кликов-прослушивателей метод updateDate() только делает материал, связанный с объектом TextView, и поэтому я не включал определения (я стараюсь, чтобы сообщение было как можно короче). Поэтому я точно знаю, что это имеет какое-то отношение к моему методу setupViewPagerAdapter(). Я попытался добавить этот метод в onCreate() и onResume(), но фрагменты по-прежнему остаются пустыми.

Вот мой ViewPager код адаптера:

public class MainPagerAdapter extends FragmentPagerAdapter 
{ 
    private final String[] mFragmentTitleList = {"My Games", "All Games", "All Places", "My Places"}; //tab title names 
    private final static int NUM_FRAGMENTS = 4; 

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

    @Override 
    public Fragment getItem(int position) 
    { 
     switch(position) 
     { 
      case 0: 
       return MyGamesFragment.newInstance(); 
      case 1: 
       return AllGamesFragment.newInstance(); 
      case 2: 
       return AllPlacesFragment.newInstance(); 
      case 3: 
       return MyPlacesFragment.newInstance(); 
      default: 
       return null; 
     } 
    } 

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

    @Override 
    public CharSequence getPageTitle(int position) 
    { 
     return mFragmentTitleList[position]; 
    } 
} 

Вот один из 4-х фрагментов. Они почти все имеют схожий дизайн.

public class AllGamesFragment extends Fragment 
{ 
    private SwipeRefreshLayout mSwipeRefreshLayout; 
    private RecyclerView mAllGamesRecyclerView; 
    private GameAdapter mGameAdapter; 
    private List<Game> mGameList = new ArrayList<>(); 
    private MainActivity mMainActivity;  //keeps a reference to MainActivity to access public methods 

    public static AllGamesFragment newInstance() 
    { 
     return new AllGamesFragment(); 
    } 

    @Override 
    public void onAttach(Context context) 
    { 
     super.onAttach(context); 
     mMainActivity = (MainActivity) context; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setRetainInstance(true); 
     mMainActivity.getProgressBar().setVisibility(View.VISIBLE); 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    { 
     View view = inflater.inflate(R.layout.recycler_view_all_games, container, false); 
     mAllGamesRecyclerView = (RecyclerView) view.findViewById(R.id.all_games_recycler_view); 
     mAllGamesRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 
     mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh); 
     mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() 
     { 
      @Override 
      public void onRefresh() 
      { 
       getGamesData(); 
       mSwipeRefreshLayout.setRefreshing(false); 
      } 
     }); 

     return view; 
    } 

    @Override 
    public void onResume() 
    { 
     super.onResume(); 
     getGamesData(); 
    } 

    private void setupAdapter() 
    { 
     if(isAdded()) 
     { 
      mGameAdapter = new GameAdapter(mGameList); 
      mAllGamesRecyclerView.setAdapter(mGameAdapter); 
     } 
    } 

    private void getGamesData() 
    { 
     new GetDataTask(mMainActivity.getLastSelectedDate()).execute(); 
    } 

    private class GetDataTask extends Scraper.GameDataTask 
    { 
     GetDataTask(Date date) 
     { 
      super(date, getActivity()); 
     } 

     @Override 
     protected void onPostExecute(List<Game> games) 
     { 
      mGameList = games; 
      setupAdapter(); 
      mMainActivity.getProgressBar().setVisibility(View.GONE); 
     } 
    } 

    private class GameAdapter extends RecyclerView.Adapter<GameHolder> 
    { 
     private List<Game> mGames; 

     public GameAdapter(List<Game> games) 
     { 
      mGames = games; 
     } 

     @Override 
     public GameHolder onCreateViewHolder(ViewGroup parent, int viewType) 
     { 
      LayoutInflater inflater = LayoutInflater.from(getActivity()); 
      View view = inflater.inflate(R.layout.list_game_item, parent, false); 
      return new GameHolder(view, getActivity()); 
     } 

     @Override 
     public void onBindViewHolder(GameHolder holder, int position) 
     { 
      holder.bindGameData(mGames.get(position)); 
     } 

     @Override 
     public int getItemCount() 
     { 
      return mGames.size(); 
     } 
    } 

Я смотрел так много сообщений здесь, много раз менял свой код, и я все еще не могу заставить его работать. Я просто озадачен тем, что он «исправляет», когда я нажимаю одну из кнопок даты. Если вы хотите, чтобы я опубликовал больше кода, дайте мне знать. Извините за длинный пост, но я чувствую, что контекст необходим. Я очень ценю любую помощь!

+0

, где вы объявили и инициализировали isAdded() –

+0

@HRaval, который является встроенной функцией фрагмента, который проверяет, привязан ли он к действию. –

+0

попробуйте [this] (http://stackoverflow.com/a/17629575/3117966), надеюсь, что это поможет – Nisarg

ответ

3

Я понял! Мне пришлось переключиться на FragmentStatePagerAdapter, а не на FragmentPagerAdapter. Я считаю, что это имеет какое-то отношение к тому, что Фрагменты уничтожаются и снова воссоздаются.

Я также читал, что другой способ будет обернуть ViewPager в фрагменте и при создании его адаптера вы используете getChildFragmentManager(), а не getSupportFragmentManager() так:

mAdapterViewPager = new MyPagerAdapter(getChildFragmentManager()); 

Я не хочу, чтобы добавить весь фрагмент вокруг моего ViewPager, чтобы исправить эту проблему, поэтому я переключился на использование FragmentStatePagerAdapter, и это сработало! Надеюсь, это поможет кому-то еще.

0

Адаптер viewPager расширяет FragmentStatePagerAdapter, а не FragmentPagerAdapter, должен решить проблему.

+0

Добро пожаловать в SO. Это должен быть комментарий, а не ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^