ui观察livedata< list< myobject>>显示新添加和新删除的对象,但不显示更新或更改

628mspwn  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(410)

所以我建立了一个小列表,在这里我可以将myobjects的示例添加到一个列表中。我的recyclerview正确地显示了新添加的示例,以及删除应该删除的内容。
但是,每当我尝试更改现有示例中的值时,更改不会显示,即使我在recyclerview中单击该项,它也会正确显示更改的数据。例如,如果我添加一个字符串值为“foo”、长值为10的myobject示例(即new myobject(“foo”,10)),并通过alertdialog编辑该示例,然后将“foo”更改为“bar”,ui仍将显示“foo”,但如果单击该项,其值现在显示为“bar”。有什么问题吗?
以下是我的活动主要内容:

public class ActivityMain extends AppCompatActivity implements MyObjectDialog.MyObjectDialogListener {

    static MyObjectViewModel myObjectViewModel;
    public static List<MyObject> listMyObject;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // lines for initializing views in layout

        listMyObject = new ArrayList<>();

        myObjectViewModel = new ViewModelProvider(this,
                new MyObjectViewModelFactory(this.getApplication(), listMyObject)).get(MyObjectViewModel.class);

    }

    @Override
    public void saveMyObject(MyObject myObject, int indexNumberInListMyObject, boolean isNewMyObject) {

        if (isNewMyObject) {
            myObjectViewModel.addMyObject(MyObject);
        } else {
            myObjectViewModel.setMyObject(indexNumberInListMyObject, MyObject);
        }
    }
}

包含显示myobject示例列表的recyclerview的片段:

public class MyObjectDebitFragment extends Fragment {

    private MyObjectAdapter myObjectAdapter;
    private MyViewModel myViewModel;

    private boolean isNewMyObject;
    private int indexNumberInListMyObject;

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // initialize views, set adapter, etc.

        myObjectViewModel = ActivityMain.myObjectViewModel;
        myObjectViewModel.getMutableLiveDataListMyObject().observe(getViewLifecycleOwner(), new Observer<List<MyObject>>() {
            @Override
            public void onChanged(List<MyObject> myObjects) {
                myObjectAdapter.submitList(myObjects);
            }
        });

        myObjectAdapter.setOnItemClickListener(new MyObjectAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(myObject clickedMyObject) {
                MyObjectDialog myObjectDialog = new myObjectDialog();
                Bundle bundleClickedMyObject = new Bundle();

                bundleClickedMyObject.putInt("indexNumberInListMyObject", ActivityMain.listMyObject.indexOf(clickedMyObject));
                bundleClickedMyObject.putBoolean("isNewMyObject", false); // only pre-existing items for MyObject can be clicked
                bundleClickedMyObject.putString("stringFieldOfMyObject", clickedMyObject.getStringFieldMyObject);
                bundleClickedMyObject.putLong("longFieldOfMyObject", clickedMyObject.getLongFieldMyObject);

                myObjectDialog.setArguments(bundleClickedMyObject);
                myObjectDialog.show(requireActivity().getSupportFragmentManager(), "myObjectDialog");
            }
        });

        new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
                ItemTouchHelper.LEFT) {
            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
                    myObjectViewModel.removeMyObject(myObjectAdapter.getMyObjectAt(viewHolder.getAdapterPosition()));
            }
        }).attachToRecyclerView(recyclerViewMyObject);
    }

}

这是myobject的类:

public class MyObject {

    private String StringFieldForMyObject;
    private long longFieldForMyObject;

    public JournalEntryDetail(String stringFieldForMyObject, long longFieldForMyObject) {
        this.stringFieldForMyObject = stringFieldForMyObject;
        this.longFieldForMyObject = longFieldForMyObject;
    }

    public String getStringFieldForMyObject() {
        return StringFieldForMyObject;
    }

    public void setStringFieldForMyObject(String StringFieldForMyObject) {
        this.StringFieldForMyObject = StringFieldForMyObject;
    }

    public Long getLongFieldForMyObject() {
        return longFieldForMyObject;
    }

    public void setLongFieldForMyObject(String longFieldForMyObject) {
        this.longFieldForMyObject = longFieldForMyObject;
    }
}

下面是我如何编写viewmodel的

public class MyViewModel extends AndroidViewModel {

  private MutableLiveData<List<MyObject>> mutableLiveDataListMyObject;
  private List<MyObject> listMyObject;

