I do have a grid view implemented with base adapter. In each view there is a click listener. When we click on that, a Custom Dialog will open. In that dialog there is a Recycler view. That is updating each 10 seconds with the help of timer. That's updating perfectly. But when the custom dialog is opened and wait for next 10 sec to update the recycler view will not update the recycler view. But when i dismiss that dialog and immediately reopened then it will show updated recycler view.
RV is not updating when Custom dialog poped up
I want to update recycler view while the custom dialog poped up.
Git: https://github.com/jishnunkrishnan/baseadaptersample
Here is the code:
MainActivity.java:
package com.aijishnu.baseadaptersample;
import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.aijishnu.baseadaptersample.databinding.ActivityMainBinding;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
int i = 0;
Context c;
ArrayList<String> alNames;
int[] arrayImages;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
c = this;
arrayImages = new int[] {
R.drawable.ic_launcher_background, R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_background, R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_background, R.drawable.ic_launcher_foreground
};
alNames = new ArrayList<>();
for (int i=0;i<5; i++) {
alNames.add("Raju: " + i);
}
updateData();
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
for (int i=0;i<5; i++) {
alNames.add("Raju Radha: " + i);
}
updateData();
Toast.makeText(c, i + " times", Toast.LENGTH_SHORT).show();
}
});
i++;
}
},15000,10000);
}
private void updateData() {
MyAdapter adapter = new MyAdapter(this, arrayImages, alNames);
binding.gvImages.setAdapter(adapter);
}
}
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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<GridView
android:id="@+id/gvImages"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:horizontalSpacing="10dp"
android:verticalSpacing="10dp"
android:numColumns="3"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
MyAdaper.java:
package com.aijishnu.baseadaptersample;
import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.aijishnu.baseadaptersample.databinding.CustomDesignBinding;
import java.util.ArrayList;
public class MyAdapter extends BaseAdapter {
Context context;
int[] arrayImages;
DataAdapter dataAdapter;
ArrayList<String> alNames;
LayoutInflater mInflater;
private boolean isDVisible = false;
MyAdapter(Context context, int[] arrayImages, ArrayList<String> alNames) {
mInflater = LayoutInflater.from(context);
this.context = context;
this.arrayImages = arrayImages;
this.alNames = alNames;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.grid_layout, null);
}
ImageView imageView = convertView.findViewById(R.id.imageView);
imageView.setImageResource(arrayImages[position]);
if (isDVisible) {
dataAdapter.notifyDataSetChanged();
}
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Dialog d = new Dialog(context);
isDVisible = true;
CustomDesignBinding binding = CustomDesignBinding.inflate(mInflater);
d.setContentView(binding.getRoot());
Window window = d.getWindow();
assert window != null;
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
binding.rvData.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL,false));
dataAdapter = new DataAdapter(alNames);
binding.rvData.setAdapter(dataAdapter);
dataAdapter.notifyDataSetChanged();
d.show();
}
});
return convertView;
}
@Override
public int getCount() {
return arrayImages.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}
DataAdapter.java
package com.aijishnu.baseadaptersample;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.aijishnu.baseadaptersample.databinding.DesignBinding;
import java.util.ArrayList;
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.Holder> {
private ArrayList<String> alNames;
public DataAdapter(ArrayList<String> names) {
this.alNames = names;
}
static class Holder extends RecyclerView.ViewHolder {
private final DesignBinding binding;
public Holder (DesignBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
@NonNull
@Override
public DataAdapter.Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new DataAdapter.Holder(DesignBinding.inflate(LayoutInflater.from(parent.getContext()), parent,false));
}
@Override
public void onBindViewHolder(@NonNull DataAdapter.Holder holder, int position) {
holder.binding.tvName.setText(alNames.get(position));
}
@Override
public int getItemCount() { return alNames.size(); }
}
grid_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
tools:srcCompat="@tools:sample/avatars" />
</LinearLayout>
design.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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
custom_desgin.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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
You should update the adapter of the dialog in the timer callback like this:
MainActivity.java
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
int counter = 0;
Context c;
ArrayList<String> alNames;
int[] arrayImages;
MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
c = this;
setupData();
setupAdapter();
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
MainActivity.this.runOnUiThread(() -> {
ArrayList<String> newItems = new ArrayList<>();
for (int i = 0; i < 5; i++) {
newItems.add("Raju Radha: " + ++counter);
}
updateData(newItems);
Toast.makeText(c, counter + " times", Toast.LENGTH_SHORT).show();
});
}
}, 15000, 10000);
}
private void setupAdapter() {
adapter = new MyAdapter(this, arrayImages, alNames);
binding.gvImages.setAdapter(adapter);
}
private void setupData() {
arrayImages = new int[]{
R.drawable.ic_launcher_background, R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_background, R.drawable.ic_launcher_foreground,
R.drawable.ic_launcher_background, R.drawable.ic_launcher_foreground
};
alNames = new ArrayList<>();
for (int i = 0; i < 5; i++) {
alNames.add("Raju: " + i);
}
}
private void updateData(ArrayList<String> newItems) {
adapter.addItem(newItems);
}
}
MyAdapter.java
public class MyAdapter extends BaseAdapter {
Context context;
int[] arrayImages;
DataAdapter dataAdapter;
ArrayList<String> alNames;
LayoutInflater mInflater;
Dialog d;
MyAdapter(Context context, int[] arrayImages, ArrayList<String> alNames) {
mInflater = LayoutInflater.from(context);
this.context = context;
this.arrayImages = arrayImages;
this.alNames = alNames;
d = new Dialog(context);
dataAdapter = new DataAdapter(alNames);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.grid_layout, null);
}
ImageView imageView = convertView.findViewById(R.id.imageView);
imageView.setImageResource(arrayImages[position]);
convertView.setOnClickListener(v -> {
CustomDesignBinding binding = CustomDesignBinding.inflate(mInflater);
d.setContentView(binding.getRoot());
Window window = d.getWindow();
assert window != null;
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
binding.rvData.setLayoutManager(new LinearLayoutManager(context,
LinearLayoutManager.VERTICAL, false));
binding.rvData.setAdapter(dataAdapter);
d.show();
});
return convertView;
}
@Override
public int getCount() {
return arrayImages.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
public void addItem(ArrayList<String> items) {
this.dataAdapter.addItems(items);
}
}
DataAdapter.java
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.Holder> {
private final ArrayList<String> alNames;
public DataAdapter(ArrayList<String> names) {
this.alNames = names;
}
public void addItems(ArrayList<String> items) {
this.alNames.addAll(items);
notifyDataSetChanged();
}
static class Holder extends RecyclerView.ViewHolder {
private final DesignBinding binding;
public Holder(DesignBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
@NonNull
@Override
public DataAdapter.Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new DataAdapter.Holder(DesignBinding.inflate(LayoutInflater.from(parent.getContext()),
parent, false));
}
@Override
public void onBindViewHolder(@NonNull DataAdapter.Holder holder, int position) {
holder.binding.tvName.setText(alNames.get(position));
}
@Override
public int getItemCount() {
return alNames.size();
}
Also, I recommend reusing your objects when possible.