我正在尝试让我的应用处理方向更改。现在我正在使用RecyclerView
来处理数据CustomAdapter
。我已经实现onSaveInstanceState
来保存Adapter
中的数据,但是当我在方向更改后重新插入它时,方法onBindViewHolder
不会被调用。我已确认数据已保存且数组列表不为空并包含我需要的数据。
以下是CustomAdapter
:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private static final String TAG = "CustomAdapter";
private ArrayList<Words> mDataSet;
private RecyclerView mRecyclerView;
private PopupWindow mPopupWindow;
private int currentPos;
private String srcOld;
private String targetOld;
private TranslateActivityFragment mFragment;
private EditText mEditSrc;
private EditText mEditTarget;
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private TextView textView2;
private TextView textView3;
public ViewHolder(View v){
super(v);
textView = v.findViewById(R.id.adapter_textview1);
textView2 = v.findViewById(R.id.adapter_textview2);
textView3 = v.findViewById(R.id.adapter_textview3);
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
mPopupWindow.showAtLocation(mRecyclerView, Gravity.CENTER,0,0);
mPopupWindow.setFocusable(true);
mPopupWindow.update();
currentPos = getAdapterPosition();
setCurrText();
}
private void setCurrText(){
Words tmp = mDataSet.get(currentPos);
srcOld = tmp.getW1();
targetOld = tmp.getW2();
mEditSrc.setText(srcOld);
mEditTarget.setText(targetOld);
}
});
}
public TextView getLeftTextView(){
return textView;
}
public TextView getCenterTextView(){return textView2;}
public TextView getRightTextView(){return textView3;}
}
public CustomAdapter(RecyclerView recyclerView, Context context, TranslateActivityFragment fragment){
mRecyclerView = recyclerView;
mDataSet = new ArrayList<Words>();
mFragment = fragment;
this.notifyDataSetChanged();
View v = LayoutInflater.from(mFragment.getActivity()).inflate(R.layout.edit_translate,null,false);
createPopupWindow(v, mFragment.getActivity());
setEditText(v);
}
private void setEditText(View v){
mEditSrc = v.findViewById(R.id.edit_src);
mEditTarget = v.findViewById(R.id.edit_target);
}
private void createPopupWindow(View v, Activity activity){
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
float width = 300*metrics.density;
float height = 200*metrics.density;
mPopupWindow = new PopupWindow(v,(int)width, (int)height);
Button buttonOk = v.findViewById(R.id.button_ok);
Button buttonCancel = v.findViewById(R.id.button_cancel);
Button buttonDelete = v.findViewById(R.id.button_delete);
buttonCancel.setOnClickListener(new CancelListener());
buttonOk.setOnClickListener(new OkListener());
buttonDelete.setOnClickListener(new DeleteListener());
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType){
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.textview_layout, viewGroup,false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position){
Log.d(TAG, "Element " + position + " set." + mDataSet.get(position).getW1());
viewHolder.getLeftTextView().setText(mDataSet.get(position).getW1());
viewHolder.getCenterTextView().setText(" - ");
viewHolder.getRightTextView().setText( mDataSet.get(position).getW2());
}
@Override
public int getItemCount() {
return mDataSet.size();
}
public void addData(Words newData, RecyclerView recyclerView){
mDataSet.add(newData);
System.out.println("------ ADDING DATA--------");
this.notifyDataSetChanged();
if (mDataSet.size() > 0) {
recyclerView.smoothScrollToPosition(mDataSet.size() - 1);
}
}
public void dismissPopup(){
mPopupWindow.dismiss();
}
public void removeWord(){
mDataSet.remove(currentPos);
System.out.println("mDataSet.size(): " + mDataSet.size());
System.out.println("mFragment.getTranslater.getData.size(): " + mFragment.getTranslater().getWords().size());
mFragment.getTranslater().deleteWord(currentPos);
this.notifyDataSetChanged();
}
// Update the current word from EditTexts
public void updateWord(){
String src = mEditSrc.getText().toString();
String target = mEditTarget.getText().toString();
mDataSet.get(currentPos).setW1(src);
mDataSet.get(currentPos).setW2(target);
mFragment.getTranslater().updateWord(src, target, currentPos);
this.notifyDataSetChanged();
}
private class OkListener implements View.OnClickListener {
@Override
public void onClick(View view) {
updateWord();
dismissPopup();
}
}
private class CancelListener implements View.OnClickListener{
@Override
public void onClick(View view){
dismissPopup();
}
}
private class DeleteListener implements View.OnClickListener{
@Override
public void onClick(View view){
removeWord();
dismissPopup();
}
}
public ArrayList<Words> getWords(){
return mDataSet;
}
public ArrayList<String> getW1List() {
ArrayList<String> tmp = new ArrayList<>();
for (Words w : mDataSet){
tmp.add(w.getW1());
}
return tmp;
}
public ArrayList<String> getW2List(){
ArrayList<String> tmp = new ArrayList<>();
for (Words w : mDataSet){
tmp.add(w.getW2());
}
return tmp;
}
//
// Here is where I try to restore data.
//
public void restoreWords(ArrayList<String> w1, ArrayList<String> w2, RecyclerView recyclerView){
if (mDataSet == null){
mDataSet = new ArrayList<>();
}
System.out.println("Restoring words");
for (int i = 0; i < w1.size(); ++i){
Words tmp = new Words(w1.get(i), w2.get(i), 0,0,0,false);
addData(tmp, recyclerView);
}
}
}
Fragment
中用于处理视图的代码:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new CustomAdapter(mRecyclerView, this.getContext(), this);
mRecyclerView.setAdapter(mAdapter);
if (savedInstanceState != null){
ArrayList<String> w1 = savedInstanceState.getStringArrayList(TranslateActivity.W1LIST);
ArrayList<String> w2 = savedInstanceState.getStringArrayList(W2LIST);
restoreWords(w1,w2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_translate, container, false);
mRecyclerView = root.findViewById(R.id.translate_recycle);
mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayout.VERTICAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
return root;
}
@Override
public void onViewCreated(View v, Bundle savedInstanceState){
mHelper = new Helper();
if (savedInstanceState == null) {
Intent intent = getActivity().getIntent();
source_lang = intent.getStringExtra(MainActivityFragment.SOURCE_LANG);
target_lang = intent.getStringExtra(MainActivityFragment.TARGET_LANG);
} else {
source_lang = savedInstanceState.getString(MainActivityFragment.SOURCE_LANG);
target_lang = savedInstanceState.getString(MainActivityFragment.TARGET_LANG);
}
key = mHelper.getKey(source_lang, target_lang);
mTranslater = new Translater(source_lang, target_lang, key);
setHasOptionsMenu(true);
setToolbarText();
}
public void restoreWords(ArrayList<String> w1, ArrayList<String> w2){
System.out.println("..................RESTORE WORDS....................");
mAdapter.restoreWords(w1, w2, mRecyclerView);
}
活动中的 onCreate
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
helper = new Helper();
mInAppPurchase = new InAppPurchase(this, this);
mInAppPurchase.setUpNoQuery();
setContentView(R.layout.activity_translate);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mFragment = new TranslateActivityFragment();
View v = LayoutInflater.from(getApplicationContext()).inflate(R.layout.start_purchase_ui, null, false);
createPopup(v, this);
getSupportFragmentManager().beginTransaction().replace(R.id.translate_layout, mFragment).commit();
}
我环顾四周,看到了一些改变getItemCount
而不返回0
的建议。这没有帮助,我真的不明白这是怎么回事。 Here它表示ListViews
必须在onCreateView
或onActivityCreated
进行恢复,但这也无济于事。
请注意,notifyDataSetChanged
addData(Words word)
编辑:我已将流程更改为以下内容:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_translate, container, false);
mRecyclerView = root.findViewById(R.id.translate_recycle);
mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayout.VERTICAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new CustomAdapter(mRecyclerView, this.getContext(), this);
mRecyclerView.setAdapter(mAdapter);
return root;
}
@Override
public void onViewCreated(View v, Bundle savedInstanceState){
mHelper = new Helper();
if (savedInstanceState == null) {
// Create helper instance
// Get the input view from which we get the source word
textInput = v.findViewById(R.id.source_input);
// Extract the chosen langauges
Intent intent = getActivity().getIntent();
source_lang = intent.getStringExtra(MainActivityFragment.SOURCE_LANG);
target_lang = intent.getStringExtra(MainActivityFragment.TARGET_LANG);
} else {
source_lang = savedInstanceState.getString(MainActivityFragment.SOURCE_LANG);
target_lang = savedInstanceState.getString(MainActivityFragment.TARGET_LANG);
ArrayList<String> w1 = savedInstanceState.getStringArrayList(TranslateActivity.W1LIST);
ArrayList<String> w2 = savedInstanceState.getStringArrayList(W2LIST);
restoreWords(w1,w2);
}
key = mHelper.getKey(source_lang, target_lang);
mTranslater = new Translater(source_lang, target_lang, key);
setHasOptionsMenu(true);
setToolbarText();
}
更多信息:
我有一个EditText
项目,我从中读取输入并添加到mAdapter
。轮换后,这仍然有效。只有当我尝试重新插入保存的数据时,它才会起作用。所以我怀疑restoreWords
是从错误的方法调用的?
答案 0 :(得分:0)
因此,似乎解决方案是在Activity
而不是Fragment
进行恢复。我和我的问题完全一样。我覆盖了onRestoreInstanceState
并将restoreWords
称为
public void restoreWords(ArrayList<String> w1, ArrayList<String> w2){
System.out.println("..................RESTORE WORDS....................");
for (int i = 0; i < w1.size(); ++i){
Words tmp = new Words(w1.get(i), w2.get(i), 0, 0, 0, false);
System.out.println(tmp.getW1() + " --- " + tmp.getW2());
mFragment.addWordToView(tmp);
}
System.out.println("-------------------Number of words in adapter: " + mFragment.getAdapter().getItemCount());
}
然后神奇地工作了。有人可以解释原因吗?