  public MyViewModel(@NonNull Application application, List<MyObject> paramListMyObject) {
    super(application);
    if (mutableLiveDataListMyObject == null){
      mutableLiveDataListMyObject = new MutableLiveData<>();
      listMyObject = paramList;
      mutableLiveDataListMyObject.setValue(paramListMyObject);
    }
  }

  public void addMyObject (MyObject myObject) {
    listMyObject.add(myObject);
  }

  public void setMyObject (int indexPosition, MyObject myObject) {
    listMyObject.set(indexPosition, myObject);
  }

  public void removeMyObject(MyObject myObject) {
    listMyObject.remove(myObject);
  }

  public LiveData<List<MyObject>> getMutableLiveDataListMyObject() {
    return mutableLiveDataListMyObject;
  }
}

myviewmodel的工厂类

public class MyViewModelFactory extends ViewModelProvider.AndroidViewModelFactory {

    private Application application;
    private List<MyObject> listMyObject;

    public MyViewModelFactory(Application paramApplication, List<MyObject> paramListMyObject) {
        super(paramApplication);
        application = paramApplication;
        listMyObject = paramListMyObject;
    }

    @NonNull
    @Override
    public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
        if (modelClass == MyViewModel.class) {
            return (T) new MyViewModel(application, listMyObject);
        }
        return null;
    }
}

用于编辑或添加myobject新示例的对话框

public class MyObjectDialog extends DialogFragment {

    private MyObjectDialogListener MyObjectDialogListener;

    private boolean isNewMyObject;
    private int indexNumberInListMyObject;
    private String stringFieldOfMyObject;
    private long longFieldOfMyObject;

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        super.onCreateDialog(savedInstanceState);

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(requireActivity());

    // lines for initializing views

        if (getArguments() != null) {
        isNewMyObject = getArguments().getBoolean("isNewMyObject", true)
        indexNumberInListMyObject = getArguments().getInt("indexNumberInListMyObject", 0);
        stringFieldOfMyObject = getArguments().getString("stringFieldOfMyObject");
        longFieldOfMyObject = getArguments().getString("longFieldOfMyObject", 0);

                editTextStringFieldOfMyObject.setText(stringFieldOfMyObject);
                editTextLongFieldOfMyObject.setText(String.valueOf(longFieldOfMyObject));
        }

        alertDialogBuilder.setView(itemView)
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // do nothing
                    }
                })
                .setPositiveButton("Save", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        stringFieldOfMyObject = editTextStringFieldOfMyObject.getText().toString();
                        longFieldOfMyObject = Long.parseLong(editTextLongFieldOfMyObject.getText().toString());

                        MyObject myObject = new MyObject(stringValue, longValue);

                        MyObjectDialogListener.saveMyObject(myObject, indexNumberInListMyObject, isNewMyObject);
                    }
                });

        return alertDialogBuilder.create();
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        try {
            MyObjectDialogListener = (MyObjectDialogListener) context;
        } catch (ClassCastException e) {
            e.printStackTrace();
            throw new ClassCastException(context.toString() +
                    "Must implement MyObjectDialogListener");
        }
    }

    public interface MyObjectDialogListener {
        void saveMyObject(MyObject myObject, int indexInListMyObject, boolean isNewMyObject);
    }
}
tag5nh1u

tag5nh1u1#

我在viewmodel类中添加行mutablelivedatalistmyobject.setvalue(listmyobject)解决了这个问题:

public void addMyObject (MyObject myObject) {
    listMyObject.add(myObject);
    mutableLiveDataListMyObject.setValue(listMyObject);
  }

  public void setMyObject (int indexPosition, MyObject myObject) {
    listMyObject.set(indexPosition, myObject);
    mutableLiveDataListMyObject.setValue(listMyObject);
  }

  public void removeMyObject(MyObject myObject) {
    listMyObject.remove(myObject);
    mutableLiveDataListMyObject.setValue(listMyObject);
  }

在viewmodel示例的observer实现中,我添加了myobjectadapeter.notifydatasetchanged():

myObjectViewModel.getMutableLiveDataListMyObject().observe(getViewLifecycleOwner(), new Observer<List<MyObject>>() {
            @Override
            public void onChanged(List<MyObject> myObjects) {
                myObjectAdapter.submitList(myObjects);
                myObjectAdapeter.notifyDataSetChanged();
            }
        });

我还没有完全理解为什么我在使用mutablelivedata时必须这样做,因为当我使用room时,我不必做这两个。

相关问题