Search code examples
androidcustom-adapternotifydatasetchanged

Pass customadapter from itself to method


I got a customAdapter that extends the BaseAdapter. Inside this customAdapter I call a method from another class which needs exactly this customAdapter as an argument. So basically I want to achieve this:

public class customAdapter extends BaseAdapter {

    public View getView(final int i, View view, ViewGroup viewGroup) {

        className.someMethod(arg1, arg2, this customAdapter);

    }

}

The reason behind this is, that inside the method the array which contains the data for this customAdapter is updated and after the update I want to call

notifiyDataSetChanged();

on the adpater.

I also tried to return the array in the said method and then call notifiyDataSetChanged(); inside the customAdapter class but the array was kinda messed up.

In this activity is the listView I want to populate with data:

public class activity_1_5_friendslist extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

    @Override protected void onCreate(Bundle savedInstanceState) {

       customFriendsListAdapter= new customAdapter_CustomFriendsListAdapter(activity_1_5_friendslist.this,friendsList);
       friendsListListView = findViewById(R.id.friendsListListView);
       friendsListListView.setAdapter(customFriendsListAdapter);

       // API-Call to get data
       API.getFriends(activity_1_5_friendslist.this, preFriendsList, friendsList, friendsListProgressBar, friendsListTextView, customFriendsListAdapter);

   }
}

in each row in the listView there are buttons, e.g. "declineFriends". In my customAdapter I got the following:

public class customAdapter_CustomFriendsListAdapter extends BaseAdapter {

     customAdapter_CustomFriendsListAdapter adapter;

     public customAdapter_CustomFriendsListAdapter(Context c, ArrayList<Object> friendsList){

     this.friendsList=friendsList;
     friendsListInflater= (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     context=c;

     }

    @Override public View getView(final int i, View view, ViewGroup viewGroup) {

        holder.declineFriendImageButton.setOnClickListener(new View.OnClickListener() {

        @Override public void onClick(View view) {

            // make call that friend reqeust was declined, delete friendObject from arrayList and refresh adapter
            API.declineFriend(context, pubKey, friendsList, i, adapter);

        }
    }
}

this is the declineFriend-method:

public void declineFriend(Context context, String pubKey, final ArrayList<Object> friendsList, final int i, final customAdapter_CustomFriendsListAdapter adapter){

    requestQueue= Volley.newRequestQueue(context);

    String userID = getUserId();

    url = "someURL";

    Log.d(TAG, "declineFriend: "+i);

    StringRequest dr = new StringRequest(Request.Method.DELETE, url,
            new Response.Listener<String>()
            {
                @Override
                public void onResponse(String response) {

                    friendsList.remove(i);
                    adapter.notifyDataSetChanged();
                }
            },
            new Response.ErrorListener()
            {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // error.

                }
            }
    );
    requestQueue.add(dr);
}

Using this this instead of the adapter in the method in the adapter doesnt work, since Im in this onClickListener and this gives me the listener instead of the adapter.


Solution

  • which needs exactly this customAdapter as an argument.

    Using this this instead of the adapter in the method in the adapter doesnt work, since Im in this onClickListener and this gives me the listener instead of the adapter

    You just pass this. More specifically CustomAdapter.this

    Or remove the parameter there, and pass it to className's constructor.


    However, if you want to do something like this, you should use a callback interface instead of coupling your adapter to the external class.

    Most Android operations are already using callbacks, even if you don't realize it. Buttons clicking and Volley responses are just two examples you're already using.

    To make your own, you would define an interface that accepts back the deleted ID as an argument. Then when you call the external method, it notifies the adapter to remove that element. The adapter then knows it needs to update itself.

    public class CustomAdapter<E> extends ArrayAdapter<E> {
    
        public static class OnUpdateListener {
           void onRemove(String id);
        }
    
        public View getView(final int i, View view, ViewGroup viewGroup) {
    
            className.someMethod(arg1, arg2, new CustomAdapter.OnUpdateListener() {
                @Override public void onRemove(String id) {
                    remove(id);
                }
            });
    
        }
    
    }
    

    And in the other class

    void someMethod(Object arg1, Object arg2, final CustomAdapter.OnUpdateListener callback) {
        // Do some things
        // Get some data
        String userID = getUserId();
        // notify back to the adapter
        callback.onRemove(userID);
    }