How to call a MainActivity method from ViewHolder in RecyclerView.Adapter?

前端 未结 5 1176
眼角桃花
眼角桃花 2020-12-09 05:45

In a simple app project at GitHub I have only 2 custom Java-files:

  1. MainActivity.java contains Bluetooth- and UI-related source code
  2. DeviceListAdapter.
5条回答
  •  南笙
    南笙 (楼主)
    2020-12-09 06:05

    For those who are looking for invoking a callback from a static ViewHolder do the following. Let you have an adapter:

    public class MyAdapter extends RecyclerView.Adapter {
        private final int resource;
        private final List items;
        private final LayoutInflater inflater;
        ...
        private Callback callback;
    
        private static class ViewHolder extends RecyclerView.ViewHolder {
            ...
        }
    
        public interface Callback {
            void onImageClick(int position);
            void onRemoveItem(int position);
        }
    }
    

    Then you should add a setCallback method and call it from activity/fragment. Also you shouldn't make a callback static (it may lead to problems when you use the same adapter in many classes). You should create a field inside the ViewHolder. So:

        public MyAdapter(Context context, int resource, List items, Callback callback) {
            super();
            this.resource = resource;
            this.items = items;
            this.inflater = LayoutInflater.from(context);
            this.callback = callback;
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            final ViewHolder viewHolder = (ViewHolder) holder;
            final Item item = this.items.get(position);
            viewHolder.caption.setText(item.caption);
            viewHolder.callback = callback;
        }
    
        // A method to set a callback from activity/fragment.
        public void setCallback(Callback callback) {
            this.callback = callback;
        }
    
        public static class Item {
            public long id;
            public String number;
            public String caption;
    
            ...
        }
    
        private static class ViewHolder extends RecyclerView.ViewHolder {
            protected final TextView caption;
            // A reference to an adapter's callback.
            protected Callback callback;
    
            public ViewHolder(View view) {
                super(view);
                this.caption = (TextView) view.findViewById(R.id.caption);
            }
    
            private View.OnClickListener onClickListener = new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int id = v.getId();
                    if (id == R.id.image) {
                        // Invoke the callback here.
                        if (callback != null) {
                            callback.onImageClick(getLayoutPosition());
                        }
                    }
                }
            };
        }
    }
    

    After you have made the adapter you can invoke it so:

    adapter = new MyAdapter(getActivity(), R.layout.item,
            new ArrayList(), null);
    
    adapterListener = new MyAdapter.Callback() {
        @Override
        public void onImageClick(int position) {
            // Some actions.
        }
    
        @Override
        public void onRemoveItem(int position) {
            // Some actions.
        }
    };
    
    adapter.setCallback(adapterListener);
    

提交回复
热议问题