TL;DR:が をリサイクルしているときと を交換しているときRecyclerView
の の呼び出しを区別できません。onBindViewHolder
View
Fragment
ここSOで答えを探すのに多くの時間を費やしましたが、結局何もうまくいきませんでした。それがしたことは、答えはおそらく を使用することにあると教えてくれましたが、savedInstanceState
うまく使用できませんでした。
構造 :
- メインフラグメント
- メインビュー
- SwitchFragmentButton
にMainView
は がありFrameLayout
、 を保持するために使用されますFragment
。
最初のFragment
ものは重要ではありませんが、2 番目Fragment
のものは でありOverviewFragment
、その構造は次のとおりです。
- 概要フラグメント
- RecyclerView
- CustomItemView
- テキストビュー
- ChangeTextColorButton
- アイテムの削除ボタン
- ...
- CustomItemView
- AddItemButton
- RecyclerView
RecyclerView
リストを水平にする必要があり、それが最も簡単な方法であるため、を使用しています。
望ましい動作:
ボタンを2回クリックしたとき(フラグメントを変更して元に戻すとき)に色の変更を保持したいのですが、リストからアイテムを削除してから再度追加したときは保持しません。
問題 :
色は常に保持されるか、まったく保持されません。onBindViewHolder
のアダプターでテキストの色を設定するために使用RecyclerView
すると、バインドがフラグメントの置換 (変更された色を復元する場所) によるものか、ビューのリサイクル (復元しない場所) によるものかを区別できません。
コード :
はSwitchFragmentButton
のメソッドOnClickListener
を呼び出しますMainView
void switchFragment(Fragment fragment) {
FragmentManager fm = mainFragment.getChildFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.mainView_fragment_slot, fragment);
ft.commit();
}
色の管理方法は次のとおりです(簡略化):
public class CustomItemView extends FrameLayout {
private TextView textView;
private int color;
/* other attributes */
public CustomItemView(/* any default constructor */) {
super(/* args */);
init();
}
private void init() {
inflate(getContext, R.layout.custom_item_view, this);
textView = (TextView) findViewById(R.id.customItemView_text_view);
ChangeTextColorButton ctcButton = /* ... */;
/* other views */
ctcButton.setOnClickListener(new OnClickListener() {
public void onClick() {
setColor(getColorWithDialogAndAll());
}
}
resetColor();
}
public void resetColor() {
setColor(0xff0000ff);
}
public void setColor(int color) {
this.color = color;
textView.setTextColor(color);
}
/* other methods */
}
RecyclerView
のAdapter
定義は次のとおりです。
public class MyAdapter extends RecyclerView.Adapter {
private List<MyItem> myItemList = new LinkedList<>();
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
MyViewHolder viewHolder = (MyViewHolder) holder;
//this is called in both situations
viewHolder.customItemView.resetColor();
}
/* other methods */
private class MyViewHolder extends RecyclerView.ViewHolder {
CustomItemView cutsomItemView;
/* constructor, calling super() and setting the attribute */
}
}
MyItem
ここに CustomItemView のコア項目があります (すべての MyItem にはその CustomItemView があり、すべての CustomItemView には MyItem があります)
ノート :
minSdkVersion
: 19.
編集 :
@goldenb のおかげで、問題が絞り込まれ、2 つの解決策が現れました。
解決策 1 :
フラグメントを置き換える代わりに、それらをすべて追加してから表示/非表示にします。
void switchFragment(Fragment fragment) {
FragmentManager fm = mainFragment.getChildFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.hide(currentFragment);
ft.show(R.id.mainView_fragment_slot, fragment);
ft.commit();
currentFragment = fragment;
}
この解決策は何とか機能しますが、問題の本当の解決策ではありません。の削除を回避するFragments
ため、状態が維持されます。
ただし、私の質問は、Fragment
の状態を保存して復元する方法に関するものであるため、これを回答として受け入れることはできません。
解決策 2 :
オーバーライドOverviewFragment#onPause
して状態を保存し、 で復元しOverviewFragment#onCreate
ます。
この解決策はもっともらしいようで、現在調査中です。CustomItemView
ただし、データを からに再配置するには、プロジェクトで再構築が必要なMyAdapter
ため、しばらく時間がかかります。