I am new to programming and I followed this tutorial to create a RecyclerView making use of an adapter. I have no idea how to use the delete function from my Dao in relation to the ImageButton. I have next to each entry. Also, this is my first app, so please be gracious when you see things like ".allowMainThreadQueries".
Activity with recyclerview:
public class DatabaseActivity extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
FloatingActionButton fab;
ImageButton delete;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_database);
recyclerView = findViewById(R.id.recycler_view);
AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "production").allowMainThreadQueries().build();
final List<Student> students = db.studentDao().getAllUsers();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new StudentAdapter(students);
recyclerView.setAdapter(adapter);
fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(DatabaseActivity.this, DatabaseAddActivity.class));
}
});
}
}
Adapter:
class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.ViewHolder> {
List<Student> students;
public StudentAdapter(List<Student> students) {
this.students = students;
}
#Override
public StudentAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.student_row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(StudentAdapter.ViewHolder holder, int position) {
holder.first_name.setText(students.get(position).getFirstName());
holder.last_name.setText(students.get(position).getLastName());
holder.email.setText(students.get(position).getEmail());
}
//See how many items need to be displayed
#Override
public int getItemCount() {
return students.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView first_name;
public TextView last_name;
public TextView email;
public ImageButton delete;
//What we are showing in the viewholder
public ViewHolder(View itemView) {
super(itemView);
first_name = itemView.findViewById(R.id.first_name);
last_name = itemView.findViewById(R.id.last_name);
email = itemView.findViewById(R.id.email);
delete = itemView.findViewById(R.id.delete);
}
}
}
Dao:
#Dao
public interface StudentDao {
#Query("SELECT * FROM student ")
List<Student> getAllUsers();
#Query("SELECT * FROM student WHERE monday = 1")
List<Student> getMonday();
#Query("SELECT * FROM student WHERE tuesday = 1")
List<Student> getTuesday();
#Query("SELECT * FROM student WHERE wednesday = 1")
List<Student> getWednesday();
#Query("SELECT * FROM student WHERE thursday = 1")
List<Student> getThursday();
#Query("SELECT * FROM student WHERE friday = 1")
List<Student> getFriday();
#Insert
void insertAll(Student... students);
#Delete
void delete(Student student);
#Update
void updateStudent(Student student);
}
Student Add:
public class DatabaseAddActivity extends AppCompatActivity {
//Calling needed resources
EditText firstName;
EditText lastName;
EditText email;
Button button;
CheckBox monday, tuesday, wednesday, thursday, friday;
//Defining which view.xml file to use
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_database_add);
//Using resources to find using .xml setup
firstName = findViewById(R.id.first_name);
lastName = findViewById(R.id.last_name);
email = findViewById(R.id.email);
monday = findViewById(R.id.monday_switch);
tuesday = findViewById(R.id.tuesday_switch);
wednesday = findViewById(R.id.wednesday_switch);
thursday = findViewById(R.id.thursday_switch);
friday = findViewById(R.id.friday_switch);
button = findViewById(R.id.button_add);
//What happens when button is pressed
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "production").allowMainThreadQueries().build();
Boolean mondayState = monday.isChecked();
Boolean tuesdayState = tuesday.isChecked();
Boolean wednesdayState = wednesday.isChecked();
Boolean thursdayState = thursday.isChecked();
Boolean fridayState = friday.isChecked();
Student student = new Student(firstName.getText().toString(), lastName.getText().toString(), email.getText().toString(), mondayState, tuesdayState, wednesdayState, thursdayState, fridayState);
db.studentDao().insertAll(student);
startActivity(new Intent(DatabaseAddActivity.this,DatabaseActivity.class));
}
});
}
}
In DatabaseActivity:
adapter = new StudentAdapter(db, students);
UPDATED
In your Adapter class:
AppDatabase db;
List<Student> students;
public StudentAdapter(AppDatabase db, List<Student> students) {
this.db = db;
this.students = students;
}
#Override
public void onBindViewHolder(StudentAdapter.ViewHolder holder, int position) {
Student student = students.get(position);
holder.first_name.setText(students.get(position).getFirstName());
holder.last_name.setText(students.get(position).getLastName());
holder.email.setText(students.get(position).getEmail());
holder.delete.setOnClickListener.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
db.delete(student);
students.remove(student);
notifyItemRemoved(position);
}
});
}
Related
First of all, sorry if my English is bad cause I'm from Spain.
I create a DB of football players (don't judge, is for school) and I want to show in the linear layout every player I add in the DB.
Here is my main activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b1 = findViewById(R.id.insertar);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DataBaseHelper helper = new DataBaseHelper(MainActivity.this);
SQLiteDatabase db = helper.getWritableDatabase();
if (db != null) {
Toast.makeText(MainActivity.this, "Insertado con éxito.", Toast.LENGTH_LONG).show();
db.close();
}
}
});
}
public void add(View view) {
DataBaseHelper helper = new DataBaseHelper(MainActivity.this);
SQLiteDatabase db = helper.getWritableDatabase();
TextView nombreJugador = findViewById(R.id.nombre);
TextView posicionJugador = findViewById(R.id.posicion);
TextView dorsalJugador = findViewById(R.id.dorsal);
if (db != null) {
ContentValues values = new ContentValues();
values.put("nombre", nombreJugador.getText().toString());
values.put("posicion", posicionJugador.getText().toString());
values.put("dorsal", dorsalJugador.getText().toString());
db.close();
}
}
public void changeToShowDB(View v) {
Intent actividad = new Intent(MainActivity.this, MainActivity2.class);
startActivity(actividad);
}
}
And here my other activity in which I have the linear layout and where I want to show the players of the DB.
public class MainActivity2 extends AppCompatActivity {
LinearLayout ll;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ll = (LinearLayout) findViewById(R.id.linearlayout);
}
public void changeToMain(View v) {
Intent actividad = new Intent(MainActivity2.this, MainActivity.class);
startActivity(actividad);
}
public void submitChoice(View view) {
TextView nombreJugador = findViewById(R.id.nombre);
TextView posicionJugador = findViewById(R.id.posicion);
TextView dorsalJugador = findViewById(R.id.dorsal);
TextView textView = new TextView(this);
textView.setText("text");
ll.addView(textView);
ll.invalidate();
}
}
How could I add the players I just collect from the DB to the linear layout?
First of all, sorry if my English is bad cause I'm from Spain.
I create a DB of football players (don't judge, is for school) and I want to show in the linear layout every player I add in the DB.
Here is my main activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button b1 = findViewById(R.id.insertar);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DataBaseHelper helper = new DataBaseHelper(MainActivity.this);
SQLiteDatabase db = helper.getWritableDatabase();
if (db != null) {
Toast.makeText(MainActivity.this, "Insertado con éxito.", Toast.LENGTH_LONG).show();
db.close();
}
}
});
}
public void add(View view) {
DataBaseHelper helper = new DataBaseHelper(MainActivity.this);
SQLiteDatabase db = helper.getWritableDatabase();
TextView nombreJugador = findViewById(R.id.nombre);
TextView posicionJugador = findViewById(R.id.posicion);
TextView dorsalJugador = findViewById(R.id.dorsal);
if (db != null) {
ContentValues values = new ContentValues();
values.put("nombre", nombreJugador.getText().toString());
values.put("posicion", posicionJugador.getText().toString());
values.put("dorsal", dorsalJugador.getText().toString());
db.close();
}
}
public void changeToShowDB(View v) {
Intent actividad = new Intent(MainActivity.this, MainActivity2.class);
startActivity(actividad);
}
}
And here my other activity in which I have the linear layout and where I want to show the players of the DB.
public class MainActivity2 extends AppCompatActivity {
LinearLayout ll;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ll = (LinearLayout) findViewById(R.id.linearlayout);
}
public void changeToMain(View v) {
Intent actividad = new Intent(MainActivity2.this, MainActivity.class);
startActivity(actividad);
}
public void submitChoice(View view) {
TextView nombreJugador = findViewById(R.id.nombre);
TextView posicionJugador = findViewById(R.id.posicion);
TextView dorsalJugador = findViewById(R.id.dorsal);
TextView textView = new TextView(this);
textView.setText("text");
ll.addView(textView);
ll.invalidate();
}
}
How could I add the players I just collect from the DB to the linear layout?
I am trying to change one of my textview(Status) when clicked but it just removes the current text and displays my original text's text.
The textview currently display either "Not Taken" or "Pending" depending on what data is retrieved from my db.
My pop up dialog fragment code that shows the card items in a recyclerview.
public class FragmentLocationPopup extends DialogFragment {
View mView;
TextView tvSelectedBranch;
RecyclerView mScheduleList;
ScheduleAdapter mAdapter;
RecyclerView.LayoutManager mLayoutManager;
String TAG = "DialogFragment";
ArrayList<Schedule> scheduleList;
VariablesHolder variablesHolder;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_location_popup, container, false);
createScheduleList();
buildRecyclerView();
return mView;
}
public void createScheduleList(){
scheduleList = new ArrayList<>();
tvSelectedBranch = mView.findViewById(R.id.tvSelectedBranch);
variablesHolder = (VariablesHolder) getActivity().getApplicationContext();
String selectedBranch = variablesHolder.getSelectedBranch();
tvSelectedBranch.setText(selectedBranch);
Log.d(TAG, "Selected branch = "+selectedBranch);
Call<List<Schedule>> call = RetrofitClient.getInstance().getApiDate().getSchedule();
call.enqueue(new Callback<List<Schedule>>() {
#Override
public void onResponse(Call<List<Schedule>> call, Response<List<Schedule>> response) {
List<Schedule> schedules = response.body();
for (Schedule schedule : schedules) {
if(schedule.getBranchID().equals(variablesHolder.getBranchID())) {
scheduleList.add(new Schedule(schedule.getWorkScheduleFromDateTime(), schedule.getWorkScheduleToDateTime(),schedule.getWorkScheduleStatus()));
Log.d(TAG, "onResponse: " + schedule.getWorkScheduleFromDateTime() + " and " + schedule.getWorkScheduleToDateTime() + " and "+schedule.getWorkScheduleStatus());
}
}
}
#Override
public void onFailure(Call<List<Schedule>> call, Throwable t) {
}
});
String asd = ""+variablesHolder.getBranchIdList();
Log.d(TAG, "onCreateView: "+asd);
}
public void buildRecyclerView(){
mScheduleList = mView.findViewById(R.id.rvScheduleList);
mScheduleList.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(mView.getContext());
mAdapter = new ScheduleAdapter(scheduleList);
mScheduleList.setLayoutManager(mLayoutManager);
mScheduleList.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new ScheduleAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
changeItem(position, "Clicked");
}
});
}
public void changeItem(int position, String text){
scheduleList.get(position).changeText1(text);
mAdapter.notifyItemChanged(position);
Log.d(TAG, "changeItem: "+position+" / "+text);
}
}
My schedule class (I only use 3 variables in it at the moment) workfromtime, worktotime, and workstatus
public class Schedule {
private String workScheduleID;
private Date workScheduleFromDateTime;
private Date workScheduleToDateTime;
private String workScheduleStatus;
private String workDescriptionID;
private String branchID;
private String staffID;
private String managerID;
private String workScheduleBidDateTime;
public Schedule(Date workScheduleFromDateTime, Date workScheduleToDateTime,String workScheduleStatus) {
this.workScheduleFromDateTime = workScheduleFromDateTime;
this.workScheduleToDateTime = workScheduleToDateTime;
this.workScheduleStatus = workScheduleStatus;
}
public void changeText1(String workScheduleStatus){
this.workScheduleStatus = workScheduleStatus;
}
public String getWorkScheduleID(){return workScheduleID;}
public Date getWorkScheduleFromDateTime(){return workScheduleFromDateTime;}
public Date getWorkScheduleToDateTime(){return workScheduleToDateTime;}
public String getWorkScheduleStatus(){return workScheduleStatus;}
public String getWorkDescriptionID(){return workDescriptionID;}
public String getBranchID(){return branchID;}
public String getStaffID(){return staffID;}
public String getManagerID(){return managerID;}
public String getWorkScheduleBidDateTime(){return workScheduleBidDateTime;}
}
Adapter class
public class ScheduleAdapter extends RecyclerView.Adapter<ScheduleAdapter.ScheduleViewHolder> {
private static final String TAG = "ScheduleAdapter";
private ArrayList<Schedule> mScheduleList;
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public static class ScheduleViewHolder extends RecyclerView.ViewHolder{
public TextView FromTime,ToTime,ScheduleStatus,Tester;
public ScheduleViewHolder(#NonNull final View itemView, final OnItemClickListener listener) {
super(itemView);
FromTime = itemView.findViewById(R.id.tvFromTime);
ToTime = itemView.findViewById(R.id.tvToTime);
ScheduleStatus = itemView.findViewById(R.id.tvStatus);
Tester = itemView.findViewById(R.id.tvTest);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
}
}
public ScheduleAdapter(ArrayList<Schedule> scheduleList ){
mScheduleList = scheduleList;
}
#NonNull
#Override
public ScheduleViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.schedule_item,parent,false);
ScheduleViewHolder svh = new ScheduleViewHolder(mView, mListener);
return svh;
}
#Override
public void onBindViewHolder(#NonNull ScheduleViewHolder holder, int position) {
Schedule currentSchedule = mScheduleList.get(position);
Log.d(TAG, "onBindViewHolder: "+currentSchedule.getWorkScheduleFromDateTime() + " and "+currentSchedule.getWorkScheduleToDateTime());
String FromTimeRegion = currentSchedule.getWorkScheduleFromDateTime().toString().replace("GMT 2020","");
String ToTimeRegion = currentSchedule.getWorkScheduleToDateTime().toString().replace("GMT 2020","");
String status = currentSchedule.getWorkScheduleStatus();
Log.d(TAG, "onBindViewHolder: "+status);
if(status.toLowerCase().equals("pending")) {
holder.ScheduleStatus.setText("Pending");
holder.ScheduleStatus.setTextColor(Color.parseColor("#FFFF00"));
}
if(status.toLowerCase().equals("not taken")) {
holder.ScheduleStatus.setText("Not Taken");
holder.ScheduleStatus.setTextColor(Color.parseColor("#7FFF00"));
}
holder.FromTime.setText("From: "+FromTimeRegion);
holder.ToTime.setText("To: "+ToTimeRegion);
}
#Override
public int getItemCount() {
return mScheduleList.size();
}
}
Please advice.
I found out that it is caused by this part of my code.
if(status.toLowerCase().equals("pending")) {
holder.ScheduleStatus.setText("Pending");
holder.ScheduleStatus.setTextColor(Color.parseColor("#FFFF00"));
}
if(status.toLowerCase().equals("not taken")) {
holder.ScheduleStatus.setText("Not Taken");
holder.ScheduleStatus.setTextColor(Color.parseColor("#7FFF00"));
}
holder.FromTime.setText("From: "+FromTimeRegion);
holder.ToTime.setText("To: "+ToTimeRegion);
Just had to edit which comes first.
I had created a app in which i have multiple edittext and one buttonwith recyclerviuew and one button which are setvisibilty as Gone.On Button click it add all my data in my recyclerview list with by chnaging visibality of my recycelr view and my button.In my Custom Adapter i am using a image view to delete the item from postion now i want that if it delete all data from list then it should automatically hide my Button and recyclerview.
//Recycler_view Adapter
public class Myviewholder extends RecyclerView.ViewHolder {
public TextView land_Detail, area_detail, s_no1;
public Button delete;
public Myviewholder(View view) {
super(view);
land_Detail = view.findViewById(R.id.hint31);
area_detail = view.findViewById(R.id.hint21);
s_no1 = view.findViewById(R.id.hint11);
delete = view.findViewById(R.id.hint41);
}
}
public Land_adapters(List<Land_list> land_list, Context context) {
this.laand_list = land_list;
this.context = context;
}
#NonNull
#Override
public Land_adapters.Myviewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.land_list, parent, false);
return new Myviewholder(itemView);
}
#Override
public void onBindViewHolder(#NonNull Myviewholder holder, final int position) {
final Land_list current_year = laand_list.get(position);
holder.area_detail.setText("District :" + current_year.getDistrict_name() + "\n" + "Village :" + current_year.getVillage_name());
holder.s_no1.setText(String.valueOf(position + 1));
holder.land_Detail.setText("Acre :" + current_year.getAcre() + "\n" + "Kanal :" + current_year.getKanal() + "\n" + "Marla :" + current_year.getMarla());
holder.delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "", Toast.LENGTH_SHORT).show();
Land_list theRemovedItem = laand_list.get(position);
// remove your item from data base
laand_list.remove(position); // remove the item from list
notifyItemRemoved(position); // notify the adapter about the removed item
}
});
}
#Override
public int getItemCount() {
return laand_list.size();
}
//how i am using my recycler in mainactivity class
public void final_step() {
// marla_edit.setError(null);
recyclerView = findViewById(R.id.recycler_view_last1);
mAdapter1 = new Land_Adapter(last_Year1);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(mAdapter1);
Land_list last_year1 = new Land_list(land_acre, land_kanal, village_selected1, land_marla, district_selected1, teshil_selected1, block_selected1, block_code, teshil_code1, village_code1, district_code);
last_Year1.add(last_year1);
mAdapter1.notifyDataSetChanged();
if (!(last_Year1.size() == 0)) {
RelativeLayout linearLayout = findViewById(R.id.linear123);
recyclerView.setVisibility(View.VISIBLE);
next_button.setVisibility(View.VISIBLE);
}
else
{
next_button.setVisibility(View.INVISIBLE);
}
// i just want that when it press delete image in recycelr view it should hide my button automatically.
you can use an interface to inform the fragment/activity, the list is empty.
Adapter like as below:
public class CustomAdapter extends RecyclerView.Adapter<CustomViewHolder> {
AdapterListener listener;
public void setListener(AdapterListener listener) {
this.listener = listener;
}
...
#Override
public void onBindViewHolder(#NonNull Myviewholder holder, final int position) {
...
holder.delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
...
// remove your item from data base
laand_list.remove(position); // remove the item from list
notifyItemRemoved(position); // notify the adapter about the removed item
if (laand_list.size()==0)
listener.onDataListIsEmpty();
}
});
}
public interface AdapterListener {
void onDataListIsEmpty();
}
}
The Activity/Fragment like as below:
class MyActivity extends Activity implements CustomAdapter.AdapterListener {
CustomAdapter adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
adapter = new CustomAdapter();
adapter.setListener(this);
...
}
#Override
public void onDataListIsEmpty() {
// set visible or gone views
}
}
hello everyone, I am kind of new using android studio and I am working on my school project. I need to use RecycleVie wand I tried making it but without success.
I use a Object class caled Task whcih have 3 propeties to be shown on the layout but I don't know where is my mistake. the rows which shown as problems are in bold. I will be glad if anyone can help me!
my Object class:
public class Task {
private String material;
private String day;
private String month;
public Task (String material,String day,String month)
{
this.material = material;
this.day = day;
this.month = month;
}
public String getMaterial() {
return material;
}
public void setMaterial(String material) {
this.material = material;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
}
the Adapter Code:
public class HomeRecyclerViewAdapter extends RecyclerView.Adapter<HomeRecyclerViewAdapter.ViewHolder> {
private Context mCtx;
private List<Task> tList;
// data is passed into the constructor
public HomeRecyclerViewAdapter(Context mCtx, List<Task> tList) {
this.mCtx = mCtx;
this.tList = tList;
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvText, tvDateDay, tvDateMonth;
public ViewHolder(View itemView) {
super(itemView);
tvText = itemView.findViewById(R.id.tvText);
tvDateDay = itemView.findViewById(R.id.tvDateDay);
tvDateMonth = itemView.findViewById(R.id.tvDateMonth);
}
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.home_recyclerview_row, null);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Task task = tList.get(position);
**holder.tvText.setText(task.getMaterial());**
}
// allows clicks events to be caught
#Override
public int getItemCount() {
return tList.size();
}
}
and the main code:
public class HomeScreen_activity extends AppCompatActivity implements View.OnClickListener {
List<Task> tList;
RecyclerView homercy;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.home_screen_layout);
homercy = (RecyclerView) findViewById(R.id.homercy);
homercy.setHasFixedSize(true);
homercy.setLayoutManager(new LinearLayoutManager(this));
// set up the RecyclerView
RecyclerView recyclerView = findViewById(R.id.homercy);
tList = new ArrayList<Task>();
Task t1 = new Task("test","12","05");
tList.add(t1);
**HomeRecyclerViewAdapter adapter = new HomeRecyclerViewAdapter(this,tList);**
recyclerView.setAdapter(adapter);
}
Maybe in onCreateViewHolder(), you must do this:
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_recyclerview_row, parent, false);
return new ViewHolder(view);
}
I am updating my recyclerview by using LiveData as below:
viewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
viewModel.getPurchaseList().observe(getViewLifecycleOwner(), new Observer<List<ProductsObject>>() {
#Override
public void onChanged(#Nullable List<ProductsObject> productsObjects) {
adapter.submitList(productsObjects);
//adapter.notifyDataSetChanged();
}
});
And I am using a FloatActionButton to change the value of my MutableLiveData as below:
FloatingActionButton fab = view.findViewById(R.id.cart_fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewModel.setPurchasePrice(0, 101.2);
}
});
All the data gets changed and onChanged is called as expected, but it only updates my recyclerview when I enable the adapter.notifyDataSetChanged();
If I create a new ProductsObject inside the FAB and submit a new list, the recyclerview gets updated without calling adapter.notifyDataSetChanged(); as below:
FloatingActionButton fab = view.findViewById(R.id.cart_fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//viewModel.setPurchaseAmount(0, 101.2);
ProductsObject prod = new ProductsObject("6666", 5, 152.2, "new product");
List<ProductsObject> prodList = new ArrayList<>();
prodList.add(prod);
adapter.submitList(prodList);
}
});
I appreciate if anyone could explain why.
Here is my adapter:
public class CartFragAdapter extends RecyclerView.Adapter<CartFragAdapter.CartFragViewHolder> {
private static final String TAG = "debinf PurchaseAdap";
private static final DiffUtil.ItemCallback<ProductsObject> DIFF_CALLBACK = new DiffUtil.ItemCallback<ProductsObject>() {
#Override
public boolean areItemsTheSame(#NonNull ProductsObject oldProduct, #NonNull ProductsObject newProduct) {
Log.i(TAG, "areItemsTheSame: old is "+oldProduct.getCode()+" ; new is "+newProduct.getCode());
return oldProduct.getCode().equals(newProduct.getCode());
}
#Override
public boolean areContentsTheSame(#NonNull ProductsObject oldProduct, #NonNull ProductsObject newProduct) {
Log.i(TAG, "areContentsTheSame: old is "+oldProduct.getPrice()+" ; new is "+newProduct.getPrice());
return oldProduct.getPrice() == newProduct.getPrice();
}
};
private AsyncListDiffer<ProductsObject> differ = new AsyncListDiffer<ProductsObject>(this, DIFF_CALLBACK);
#NonNull
#Override
public CartFragViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_purchase, parent, false);
return new CartFragViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CartFragViewHolder holder, int position) {
final ProductsObject purchaseList = differ.getCurrentList().get(position);
holder.mCode.setText(purchaseList.getCode());
holder.mPrice.setText(String.valueOf(purchaseList.getPrice()));
holder.mDescription.setText(purchaseList.getDescription());
}
#Override
public int getItemCount() {
Log.i(TAG, "getItemCount");
return differ.getCurrentList().size();
}
public void submitList(List<ProductsObject> products){
Log.i(TAG, "submitList: products.size is "+products.size());
differ.submitList(products);
}
public class CartFragViewHolder extends RecyclerView.ViewHolder {
public TextView mCode, mPrice, mDescription;
public CartFragViewHolder(#NonNull View itemView) {
super(itemView);
mCode = (TextView) itemView.findViewById(R.id.item_productCode);
mPrice = (TextView) itemView.findViewById(R.id.item_productPrice);
mDescription = (TextView) itemView.findViewById(R.id.item_productDescription);
}
}
}
And here is my ViewModel:
public class MyViewModel extends ViewModel {
MutableLiveData<List<ProductsObject>> purchaseList = new MutableLiveData<>();
public LiveData<List<ProductsObject>> getPurchaseList() {
return purchaseList;
}
public void setPurchasePrice(int position, double price) {
List<ProductsObject> itemList = purchaseList.getValue();
if (itemList != null && itemList.get(position) != null) {
Log.i("debinf ViewModel", "setPurchaseAmount: "+itemList.get(position).getPrice());
itemList.get(position).setPrice(price);
purchaseList.postValue(itemList);
}
}
}
AsyncListDiffer saves only the reference of the list. This means that if you submit a modified list instead of submitting a new list, AsncListDiffer won't be able to detect any difference because both the previous list and the new list are referencing the same list with the same items.
To fix this you need to create a new list and new item. Change MyViewModel#setPurchasePrice as below:
public void setPurchasePrice(int position, double price) {
List<ProductsObject> itemList = purchaseList.getValue();
if (itemList != null && itemList.get(position) != null) {
List<ProductsObject> newList = new ArrayList<>();
for (int i = 0; i < itemList.size(); i++) {
ProductsObject prevProd = itemList.get(i);
if (i != position) {
newList.add(prevProd);
} else {
ProductsObject newProd = new ProductsObject(..., price, ...);
newList.add(newProd);
}
}
purchaseList.postValue(newList);
}
}