Adding a new item to a RecyclerView when button is clicked? - android

I just started using RecyclerViews but i cant completely understand how to add or remove items from it. Below i will attach my adapter code it is a test code and everything in the layout works fine. I feel like im also writing too much unnecessary code so any tips or criticism is appreciated.
public class PlatesAdapter extends
RecyclerView.Adapter<PlatesAdapter.ViewHolder> {
//Declaring a List<> of Plates
private List<Plates> mPlates;
int amountOfPlates;
public static class ViewHolder extends RecyclerView.ViewHolder {
//Declaring Buttons and textViews
public TextView plateWeightTextView, amountOfPlatesTextView;
public Button addButton, subButton, addLayoutButton;
public ViewHolder(View itemView) {
super(itemView);
//initializing Buttons and TextViews
plateWeightTextView = (TextView) itemView.findViewById(R.id.plate_weight_value_textView);
amountOfPlatesTextView = (TextView) itemView.findViewById(R.id.amount_of_plates_textView);
addButton = (Button) itemView.findViewById(R.id.add_button);
subButton = (Button) itemView.findViewById(R.id.subtract_button);
addLayoutButton = (Button) itemView.findViewById(R.id.button);
}
}
//Constructor
public PlatesAdapter(List<Plates> plates) {
mPlates = plates;
}
#Override
public PlatesAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View PlatesView = inflater.inflate(R.layout.plate_item_layout, parent, false);
ViewHolder viewHolder = new ViewHolder(PlatesView);
return viewHolder;
}
#Override
public void onBindViewHolder(PlatesAdapter.ViewHolder holder, int position) {
final TextView textView2 = holder.amountOfPlatesTextView;
//BUTTONS add 1 or subtract 1 from amountOfPlates;
Button button = holder.addButton;
Button button2 = holder.subButton;
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
amountOfPlates++;
textView2.setText(Integer.toString(amountOfPlates));
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
amountOfPlates--;
textView2.setText(Integer.toString(amountOfPlates));
}
});
}
#Override
public int getItemCount() {
return mPlates.size();
}
Here is my Model Layer which i feel is completely wrong but im not 100% sure if it is.
public class Plates {
private int mPlateWeight;
private int mAmountOfPlates;
public Plates() {
//mPlateWeight = plateWeight;
//mAmountOfPlates = amountOfPlates;
}
public int getmPlateWeight() {
return mPlateWeight;
}
public int getmAmountOfPlates() {
return mAmountOfPlates;
}
public static List<Plates> createPlateList() {
List<Plates> plates = new ArrayList<>();
plates.add(new Plates());
return plates;
}
}
This is where im comfused. Its were do i call the addPlates or addItem method and what do i pass to it? Below is my main activity. I Just dont know where to add these addItems or addPlates methods is it to the Model Layer or the Adapter?
public class MainActivity extends AppCompatActivity {
private RecyclerView.LayoutManager mLayoutManager;
Button mButton;
private List<Plates> mData = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Button to add layout to recyclerView
mButton = (Button) findViewById(R.id.button);
//Adapter LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.weights_recycler_view);
PlatesAdapter adapter = new PlatesAdapter(mData);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(mLayoutManager);
}
});
}
}

What I usually do with RecyclerViews is to add a method to set the data.
In your example :
public void setPlates(List<Plates> plates) {
mPlates = plates;
notifyDataSetChanged();
}`
You can also add a getter if you want to verify if the data have changed or not.

You can add a method in your adapter to add a Plates in the arrayList and to notify the change.
Something like:
public void addPlates(Plates plate) {
if (mPlates == null) mPlates = new ArrayList();
mPlates.add(plate);
//notifyDataSetChanged();
notifyItemInserted(mPlates.size()-1)
}`

First of all the createPlateList method is not needed.
You should add a method in your adapter that looks like this:
public void addItem(Plates plate)
{
mPlates.add(plate);
}
Since your adapter works with this list, all you need to do to add or remove items, is to add/remove the items from your list. After all you need to call notifyDataSetChanged() in your adapter so it knows data was changed in your list.

Related

How can I insert element in Recycler View?

