问题
The RecyclerView when launched shows all the data instead of showing data of a specific id. I am using Room database and as I understand the problem is when the ViewModel is getting initialized, the repository gets all the colors.. I couldn't figure out how to code in Repository, so that when the ViewModel is initialized it only gets data of specific ids instead of all data.
In one of the answers in stack it mentions something about using "SwitchMap"...but I am new to Android so not sure if it should be used and how it should be used.
Below is my related code below:
Fragment Code:
'''
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
recyclerViewColors = getActivity().findViewById(R.id.recyclerViewColors);
recyclerViewColors.setHasFixedSize(true);
layoutManagerColors = new LinearLayoutManager(getActivity()); //This is the code for LinearLayoutManager
recyclerViewColors.setLayoutManager(layoutManagerColors);
mAdapterColors = new MyAdapterColors(colors); //MyAdapter is a Recycler.Adapter class
recyclerViewColors.setAdapter(mAdapterColors);
addColor = getActivity().findViewById(R.id.addColor);
addColor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle bundle = new Bundle();
if(id != -1){
bundle.putInt("ID",id);
}
Navigation.findNavController(getActivity().findViewById(R.id.editLinear)).navigate(R.id.action_editStatusFragment_to_addColors3, bundle);
}
});
edit_text_titleedit = getActivity().findViewById(R.id.edit_text_titleedit);
edit_text_descriptionedit = getActivity().findViewById(R.id.edit_text_descriptionedit);
edit_text_titleedit.setText(title);
edit_text_descriptionedit.setText(description);
((AppCompatActivity) getActivity()).getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close);
mViewModel = new ViewModelProvider(this).get(FragmentStatusViewModel.class);
mViewModel.loadComments(id).observe(getViewLifecycleOwner(), new Observer<List<Colors>>() {
@Override
public void onChanged(List<Colors> colors) {
// Toast.makeText(getActivity(), "size is = " + colors.size() + " & "
// + id, Toast.LENGTH_SHORT).show();
mAdapterColors.setColors(colors);
}
});
if (getArguments() != null && getArguments().containsKey("IDAdd")){
String colorname = getArguments().getString("colorname");
String fabricquality = getArguments().getString("fabricquality");
String productionunitname = getArguments().getString("productionunitname");
String millname = getArguments().getString("millname");
int statusid = getArguments().getInt("IDAdd");
Colors colors = new Colors(colorname,fabricquality,productionunitname,millname, statusid);
mViewModel.insert(colors);
//mViewModel.getAllStyles(statusid);
Toast.makeText(getActivity(), "Status id = " + statusid, Toast.LENGTH_LONG).show();
}else {
//Toast.makeText(getActivity(), "id is " + id, Toast.LENGTH_SHORT).show();
Toast.makeText(getActivity(), "Colors displayed!", Toast.LENGTH_SHORT).show();
}
}
'''
adapter code:
'''
public class MyAdapterColors extends RecyclerView.Adapter<MyViewHolderColors> {
private List<Colors> colors;
public MyAdapterColors(List<Colors> colors) {
this.colors = colors;
}
@NonNull
@Override
public MyViewHolderColors onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.colorsrow, parent, false);
MyViewHolderColors myViewHolderColors = new MyViewHolderColors(view);
return myViewHolderColors;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolderColors holder, int position) {
Colors color = colors.get(position);
holder.colorname.setText(color.getColorname().toString());
holder.fabricquality.setText(color.getFabricQuality());
holder.productionunitname.setText(color.getProductionUnitName());
holder.fabricmill.setText(color.getFabricMill());
}
@Override
public int getItemCount() {
return colors.size();
}
public void setColors(List<Colors> newcolors) {
this.colors = newcolors;
notifyDataSetChanged();
}
public Colors getColorsAt(int position) {
return colors.get(position);
}
}
''' ViewModel Code
'''
public class FragmentStatusViewModel extends AndroidViewModel {
private Status_Repository repository;
private MutableLiveData<Integer> id;
List<Colors> colors;
private LiveData<List<Status>> allStatus;
private LiveData<List<Colors>> allColors;
private LiveData<List<Stylewithcolors>> stylewithcolors;
public FragmentStatusViewModel(@NonNull Application application) {
super(application);
repository = new Status_Repository(application);
allStatus = repository.getAllStatus();
}
LiveData<List<Colors>> loadComments(int statusId){
allColors = repository.loadComments(statusId);
return allColors;
}
''' My Repository Code: ''' public class Status_Repository {
private StatusDao statusDao;
private LiveData<List<Status>> allStatus;
List<Colors> colors;
private LiveData<List<Colors>> allColors;
// private ColorsDao colorsDao;
// private LiveData<List<Colors>> allColors;
//private List<Colors> colors;
private LiveData<List<Stylewithcolors>> allStyles;
public Status_Repository(Application application) {
Status_Database database = Status_Database.getInstance(application);
statusDao = database.statusDao();
allStatus = statusDao.getAllStatus();
allColors = statusDao.getAllColors();
// colorsDao = database.colorsDao();
// allColors = colorsDao.getAllColors();
}
LiveData<List<Colors>> loadComments(int statusId){
Status_Database.databaseWriteExecutor.execute(() -> {
allColors = statusDao.loadComments(statusId);
});
return allColors;
}
''' Dao Query:
'''
@Query("SELECT * FROM colors where statusid = :statusId")
LiveData<List<Colors>> loadComments(int statusId);
'''
XML code of the 2nd Fragment
'''
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/editLinear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:orientation="vertical"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:context=".UpdateFragment">
<EditText
android:id="@+id/edit_text_titleedit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Title"
android:inputType="text" />
<EditText
android:id="@+id/edit_text_descriptionedit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Description"
android:inputType="textMultiLine" />
</LinearLayout>
<Button
android:id="@+id/addColor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="Add Color"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/editLinear" />
<androidx.cardview.widget.CardView
android:id="@+id/cardRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/addColor">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewColors"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
'''
回答1:
I solved the problem by directly accessing Repository from the Fragment and skipping the ViewModel. Now the RecyclerView shows the detail of the selected id only.
It solves my problem but I dont know if it will create any problem or if it is the correct way to solve the problem... Now I don't understand why should we use ViewModel if we can directly access Repository from Fragment in case of Room Database.
Now my Repository code and Fragment Code looks like below
'''
Status_Repository repository = new Status_Repository(getActivity().getApplication(), id);
//MyViewModelTest myViewModel = new ViewModelProvider(this, new MyViewModelFactory(getActivity().getApplication(), id)).get(MyViewModelTest.class);
repository.loadComments(id).observe(getViewLifecycleOwner(), new Observer<List<Colors>>() {
@Override
public void onChanged(List<Colors> colors) {
Toast.makeText(getActivity(), "size is = " + colors.size() + " & "
+ id, Toast.LENGTH_SHORT).show();
mAdapterColors.setColors(colors);
}
});
''' Repository Code
'''
public Status_Repository(Application application, int id) {
Status_Database database = Status_Database.getInstance(application);
statusDao = database.statusDao();
allStatus = statusDao.getAllStatus();
allColors = statusDao.loadComments(id);
// colorsDao = database.colorsDao();
// allColors = colorsDao.getAllColors();
}
'''
来源:https://stackoverflow.com/questions/62210271/recycler-view-shows-all-data-from-room-database-instead-of-just-showing-data-of