I am trying to add data in Recycler View
but my data extracted from Edit Text
is not getting inserted instantly. Data is getting inserted only after I do some other operation like removing a list.
I have attached all of my codes in here .
I think notifyDataSetChanged
is not getting called when i try to add a new text from edit text.
Code:
MainActivity.java
package com.example.sqlitedatabase;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
Adapter adapter;
RecyclerView recyclerView;
TextView textView;
ImageView addTodo;
ConstraintLayout constraintLayout;
ConstraintLayout editTextContainer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<ListModel> list = new ArrayList<>();
editTextContainer = findViewById(R.id.constraintParentOfAddTodo);
textView = findViewById(R.id.textView);
addTodo = findViewById(R.id.addTodo);
addData(list);
addTodo_onClickListener(list);
adapter = new Adapter(this);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter.setList(list);
}
private void addTodo_onClickListener(ArrayList<ListModel> list) {
addTodo.setOnClickListener(v -> {
addTodo.setVisibility(View.GONE);
View view = getLayoutInflater().inflate(R.layout.after_add_clicked, null, false);
//Used for USERS input
EditText editText = (EditText) view.findViewById(R.id.editTextTodo);
//This ImageView is used as a button to set data in list
ImageView setTodo = (ImageView) view.findViewById(R.id.sendTodo);
Animation animAddTodo = AnimationUtils.loadAnimation(MainActivity.this, R.anim.righttoleft);
view.setAnimation(animAddTodo);
editTextContainer.addView(view);
setTodo_onClickListener(editText, setTodo, list, view);
});
}
private void setTodo_onClickListener(EditText editText, ImageView setTodo, ArrayList<ListModel> list, View view) {
setTodo.setOnClickListener(v -> {
String txt = editText.getText().toString();
addToList(list, txt);
view.setVisibility(View.GONE);
addTodo.setVisibility(View.VISIBLE);
}
);
}
//this function is Supposed to add new data to To do list
private void addToList(ArrayList<ListModel> list, String text) {
//no work is done on id
list.add(new ListModel(1, text, true));
}
//for displaying list initially
//this data gets inserted instantly
//No problem with them.
private void addData(ArrayList<ListModel> list) {
list.add(new ListModel(1, "1", false));
list.add(new ListModel(2, "2", false));
list.add(new ListModel(3, "3", false));
list.add(new ListModel(4, "4", false));
list.add(new ListModel(5, "5", false));
list.add(new ListModel(6, "6", false));
list.add(new ListModel(7, "7", false));
list.add(new ListModel(8, "8", false));
list.add(new ListModel(9, "9", false));
list.add(new ListModel(10, "10", false));
}
Adapter.java
package com.example.sqlitedatabase;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
private final Context context;
private ArrayList<ListModel> list = new ArrayList<>();
public Adapter(Context context) {
this.context = context;
}
@NonNull
@Override
public Adapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_template, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull Adapter.ViewHolder holder, int position) {
holder.todoText.setText(list.get(position).getText());
holder.notDoneBtn.setOnClickListener(v -> {
if (list.size() != 0) {
list.remove(list.get(position));
notifyDataSetChanged();
}
}
);
}
@Override
public int getItemCount() {
return list.size();
}
public void setList(ArrayList<ListModel> list) {
this.list = list;
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView todoText;
private final ImageView doneBtn;
private final ImageView notDoneBtn;
private final RelativeLayout listBlock;
public ViewHolder(@NonNull View itemView) {
super(itemView);
listBlock=itemView.findViewById(R.id.listBlock);
todoText = itemView.findViewById(R.id.todoText);
doneBtn = itemView.findViewById(R.id.doneBtn);
notDoneBtn = itemView.findViewById(R.id.notDoneBtn);
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@ id/constraintLayout"
android:layout_width="match_parent"
android:background="@color/white"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@ id/textView"
android:layout_width="200dp"
android:layout_height="120dp"
android:layout_marginTop="4dp"
android:fontFamily="sans-serif-condensed"
android:gravity="center"
android:text="TO-DO LIST"
android:textSize="28sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.502"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</TextView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@ id/constraintLayout3"
android:layout_width="300dp"
android:layout_height="480dp"
android:layout_marginTop="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/textView"
app:layout_constraintVertical_bias="0.0">
<ScrollView
android:layout_width="300dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.50">
<androidx.recyclerview.widget.RecyclerView
android:id="@ id/recyclerView"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="12dp">
</androidx.recyclerview.widget.RecyclerView>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@ id/constraintParentOfAddTodo"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginBottom="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/constraintLayout3"
app:layout_constraintVertical_bias="0.794">
<ImageView
android:id="@ id/addTodo"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginVertical="0dp"
android:backgroundTint="@color/white"
android:elevation="10dp"
android:src="@drawable/add_circle_48px"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.956"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</ImageView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
list_template.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="42dp"
android:id="@ id/listBlock"
android:layout_width="280dp"
android:layout_gravity="center_horizontal">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="2dp"
android:layout_marginStart="1dp"
android:elevation="200dp"
app:cardBackgroundColor="#932"
app:cardCornerRadius="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@ id/todoText"
android:layout_width="190dp"
android:layout_height="40dp"
android:layout_marginStart="10dp"
android:fontFamily="monospace"
android:gravity="center_vertical"
android:maxHeight="40dp"
android:padding="5dp"
android:text="Reading books"
android:textColor="#EFEBE9"
android:textSize="14sp"
android:textStyle="bold">
</TextView>
<ImageView
android:id="@ id/notDoneBtn"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignBottom="@id/todoText"
android:padding="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:layout_toEndOf="@ id/todoText"
android:background="#999999"
android:src="@drawable/close_20px">
</ImageView>
<ImageView
android:id="@ id/doneBtn"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="4dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="4dp"
android:layout_toEndOf="@ id/notDoneBtn"
android:background="#999999"
android:padding="5dp"
android:src="@drawable/done_20px">
</ImageView>
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
after_add_clicked.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginBottom="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent">
<com.google.android.material.card.MaterialCardView
android:id="@ id/materialCardView"
android:layout_width="310dp"
android:layout_height="match_parent"
android:layout_marginStart="50dp"
android:background="#121212"
android:backgroundTint="@color/white"
app:cardCornerRadius="30dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:strokeColor="#888"
app:strokeWidth="2dp">
<EditText
android:id="@ id/editTextTodo"
android:layout_width="300dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="@color/white"
android:fontFamily="monospace"
android:gravity="center_vertical"
android:text="What to do"
android:inputType="text"
android:textSize="20sp">
</EditText>
</com.google.android.material.card.MaterialCardView>
<ImageView
android:id="@ id/sendTodo"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
android:src="@drawable/ic_baseline_send_24"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.529"
app:layout_constraintStart_toEndOf="@ id/materialCardView"
app:layout_constraintTop_toTopOf="parent">
</ImageView>
<ImageView
android:id="@ id/cancel"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_margin="4dp"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
android:src="@drawable/close_20px"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@ id/materialCardView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</ImageView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
CodePudding user response:
If you're calling addToList
to add your data, all that does is insert a new item into the list that your Activity and Adapter are sharing - the adapter has no idea anything's changed, so it won't update the display
You should be calling your setList
function on the adapter instead - that replaces the current list with the new one (doesn't matter if it's actually the same list) and then calls notifyDataSetChanged()
to display the "new" list.
It's always better to have a function like that on your adapter - when you have new data, you just pass it to the adapter, and it can handle the details of updating itself internally. The thing passing the data doesn't need to know anything about it. And if you want to update the way the adapter works later (say to be more specific about updating certain items, or to use a DiffUtil
) then that's still an internal detail - the thing passing the data in just needs to pass the data in as usual.
(You should make setList
make a copy of the list passed in though, like with list.toList()
- if something modifies that original list, you don't want the adapter's internal list to change, that can lead to bugs. It's fine here, but if you used a DiffUtil
for example, your oldList
would also be your newList
, and no differences means no update)