I have a problem with RecyclerView.
Every time I try to manage a Rec View for insert or delete or update some element I have to fight with Recycler View and the evil notifyDataSetChange.
I tried with runOnUiThread and everytime this solution is useless.
I tried to call notifyDataSetChange in the Adapter or in the Activity that instance the Rec View.
I really need to know how to make this work everytime to be a little better developer.
I really hope to solve this problem definitely.
This is my new try
public class MainActivity extends AppCompatActivity {
private Button nextTurn;
private Button submit;
private EditText name;
private EditText number;
private CounterElementAdapter mAdapter;
private RecyclerView recV;
private List<CounterElement> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nextTurn = (Button) findViewById(R.id.button2);
submit = (Button) findViewById(R.id.button);
name = (EditText) findViewById(R.id.editText);
number = (EditText) findViewById(R.id.editText2);
recV = (RecyclerView) findViewById(R.id.recV);
list = new ArrayList<CounterElement>();
mAdapter = new CounterElementAdapter(list);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recV.setLayoutManager(mLayoutManager);
recV.setItemAnimator(new DefaultItemAnimator());
recV.setAdapter(mAdapter);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(name.getText().toString().length() > 0 && number.getText().toString().length() > 0) {
mAdapter.addElement(new CounterElement(name.getText().toString(), Integer.parseInt(number.getText().toString())));
}
}
});
nextTurn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mAdapter.nextTurn();
}
});
}
}
public class CounterElementAdapter extends RecyclerView.Adapter<CounterElementAdapter.MyViewHolder> {
private List<CounterElement> elementList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name, counter;
public MyViewHolder(View view) {
super(view);
name = view.findViewById(R.id.name);
counter = view.findViewById(R.id.counter);
}
}
public CounterElementAdapter(List<CounterElement> elementList) {
this.elementList = elementList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.element, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
CounterElement ce = elementList.get(position);
holder.name.setText(ce.getName());
holder.counter.setText(ce.getDuration());
}
#Override
public int getItemCount() {
return elementList.size();
}
public void addElement(CounterElement ce){
elementList.add(ce);
notifyDataSetChanged();
}
public void nextTurn(){
for(CounterElement ce : elementList){
if(ce.getStatus() >= 1)
ce.setStatus(ce.getStatus() - 1);
else {
elementList.remove(elementList.indexOf(ce));
notifyDataSetChanged();
}
}
}
}
Thanks in advance
Your code looks fine. I would recommend you to take a look at this article
Also try to debug your code and check if your elementList updates correctly.
Looked at your code for a while, didn't seem to find anything wrong, Are you using an android emulator for testing or a physical device? Sometimes emulators tend to be buggy.
Try initializing your array list with a few dummy values at first and then try to add or remove and see if that helps

ListView using CardView + RecyclerView is not working

I am new to android ,Here i trying to bind ListView by using RecyclerView and Cardview .In my case I didn't get any errors but I could not get the ListView items.
This is my adapter class
RecyclerviewAdapter_list.java
public class RecyclerviewAdapter_list extends RecyclerView.Adapter<RecyclerviewAdapter_list.MyViewHolder> {
private Context mContext;
private List<myAlarms> myAlarmsdata;
public RecyclerviewAdapter_list(Context mContext, List<myAlarms>myAlarms){
this.mContext = mContext;
this.myAlarmsdata =myAlarms;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.cardview_alarm, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
myAlarms myAlarms =myAlarmsdata.get(position);
holder.mTime.setText(myAlarmsdata.get(position).getALARM_TIME());
holder.mTitle.setText(myAlarmsdata.get(position).getALARM_TITLE());
}
#Override
public int getItemCount() {
return myAlarmsdata.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView mTime,mTitle,mAmPm;
SwitchButton mbtn;
public MyViewHolder(View itemView) {
super(itemView);
mTime = (TextView) itemView.findViewById(R.id.mTime);
// mAmPm = (TextView) itemView.findViewById(R.id.mAmPm);
mTitle = (TextView) itemView.findViewById(R.id.mTitle);
// mbtn = (SwitchButton) itemView.findViewById(R.id.mTime);
}
}
}
AlarmActivity.java
public class AlarmActivity extends Activity {
private ImageView mAddIcon;
List<myAlarms>myAlarms;
RecyclerView recyclerView;
Database_Helper database_helper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm);
Utils.darkenStatusBar(this, R.color.StatusbarColor);
database_helper = new Database_Helper(this);
mAddIcon = (ImageView) findViewById(R.id.mAddIcon);
myAlarms = new ArrayList<>();
recyclerView=(RecyclerView)findViewById(R.id.mRecyclerView_id);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
RecyclerviewAdapter_list recyclerviewAdapter_list =new RecyclerviewAdapter_list(this,myAlarms);
recyclerView.setAdapter(recyclerviewAdapter_list);
mAddIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
List<myAlarms> myAlarms = database_helper.getMyAlarms();
Intent intent = new Intent(AlarmActivity.this, CreateAlarm.class);
startActivity(intent);
overridePendingTransition(R.anim.slide_up, R.anim.slide_out);
}
});
}
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
}
Can anyone tell me where I need to do the changes and where I did the mistakes .
Thanks.
You put this code in your project
//when you want horizontal
layoutManager.setOrientation(context,LinearLayoutManager.HORIZONTAL,false);
//when you want vertical
layoutManager.setOrientation(context,LinearLayoutManager.VERTICAL,false);
I add the same problem before, a solution is to remove your CardView and just add this line to a Layout:
android:background="#android:drawable/dialog_holo_light_frame"
This drawable has exactly the same design than a CardView. Besides, you don't need any implementation to use it so you can remove your CardView implementation from Gradle.
You can also check this : How to use RecyclerView and CardView

