我在 AppCompatActivity
中有一个 RecyclerView
。旋转设备后,项目插入和更改会正确显示和动画。
问题发生在您:
- 点击
RecyclerView
中的项目。 DialogFragment
打开提示是否要删除项目。- 旋转设备。
- 在对话框中确认删除。
- 检查数组列表。该项目已被删除。
RecyclerView
仍然显示项目。
尝试使用 notifyDataSetChanged
而不是 notifyItemRemoved
但也没有用,因为该项目仍在 RecyclerView
中显示。
任何版本的 Android 都会发生这种情况。
流程处理方式的简化代码:
public class MyAppCompatActivity extends AppCompatActivity {
int positionOfDeletedItem;
MyObjectRecyclerViewAdapter adapter;
ArrayList<MyObject> someTestData;
MyItemDeletionHandler deletionHandlerRemover;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity_layout);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
positionOfDeletedItem = 1;
deletionHandlerRemover = new MyItemDeletionHandler(this);
someTestData = new ArrayList<MyObject>(3);
someTestData.add(new MyObject("A"));
someTestData.add(new MyObject("B"));
someTestData.add(new MyObject("C"));
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyObjectRecyclerViewAdapter(new MyAdapterOnClickEvent.OnItemClick() {
@Override
public void onClick(int posicion, int idViaje, View view) {
String tag = "Some tag value";
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag(tag);
if(prev != null)
ft.remove(prev);
ft.addToBackStack(null);
DialogFragment newFragment = MyDeletionConfirmationDialog.newInstance(deletionHandlerRemover);
newFragment.show(ft, tag);
}
}, someTestData);
recyclerView.setAdapter(adapter);
}
private final static class MyItemDeletionHandler extends Handler {
private final WeakReference<MyAppCompatActivity> theActivity;
private MyItemDeletionHandler(MyAppCompatActivity act) {
theActivity = new WeakReference<MyAppCompatActivity>(act);
}
@Override
public void handleMessage(Message msg) {
MyAppCompatActivity activity = theActivity.get();
if(activity != null) {
if(msg.what == 1) {
activity.deleteTheItem();
}
}
}
}
public void deleteTheItem() {
someTestData.remove(positionOfDeletedItem);
adapter.notifyItemRemoved(positionOfDeletedItem);
}
}
public class MyDeletionConfirmationDialog extends DialogFragment {
private Message handlerMessage;
public static MyDeletionConfirmationDialog newInstance(Handler callbackHandler) {
MyDeletionConfirmationDialog myDialog = new MyDeletionConfirmationDialog();
Bundle args = new Bundle();
args.putParcelable("handlerMessage", callbackHandler.obtainMessage(1, true));
myDialog.setArguments(args);
return myDialog;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handlerMessage = getArguments().getParcelable("handlerMessage");
}
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
alertDialogBuilder.setMessage("Some message");
alertDialogBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
final Message toSend = Message.obtain(handlerMessage);
toSend.sendToTarget();
}
});
alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
Dialog dialog = alertDialogBuilder.create();
dialog.setCanceledOnTouchOutside(true);
return dialog;
}
}
如何让 RecyclerView
正常工作?
编辑 1:
我还有其他 RecyclerView
可以正常工作。唯一的区别是它们在 Fragment
中,而不是在 AppCompatActivity
中。我怀疑这与 RecyclerView
的事件 onDetachedFromWindow
和 onAttachedToWindow
有关。
编辑 2:
如果对话框关闭(第 4 步)并再次打开,它将按预期工作。
编辑 3:
如果 RecyclerView
被提取为 Fragment
,问题就会消失并按预期工作。上述用例与 AppCompatActivity
而不是 Fragment
一起正确工作是不可能的。
最佳答案
我在使用 RecyclerView 时遇到了类似的问题。 当我向左滑动以删除一个项目然后旋转屏幕时,该项目已从我的数据集中删除,但屏幕并没有像我们在不旋转的情况下执行相同操作时通常那样刷新。似乎 adaptar.notifyItemRemoved() 根本没有刷新屏幕。
我正在使用 Nemanja Kovacevic源代码作为起点,但我对其进行了一些更改(如添加项目点击、使用对话框编辑、数据库支持等)。
所以我读了这个post这给了我一个关于可能出了什么问题的提示。 似乎 adapter.notify 在旋转之前仍然指向以前的适配器引用。每次我们旋转时,都会在 Activity:OnCreate 中创建一个新的适配器
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,
AddAlertDialog.OnAlertSavedListener,
AlertListAdapter.OnItemDeletedListener {
static ListAdapter mListAdapter;
RecyclerView mRecyclerView;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mRecyclerView = (RecyclerView) findViewById(R.id.mainListView);
mDB = new DatabaseTable(this);
// Reading all alerts
ArrayList<Alert> alerts = mDB.getAllAlerts();
if (mListAdapter == null)
mListAdapter = new ListAdapter(this, alerts);
}
}
也许它并不理想(创建静态对象不是一个好主意),但它解决了问题。
希望对你也有帮助。
关于android - 使用打开的 DialogFragment 旋转设备后 RecyclerView 不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36813726/