我用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>