Getting Android RecyclerView to update view inside React Native component

I am making a mobile application using React Native and included list components didn't have high enough performance for it so I started using Android's RecyclerView as the list component. There is a problem though with it. The RecyclerView doesn't update its contents views until I scroll or change RecyclerView's size. What could cause this problem and how I can fix it? I have tried notifyDatasetChanged, notifyItemChanged, forceLayout, invalidate, postInvalidate and many different variations with each.
Try this one this.setIsRecyclable(true);
It will referesh your views
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ArrayList<String> mSingleItemLists = new ArrayList<>();
private SingleListItemAdapter mSingleListItemAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view_single_item);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(linearLayoutManager);
setDummyData();
}
private void setDummyData() {
for (int i = 0; i <= 30; i++)
mSingleItemLists.add("item" + i);
}
#Override
protected void onResume() {
super.onResume();
mSingleListItemAdapter = new SingleListItemAdapter(mSingleItemLists);
mRecyclerView.setAdapter(mSingleListItemAdapter);
}
class SingleListItemAdapter extends RecyclerView.Adapter<SingleListItemAdapter.SingleListItemHolder> {
private ArrayList<String> mSingleItemLists;
private SingleListItemAdapter(ArrayList<String> singleItemLists) {
mSingleItemLists = singleItemLists;
//You can do notifydatasetchange if u r having any saved value
}
#Override
public SingleListItemAdapter.SingleListItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View inflatedView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_recyclerview, parent, false);
return new SingleListItemHolder(inflatedView);
}
#Override
public void onBindViewHolder(SingleListItemAdapter.SingleListItemHolder holder, int position) {
holder.mItemDate.setText(mSingleItemLists.get(position));
}
#Override
public int getItemCount() {
return mSingleItemLists.size();
}
class SingleListItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView mItemDate;
SingleListItemHolder(View v) {
super(v);
mItemDate = (TextView) v.findViewById(R.id.textview_recycler_list_item);
v.setOnClickListener(this);
this.setIsRecyclable(true); // This will help u
}
#Override
public void onClick(View v) {
//do your stuff
notifyDataSetChanged();
}
}
}
}

How to add user data to my Recyclerview through onClick?

