1

Когда я перехожу от DetailsActivity в MainActivity, RecyclerView сбрасывается, и список всегда отображается в верхнем положении.Невозможно восстановить положение/состояние RecyclerView

Полный исходный код можно увидеть here. Код по-прежнему в значительной степени находится в процессе разработки.

MainActivityFragment is as follows. 

public class MainActivityFragment extends Fragment { 

    private ArrayList<Movie> mMovieArrayList = new ArrayList<Movie>(); 
    private static final String PAGE = "1"; 
    private RecyclerView mRecyclerView; 

    private SharedPreferences mSettings; 
    private SharedPreferences.Editor mEditor; 

    private static final String LOG = MainActivityFragment.class.getSimpleName(); 

    public MainActivityFragment() { 
    } 

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

     View rootView = inflater.inflate(R.layout.fragment_movie_list, container, false); 

     // Set column size to 2 for default and portrait 
     // and 3 for landscape orientations 
     int column = Integer.parseInt(getString(R.string.grid_portrait)); 
     if (getResources().getConfiguration().orientation == 1) { 
      column = Integer.parseInt(getString(R.string.grid_portrait)); 
     } else if (getResources().getConfiguration().orientation == 2) { 
      column = Integer.parseInt(getString(R.string.grid_landscape)); 
     } 

     if (getActivity().findViewById(R.id.movie_detail_container) != null) { 
      column = Integer.parseInt("2"); 
     } 

     mSettings = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
     mEditor = mSettings.edit(); 
     mEditor.apply(); 

     mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview); 
     mRecyclerView.setHasFixedSize(true); 
     mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), column)); 

     mRecyclerView.setAdapter(new MovieAdapter(getActivity(), mMovieArrayList)); 
     return rootView; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setHasOptionsMenu(true); 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     updateMovieList(); 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     inflater.inflate(R.menu.menu_main_fragment, menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.popularity: 
       mEditor.putString(getResources().getString(R.string.perf_sort), 
         getResources().getString(R.string.url_popularity)); 
       mEditor.apply(); 
       updateMovieList(); 
       item.setChecked(true); 
       Log.d(LOG, "onOptionsItemSelected: popularity"); 
       return true; 
      case R.id.rating: 
       mEditor.putString(getResources().getString(R.string.perf_sort), 
         getResources().getString(R.string.url_top_rated)); 
       mEditor.apply(); 
       updateMovieList(); 
       item.setChecked(true); 
       Log.d(LOG, "onOptionsItemSelected: rating"); 
       return true; 
      case R.id.favorite: 
       mEditor.putString(getResources().getString(R.string.perf_sort), 
         getResources().getString(R.string.url_favorite)); 
       mEditor.apply(); 
       updateMovieList(); 
       item.setChecked(true); 
       Log.d(LOG, "onOptionsItemSelected: favorite"); 
       return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onPrepareOptionsMenu(Menu menu) { 
     super.onPrepareOptionsMenu(menu); 

     String sortBy = mSettings.getString(getResources().getString(R.string.perf_sort), 
       getResources().getString(R.string.url_popularity)); 

     if (sortBy.equals(getResources().getString(R.string.url_popularity))) { 
      menu.findItem(R.id.popularity).setChecked(true); 
     } else if (sortBy.equals(getResources().getString(R.string.url_top_rated))) { 
      menu.findItem(R.id.rating).setChecked(true); 
     } else if (sortBy.equals(getResources().getString(R.string.url_favorite))) { 
      menu.findItem(R.id.favorite).setChecked(true); 
     } 
    } 

    private void updateMovieList() { 
     mMovieArrayList = new ArrayList<>(); 
     String sortBy = mSettings.getString(getResources().getString(R.string.perf_sort), 
       getResources().getString(R.string.url_popularity)); 

     if (sortBy.equals(getResources().getString(R.string.url_popularity)) || 
       sortBy.equals(getResources().getString(R.string.url_top_rated))) { 

      try { 
       mMovieArrayList = 
         new FetchMoviesTask().execute(sortBy, PAGE).get(); 
      } catch (ExecutionException | InterruptedException ei) { 
       ei.printStackTrace(); 
      } 
     } else if (sortBy.equals(getResources().getString(R.string.url_favorite))) { 
      ContentResolver resolver = getActivity().getContentResolver(); 
      Cursor cursor = 
        resolver.query(MovieContract.MovieEntry.CONTENT_URI, 
          null, 
          null, 
          null, 
          null); 

      if (cursor != null) { 
       if (cursor.moveToFirst()) { 
        do { 
         String title = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.TITLE)); 
         String movie_id = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.MOVIE_ID)); 
         String poster = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.POSTER)); 
         String backdrop = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.BACKDROP)); 
         String overview = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.OVERVIEW)); 
         String vote_average = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.VOTE_AVERAGE)); 
         String release_date = cursor.getString(cursor.getColumnIndex(MovieContract.MovieEntry.DATE)); 

         Movie movie = new Movie(title, release_date, poster, 
           vote_average, overview, backdrop, movie_id); 
         mMovieArrayList.add(movie); 
        } while (cursor.moveToNext()); 
       } 
      } 

      if (cursor != null) 
       cursor.close(); 
     } 

     mRecyclerView.setAdapter(new MovieAdapter(getActivity(), mMovieArrayList)); 
     mRecyclerView.getAdapter().notifyDataSetChanged(); 
    } 
} 

Основная деятельность заключается в следующем.

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.activity_main); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
    } 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

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

//  if (id == android.R.id.home) { 
//   onBackPressed(); 
//   return true; 
//  } 

     return super.onOptionsItemSelected(item); 
    } 
} 

Я попытался установить копит состояние RecyclerView как показано в этом post.

Я также попытался спасения mArrayList в onSaveInstanceState и восстановлении его в onActivityCreated или onViewCreated как в этом post.

Оба эти не работали для меня. Как только я вернусь с DetailsActivity на MainActivity, позиция исчезла.

Спасибо.

ответ

1
  1. Вы вызываете метод обновления списка фильмов в onStart обратном вызове жизненного цикла фрагмента. Это означает, что, когда ваше основное действие отображается назад, вы переустанавливаете свой список. Вы не должны.
  2. В конце списка обновлений вы устанавливаете новый экземпляр адаптера. Это перерисовывает весь список. Вы должны пересмотреть свои жизненные циклы. Вызовите обновление списка фильмов только в onCreate или onCreateView и всегда проверяйте, является ли аргумент адаптера нулевым, и только затем используйте метод setAdapter для просмотра recycler. Если адаптер не является нулевым, просто вызовите notifyDataSetChanged или все, что необходимо для обновления ваших элементов.
+0

Я переместил код обновления в onCreateView и, похоже, работает нормально. –

+1

Удачи в Udacity с популярными фильмами Я думаю ;-) – daxgirl

0

Возможно, this может помочь. Несмотря на то, что он будет каждый раз прокручиваться до выбранного элемента.

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