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

时间:2017-05-10 13:33:37

标签: android mvvm

此代码在我将一些数据添加到“列表模型”并在旋转设备上恢复已保存数据时运行正常,遗憾的是在恢复数据后将其设置为model方法中的onRestoreInstanceState,添加其他数据后为此,适配器无法刷新新添加的数据,适配器中的数据源可以更新后,但适配器可以知道它们,我正在使用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);
    }

添加到model方法:

    @Override
    public void clickOnSendCommandToRobot() {
        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 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);
    }
}

我想知道为什么这段代码工作正常:

    @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);

        RobotViewModel temp = new RobotViewModel();

temp.setMessage("message");

        temp.setCommand(true);

        model.add(temp);

        adapter.notifyItemInserted(model.size() - 1);
        binding.registerRobot.scrollToPosition(adapter.getItemCount() - 1);
    }

没有任何问题,在移动这一行之后:

        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;
    }
}

SOURCE CODE IS HERE

问题出在clickOnRegisterMobileNumberclickOnSendCommandToRobot方法

3 个答案:

答案 0 :(得分:9)

我的问题已解决,

将以下行添加到您设置广告的特定活动的清单中

android:configChanges="screenSize|orientation|screenLayout" 

但如果您设计“纵向”和“横向”布局,或仅在这两种模式下运行应用程序,它将返回最佳视图。

答案 1 :(得分:1)

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);
        }
     public void setData(List<RobotViewModel> data) {
            Log.e("data size ", data.size() + "");
            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.

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

答案 2 :(得分:0)

我尝试了你的代码,只需很少的更新即可正常运行。 执行此操作时

 model.add(temp);
 adapter.notifyItemInserted(model.size() - 1);

您假设对象模型和适配器数据源之间的链接持久化。 这个假设是错误的,事实上如果你只是用

替换上面的代码
 model.add(temp);
 adapter.setData(model);
 adapter.notifyItemInserted(model.size() - 1);

它工作正常。 我希望它有所帮助。