I'm trying to build a simple To Do List app using a RecyclerView with a custom Adapter. I've build a model data class to get and set my todos. My problem is that each time I click the button to add my item, nothing happens. I did call notifyDataSetChanged() method but it still doesn't work.
This is a practice app that I'm building to learn RecyclerViews and custom adapters so I'd appreciate it if someone could explain why it doesn't work and perhaps explain to me how I can fix it.
This is my code where I'm retrieving the user input from the EditText field and placing it in my data:
public class MainActivity extends AppCompatActivity {
private ToDoData toDoData;
private List<ToDoData> toDoList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ToDoAdapter toDoAdapter = new ToDoAdapter(toDoList, this);
toDoData = new ToDoData(this);
final EditText toDoInput = (EditText)findViewById(R.id.add_todo);
Button toDoAdd = (Button)findViewById(R.id.add_item);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
RecyclerView toDoDisplay = (RecyclerView) findViewById(R.id.toDoDisplayRecyclerView);
toDoDisplay.setAdapter(toDoAdapter);
toDoDisplay.setHasFixedSize(true);
toDoDisplay.setLayoutManager(layoutManager);
toDoAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toDoData.setToDo(toDoInput.getText().toString());
toDoAdapter.notifyDataSetChanged();
}
});
}
}
This is my model class with getters and setters. The list-item has only 1 field so its rather small:
public class ToDoData {
private String toDoString;
public ToDoData(String todoString){
this.toDoString = todoString;
}
public ToDoData(Context context){}
public String getToDo() {
return toDoString;
}
public void setToDo(String toDoString) {
this.toDoString = toDoString;
}
}
And this is my custom adapter. I followed through a tutorial while building this but I do however think that my problem stems from the adapter:
public class ToDoAdapter extends RecyclerView.Adapter<ToDoAdapter.ViewHolder> {
private List<ToDoData> toDoList;
private Context context;
public ToDoAdapter(List<ToDoData> todoList, Context context) {
this.toDoList = todoList;
this.context = context;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView todoView;
public ViewHolder(View itemView) {
super(itemView);
todoView = (TextView) itemView.findViewById(R.id.to_do_display);
}
}
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.to_do_list_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
ToDoData todo = toDoList.get(position);
holder.todoView.setText(todo.getToDo());
}
#Override
public int getItemCount() {
return (toDoList == null) ? 0 : toDoList.size();
}
}
Add one setter method in your adapter class for setting the collection and then invoke notifyDataSetChanged.
Declare the ToDoAdapter as class member and then invoke the setter function on Button click as follows,
adapter.setTodoList(/* pass collection */);
adapter.notifyDataSetchanged();

Dynamically inflating the RecyclerView listItem with EditText string

I'm trying to learn how to use RecyclerViews and the best way to learn is by doing :) so I'm trying to transition from using a ListView in a simple to do list to a Recyclerview. I'm trying to get the String value from the EditText and add that value to my RecyclerView list when the button is clicked. The following are my implementations.
This is my custom adapter. I'm using a ViewHolder to use a basic, single TextView custom list-item.
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder>{
private List<todo> todoList;
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView toDoTextView;
public ViewHolder(View itemView) {
super(itemView);
toDoTextView = (TextView)itemView.findViewById(R.id.to_do);
}
}
public ItemAdapter(List<todo> todoList){
this.todoList = todoList;
}
#Override
public ItemAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ItemAdapter.ViewHolder holder, int position) {
todo toDo = todoList.get(position);
holder.toDoTextView.setText(toDo.getToDo());
}
#Override
public int getItemCount() {
return todoList.size();
}
}
And this is my MainActivity. This is where I'm going to be adding my EditText values to my RecyclerView List. The implementation is done in the setOnClickListener but it gives me an error.
public class MainActivity extends AppCompatActivity {
private List<todo> items = new ArrayList<>();
private ItemAdapter itemAdapter;
private RecyclerView listItemsRecyclerView;
EditText itemsInput;
Button addingItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
itemsInput = (EditText)findViewById(R.id.to_do_editText);
addingItems = (Button)findViewById(R.id.to_do_btn);
listItemsRecyclerView = (RecyclerView) findViewById(R.id.to_do_list);
final String todoItem = String.valueOf(itemsInput.getText());
itemAdapter = new ItemAdapter(items);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
listItemsRecyclerView.setLayoutManager(layoutManager);
listItemsRecyclerView.setItemAnimator(new DefaultItemAnimator());
listItemsRecyclerView.setAdapter(itemAdapter);
addingItems.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(todoItem != null){
items.add(todoItem);
itemsInput.setText("");
}else {
Toast.makeText(MainActivity.this, "Please enter something to do", Toast.LENGTH_SHORT).show();
}
itemAdapter.notifyDataSetChanged();
}
});
This is my todo class:
public class todo {
private String toDo;
public todo(){}
public todo(String somethingToDo){
somethingToDo = toDo;
}
public String getToDo() {
return toDo;
}
public void setToDo(String toDo) {
this.toDo = toDo;
}
}
Modify your code inside if condition inside button OnClickListener
if(todoItem != null){
todo mTodo = new todo(todoItem); //Create object of todo using the input done by user.
items.add(mTodo);
itemsInput.setText("");
}
Also your todo class constructor code is wrong
public todo(String somethingToDo){
//somethingToDo = toDo;
toDo = somethingToDo; //need to assign the value received as signature to the class variable.
}

Categories

Resources