0
votes

How can I refresh internal data in a RecyclerView that is bound to a public static variable? I've created this Adapter class, and defined all (I think) that I need to create a list of object displayed via a RecyclerView. Now as you can see in the constructor, there is an internal ArrayList that is built by fetching the data from a public static ArrayList elsewhere.

public class MyListAdapter extends RecyclerView.Adapter<MyListAdapter.ViewHolder> {

private ArrayList<StatusBarNotification> myList;
Context ctx;

public class ViewHolder extends RecyclerView.ViewHolder {
    public ImageView appSmallIcon;

    public ViewHolder(View v) {
        super(v);
        appSmallIcon = // ..
     // ....
    }
}

public void add(int position, StatusBarNotification item) {
    myList.add(position, item);
    notifyItemInserted(position);
}

public void remove(StatusBarNotification item) {
    int position = myList.indexOf(item);
    myList.remove(position);
    notifyItemRemoved(position);
}

public MyListAdapter(Context context) {
    if (MyService.allMyData != null)
        myList = new ArrayList<>(MyService.allMyData);
    else
        myList = new ArrayList<>();
    ctx = context;
}

@Override
public MyListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = //... 
    ViewHolder vh = new ViewHolder(v);
    return vh;
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    // ....
}

@Override
public int getItemCount() {
    return myList.size();
}

}

After the RecyclerView is created, and the app is running, what should I do to notify that the external myAllData ArrayList has changed, or an item added or removed? I tried to invoke notifyDataSetChanged() but nothing happens. The weird thing (at my eyes, of course) is that I don't have access to methods like add(), remove().

Supposing that notifyDataSetChanged() is the correct road to follow, where should I put a listener inside the adapter to actually update the internal data and ask the RecyclerView to refresh the screen? Should I use Intents instead to communicate with my adapter?

And also, why Java prevents me to do something like this:

MyListAdapter myLA = new MyListAdapter(....);
myLA.remove(item);    // <-- why the public method remove() is not available?!?

I don't understand the syntax and semantics that prevent me from accessing the public methods, as if they were private.

3
Can some one explain the reason for the downvotes?Beppi's

3 Answers

3
votes

You can use notifyDataSetChanged, if you encounter rendering problems try requestLayout and forceLayout.

1
votes

It seems that my problem was that I supposed that I needed to keep an internal private variable, synchronized with the real external data to be shown. I was wrong: the Adapter must be directly linked to the data that must be shown, through a reference. The private copy is just a private reference to the public data, so copying the addressed data in the constructor is wrong. At that point, if the constructor of the Adapter is fed with the reference to some data object, it can be notified at every change with notifyDataSetChanged() .

0
votes

Try This

public MyListAdapter(Context context) {
if (MyService.allMyData != null)
{
   // myList = new ArrayList<>(MyService.allMyData); // This type of initialization don't allow mofification in list. or you can do this 

      myList = new ArrayList<>(Arrays.asList(MyService.allMyData));
      // or 
      myList = new ArrayList<>();
      myList.addAll(MyService.allMyData);
 }
  else
    myList = new ArrayList<>();
    ctx = context;
}