LinearLayoutManager的方法onSaveInstanceState和onRestoreInstanceState不恢复RecyclerView的滚动状态

时间:2018-04-04 10:48:19

标签: android android-recyclerview

我用FAB菜单和RecyclerView编写了一个活动(WordsActivity),它表示包含单词及其翻译的项目列表。这样的列表可能很长,所以我想在屏幕旋转期间保持滚动位置。为此,我实现了LinearLayoutManager的方法onSaveInstanceState和onRestoreInstanceState(https://developer.android.com/reference/android/support/v7/widget/LinearLayoutManager.html#onRestoreInstanceState(android.os.Parcelable) 我在这个答案中找到了保存状态的技巧: https://stackoverflow.com/a/45436460/9214917 但是在我的代码中这个方法没有带来任何影响:在屏幕旋转后,recyclerView会回到初始项目。在这个阶段我的程序不会抛出任何异常,所以我需要你的帮助来定义我的位置我错了。

public class WordsActivity extends AppCompatActivity implements TextToSpeech.OnInitListener {
private WordsAdapter adapter;
private RecyclerView mRecyclerView;
private VocaNoteViewModel mVocaNoteViewModel;
private String origWord;
private String language;
private String translation;
private Parcelable listState;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_words);
    // TODO: 02.04.2018 Save instance of recycler view appearance
    if(savedInstanceState != null){
        listState = savedInstanceState.getParcelable("KeyForLayoutManagerState");
    }
    //Creating of toolbar with title Words
    Toolbar myToolbar = findViewById(R.id.toolbar_words);
    setSupportActionBar(myToolbar);
    //Enable Up Button
    ActionBar ab = getSupportActionBar();
    ab.setDisplayHomeAsUpEnabled(true);
    String nameGroup = "Hello";
    //RecyclerView containing the list of VocaNotes with sound icons
    mRecyclerView = initRecyclerView();
    //Using ViewModel to observe VocaNote data
    mVocaNoteViewModel = ViewModelProviders.of(this).get(VocaNoteViewModel.class);
    mVocaNoteViewModel.getByGroupVcVocaNote(nameGroup).observe(this, new Observer<List<VocaNote>>() {

        @Override
        public void onChanged(@Nullable List<VocaNote> vocaNotes) {
            adapter.setVocaNotes(vocaNotes);
        }
    });
}

protected RecyclerView initRecyclerView() {
    RecyclerView recyclerView = findViewById(R.id.words_recycler_view);
    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    if (listState != null){
        layoutManager.onRestoreInstanceState(listState);
    }
    recyclerView.setLayoutManager(layoutManager);
    OnItemClicked listener = (v, position) -> {
        origWord = adapter.getmVocaNotes().get(position).getOriginWord();
        translation = adapter.getmVocaNotes().get(position).getTranslation();
        switch (v.getId()) {
            case R.id.word_sound:
                speakOut();
                break;
            default:
                Log.i("TAG", "Well Done");
                break;
        }
    };
    adapter = new WordsAdapter(this, listener);
    adapter.notifyItemInserted(adapter.getItemCount());
    recyclerView.setAdapter(adapter);
    DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
            layoutManager.getOrientation());
    recyclerView.addItemDecoration(dividerItemDecoration);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    return recyclerView;
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putParcelable("KeyForLayoutManagerState",
            mRecyclerView.getLayoutManager().onSaveInstanceState());
    super.onSaveInstanceState(outState);
}
}

RecyclerViews的适配器

public class WordsAdapter extends
    RecyclerView.Adapter<WordsViewHolder> {

private LayoutInflater mInflater;
List<VocaNote> mVocaNotes;
private OnItemClicked onClick;

public WordsAdapter(Context context, OnItemClicked onClick) {
    mInflater = LayoutInflater.from(context);
    this.onClick = onClick;
}

public List<VocaNote> getmVocaNotes() {
    return mVocaNotes;
}

@Override
public WordsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = mInflater.inflate(R.layout.layout_list_of_words, parent, false);
    return new WordsViewHolder(itemView, onClick);
}

@Override
public void onBindViewHolder(WordsViewHolder holder, int position) {
    if (mVocaNotes != null) {
        VocaNote current = mVocaNotes.get(position);
        holder.getWordNum().setText(String.valueOf(position + 1));
        holder.getOrigWord().setText(current.getOriginWord());
        holder.getTransWord().setText(current.getTranslation());

    } else {
        Log.i("INF", "No words in this group.");
    }
}

@Override
public int getItemCount() {
    if (mVocaNotes != null)
        return mVocaNotes.size();
    else return 0;
}

public void setVocaNotes(List<VocaNote> mVocaNotes) {
    this.mVocaNotes = mVocaNotes;
    notifyDataSetChanged();
}
}

ViewHolder

 public class WordsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

private OnItemClicked onClick;
private ImageView soundIcon;
private TextView wordNum;
private TextView origWord;
private TextView transWord;

public WordsViewHolder(View itemView, OnItemClicked onClick) {
    super(itemView);
    this.onClick = onClick;
    soundIcon = itemView.findViewById(R.id.word_sound);
    wordNum = itemView.findViewById(R.id.wordNum);
    origWord = itemView.findViewById(R.id.originWord);
    transWord = itemView.findViewById(R.id.translation);
    soundIcon.setOnClickListener(this);
    itemView.setOnClickListener(this);
}

public TextView getWordNum() {
    return wordNum;
}

public TextView getOrigWord() {
    return origWord;
}

public TextView getTransWord() {
    return transWord;
}

@Override
public void onClick(View v) {
    onClick.onItemClick(v, getAdapterPosition());
}
}

活动布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <include
        android:id="@+id/toolbar_words"
        layout="@layout/layout_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/words_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

<com.github.clans.fab.FloatingActionMenu
    android:id="@+id/menu_fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentEnd="true"
    android:layout_margin="8dp"
    fab:menu_animationDelayPerItem="0"
    fab:menu_colorNormal="@color/colorAccent"
    fab:menu_colorPressed="@color/fabPressed"
    fab:menu_colorRipple="@color/fabRipple"
    fab:menu_icon="@drawable/ic_add_white_24dp"
    fab:menu_labels_ellipsize="end"
    fab:menu_labels_maxLines="1">

    <com.github.clans.fab.FloatingActionButton
        android:id="@+id/fab_add_vocanote"
        style="@style/FabButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_create_white_24dp"
        fab:fab_label="@string/new_vocanote"
        fab:fab_size="mini" />

    <com.github.clans.fab.FloatingActionButton
        android:id="@+id/fab_add_group"
        style="@style/FabButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_folder_white_24dp"
        fab:fab_label="@string/new_group"
        fab:fab_size="mini" />

</com.github.clans.fab.FloatingActionMenu>

0 个答案:

没有答案