Android刷新适配器工作后再次旋转设备

Android刷新适配器工作后再次旋转设备,android,mvvm,Android,Mvvm,当我将一些数据添加到“列表模型”中并在旋转设备上恢复保存的数据时,此代码工作正常,不幸的是,在还原数据并将其设置为onRestoreInstanceState方法中的model之后,在向该方法添加其他数据之后,适配器无法使用新添加的数据刷新,数据源在适配器之后可以更新,但适配器可以;我不了解它们,我正在使用MVVM数据模型绑定并搜索更多关于这个问题的时间,我无法解决这个问题 Rhat有一个简单的提示,在再次旋转设备之后,我的适配器可以使用所有添加的数据进行刷新,而适配器不会使用这些数据进行刷新

当我将一些数据添加到“列表模型”中并在旋转设备上恢复保存的数据时,此代码工作正常,不幸的是,在还原数据并将其设置为
onRestoreInstanceState
方法中的
model
之后,在向该方法添加其他数据之后,适配器无法使用新添加的数据刷新,数据源在适配器之后可以更新,但适配器可以;我不了解它们,我正在使用
MVVM
数据模型绑定并搜索更多关于这个问题的时间,我无法解决这个问题

Rhat有一个简单的提示,在再次旋转设备之后,我的适配器可以使用所有添加的数据进行刷新,而适配器不会使用这些数据进行刷新

public class ActivityRegister extends BaseActivities{
    private  List<RobotViewModel> model  = new ArrayList<>();
    ...
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ...
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putParcelable("model", Parcels.wrap(model));
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle outState) {
        model = Parcels.unwrap(outState.getParcelable("model"));

        adapter.setData(model);
        adapter.notifyItemInserted(model.size() - 1);
        binding.registerRobot.scrollToPosition(adapter.getItemCount() - 1);
    }
我的适配器类:

public class RobotMessagesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<RobotViewModel> list;
    private LayoutInflater       inflater;

    public RobotMessagesAdapter(List<RobotViewModel> robotViewModels) {
        this.list = robotViewModels;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (inflater == null) {
            inflater = LayoutInflater.from(parent.getContext());
        }
        if (viewType == SV.RobotMessageType.SENT_BY_USER.ordinal()) {
            return new UserViewHolder(UserMessagesDataBinding.inflate(inflater, parent, false));
        } else {
            return new RobotViewHolder(RobotDataBinding.inflate(inflater, parent, false));
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (getItemViewType(position)) {
            case 0:
                ((UserViewHolder) holder).bind(list.get(position));
                break;
            case 1:
                ((RobotViewHolder) holder).bind(list.get(position));
                break;
        }
    }

    ...

    public void setData(List<RobotViewModel> data) {
        Log.e("data size ", data.size() + "");
        list.clear();
        list.addAll(data);
    }
}
没有任何问题,移动此线路后:

        RobotViewModel temp = new RobotViewModel();

temp.setMessage("message");

        temp.setCommand(true);

        model.add(temp);

        adapter.notifyItemInserted(model.size() - 1);
        binding.registerRobot.scrollToPosition(adapter.getItemCount() - 1);
到其他不起作用的方法:|

我的演示者:

public class ActivityRegisterPresenter {
    private ActivityRegisterContract view;

    public ActivityRegisterPresenter(ActivityRegisterContract mView) {
        view = mView;
    }

    ...
}
和我的ViewModel:

public class ActivityRegisterViewModel extends BaseObservable {
    private String readContactPermission;
    private String getMessages;

    public ActivityRegisterViewModel() {
    }

    @Bindable
    public String getReadContactPermission() {
        return readContactPermission;
    }

    public void setReadContactPermission(String readContactPermission) {
        this.readContactPermission = readContactPermission;
        notifyChange();
    }

    public String getGetMessages() {
        return getMessages;
    }

    public void setGetMessages(String getMessages) {
        this.getMessages = getMessages;
    }
}

问题出现在
clickOnRegisterMobileNumber
clickOnSendCommandToRobot
方法中

The main reason is that, because you called set-data and that method did not immediately notify that the data set was changed, therefore it was not ware.

      public void setData(List<RobotViewModel> data) {
            Log.e("data size ", data.size() + "");
            list.clear();
            list.addAll(data);
        }

主要的问题是,您从未通知您所做的更改,您清除了它,但您从未告诉它,您知道,但适配器不知道,您还使用
addAll
插入了新数据,但您仍然没有通知它。

我尝试了您的代码,它只需几次更新即可正常工作。 当您执行此操作时

 model.add(temp);
 adapter.notifyItemInserted(model.size() - 1);
假设对象模型和适配器数据源之间的链接是持久的。 这种假设是错误的,事实上,如果您只是将上面的代码替换为

 model.add(temp);
 adapter.setData(model);
 adapter.notifyItemInserted(model.size() - 1);
它很好用。 希望有帮助。

我的问题解决了

在为您设置适配器的特定活动将以下行添加到清单中之后

android:configChanges="screenSize|orientation|screenLayout" 

但是,如果您同时设计纵向和横向布局,或者只在其中一种模式下运行应用程序,它将返回最佳视图。

那么旋转是问题所在吗?@Remario在更改设备旋转并使用
clickOnSendCommandToRobot
方法添加更多项目后。我没有在适配器上看到它们,但在再次旋转设备后,我在适配器上看到它们adapter@Remario我的帖子更新了。好吧,给我一些时间,很快就会发布一个答案@Remario非常感谢,你想和我一起获取源代码吗?另一个原因是你使用了list.addAll(data);,但您从未清理或删除以前的模型数据。我想你是想在已有的条目中添加一个条目!问题是通知适配器使用新保存的数据更新到
model
后,旋转设备
setData
以精细和刷新我的适配器,但在向
model
添加更多数据后,例如单击按钮无法通知我的适配器使用新数据更新,根本无法刷新,使用
setData
on click方法清除适配器上的所有数据的原因意外问题无法解决先生,您可以在
clickOnRegisterMobileNumber
方法和
clickOnSendCommandToRobot
@Remario:数据编辑后应调用
notifydatasetchange()
,所以在
list.addAll(data)
之后。我错了吗?是的,这是基于国家的内部执行。当您将数据放入其中时,它会缓存并记住该数据状态,如果发生了某些事情而您没有通知它更改,它将不知道该状态是否已更改。
            list.clear();
            notifyDataSetChanged(); //here,to signal change occurred.
            list.addAll(data);
            notifyDataSetChanged(); //here,to signal change occurred.

        }

should probably get into the habit of notifying changes on the spot.
 model.add(temp);
 adapter.notifyItemInserted(model.size() - 1);
 model.add(temp);
 adapter.setData(model);
 adapter.notifyItemInserted(model.size() - 1);
android:configChanges="screenSize|orientation|screenLayout"