I am creating a time table app. The app has a RecyclerView
and each row of it has a CardView
, called row
. Each row
has 1 TextView
and 2 EditText
. I want to get the values from the EditText
s and update it in an ArrayList of row
, called rows
that is in TimeTable
class.
I want to update values in the array list entered in the EditText
s by using addTextChangedListener
. But, I am confused in which class I should implement the method. I have to choose between TimeTable
class and the TimeTableAdapter
class. In case of TimeTable
class, I was thinking of putting this method in else
condition in my addBtn.setOnClickListener()
. In case of TimeTableAdapter
I was thinking of adding it in the onBindViewHolder
method. I am confused where to put it.
Here is the TimeTable
class -
package com.example.timetable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class TimeTable extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
Button addBtn;
TextView day;
TextView date;
ArrayList<row> rows = new ArrayList<>();
private int indexOfEachRow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.time_table);
setupAppElements();
createRecyclerView();
rows.add(new row());
indexOfEachRow = rows.get(rows.size() - 1).getIndex();
//for testing purpose only, will be deleted in the future
rows.get(rows.size() - 1).setTasksName("sdf");
rows.get(rows.size() - 1).setHours(120);
addBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//check whether the last row is empty or not
if(rows.get(rows.size()-1).getTasksName().matches("") || rows.get(rows.size()-1).getHours() == 0) {
Toast.makeText(TimeTable.this, "Fill out previous row's content", Toast.LENGTH_SHORT).show();
}
else {
addEmptyRow();
mAdapter.notifyItemInserted(rows.size());
}
}
});
}
public void createRecyclerView(){
recyclerView = (RecyclerView) findViewById(R.id.list);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
mAdapter = new TimeTableAdapter(rows, TimeTable.this);
recyclerView.setAdapter(mAdapter);
}
public void addEmptyRow(){
rows.add(new row());
rows.get(rows.size() - 1).setIndex(indexOfEachRow + 1);
rows.get(rows.size() - 1).setTasksName("");
}
public void setupAppElements(){
addBtn = findViewById(R.id.add);
day = findViewById(R.id.day);
date = findViewById(R.id.date);
}
}
Here is TimeTableAdapter
-
package com.example.timetable;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class TimeTableAdapter extends RecyclerView.Adapter<TimeTableAdapter.rowVH> {
ArrayList<row> rows;
Context context;
public TimeTableAdapter(ArrayList<row> oneCell, Context context){
rows = oneCell;
this.context = context;
}
public class rowVH extends RecyclerView.ViewHolder{
public TextView index;
public EditText tasksName;
public EditText totalHours;
public rowVH(@NonNull View itemView) {
super(itemView);
index = itemView.findViewById(R.id.index);
tasksName = itemView.findViewById(R.id.taskName);
tasksName.setText("");
totalHours = itemView.findViewById(R.id.totalHours);
totalHours.setText("");
}
}
@NonNull
/**
* RecyclerView calls this method whenever it needs to create a new ViewHolder.
* The method creates and initializes the ViewHolder and its associated View, but
* does not fill in the view's contents—the ViewHolder has not yet been bound to
* specific data.
*/
@Override
public rowVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.each_row, parent, false);
rowVH rVH = new rowVH(v);
return rVH;
}
/**
* RecyclerView calls this method to associate a ViewHolder with data. The method fetches
* the appropriate data and uses the data to fill in the view holder's layout. For example,
* if the RecyclerView displays a list of names, the method might find the appropriate name
* in the list and fill in the view holder's TextView widget.
*/
@Override
public void onBindViewHolder(@NonNull rowVH holder, int position) {
holder.index.setText(String.valueOf(rows.get(position).getIndex()));
holder.tasksName.setText(String.valueOf(rows.get(position).getTasksName()));
holder.totalHours.setText(String.valueOf(rows.get(position).getHours()));
}
/**
* RecyclerView calls this method to get the size of the data set. For example, in an address book
* app, this might be the total number of addresses. RecyclerView uses this to determine when there
* are no more items that can be displayed.
*/
@Override
public int getItemCount() {
return rows.size();
}
}
Place the text change listener in view holder (rowVH funtion in this case) where you are setting text for the views. Here you can use some kind of Interface if you want to send a callback to the activity/fragment containing this recyclerview.