adapter calls methods in fragment s

Keywords: Fragment network React Database

adapter calls methods in fragment s

Foreword: Yesterday, I met a technical problem. For me, ha. My demo requirement is to put a RecyclerView in fragment, and then RecyclerView displays some simple data, which needs to request the network. Then I customized an adapter and found that when dealing with click events of RecyclerView subitems, because adapter is not an internal class of fragment, fragme cannot be accessed directly. The attributes and methods of nt, but I have to notify fragment to call fragment to call some of its own methods, such as opening progress bar dialogs or closing them.

Okay, let's start to solve this problem:

After checking it on the internet, no corresponding solution has been found. The gods say there are two ways:

  • Interface callback
  • Radio broadcast

I use local broadcasting to achieve the above problems. The specific implementation is as follows:

  1. First, create a new adapter inherited from RecyclerView.Adapter, the specific code is as follows:

    public class ProvinceCityAdapter extends
            RecyclerView.Adapter<ProvinceCityAdapter.ViewHolder> {
    
        private static final String TAG = "ProvinceCityAdapter";
    
    
        private List<String> mDataList = new ArrayList<>();   //data
    
        private LocalBroadcastManager localBroadcastManager;
    
        //Used for caching data
        static class ViewHolder extends RecyclerView.ViewHolder {
    
            TextView textView;
    
            //Construction method
            public ViewHolder(View itemView) {
                super(itemView);
                textView = (TextView) itemView.findViewById(R.id.tv_prcico);
            }
        }
    
        public ProvinceCityAdapter(List<String> mDataList) {
            this.mDataList = mDataList;
        }
    
        //Create a ViewHolder instance
        @Override
        public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
            final View view = LayoutInflater.from(parent.getContext()).
                    inflate(R.layout.item_prcico_layout, parent, false);
            final ViewHolder viewHolder = new ViewHolder(view);
            localBroadcastManager = LocalBroadcastManager.getInstance(parent.getContext());
            final Intent intent = new Intent(ChooseAreaFragment.LOCAL_BROADCAST);
            viewHolder.textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int adapterPosition = viewHolder.getAdapterPosition();  //An index of clicks is available
                    intent.putExtra("query_city", true);   //Notify fragment to call the queryCity() method
                    localBroadcastManager.sendBroadcast(intent);   //Send local broadcast notification fragment to refresh
                }
            });
            return viewHolder;
        }
    
        //Subitem data assignment is performed when scrolled to the screen
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            String position_choice = mDataList.get(position);
            holder.textView.setText(position_choice);
        }
    
        //How many subitems are there?
        @Override
        public int getItemCount() {
            return mDataList.size();
        }
    
    }
    
  2. Then write a fragment code that needs to register local broadcasts. When receiving the broadcast sent by adapter, it needs to react. The specific implementation is as follows:

        public class ChooseAreaFragment extends Fragment {
    
            private static final String TAG = "ChooseAreaFragment";
    
    
            private RecyclerView recyclerView;  //list
            private ProvinceCityAdapter adapter;  //Adapter
            private List<String> dataList = new ArrayList<>();   //data
    
    
    
            private IntentFilter intentFilter;
            private LocalReceiver localReceiver;    //Local Broadcast Receiver
            private LocalBroadcastManager localBroadcastManager;   //Local broadcasting administrators can be used to register broadcasts
    
            /**
             * Actions to send local broadcasts
             */
            public static final String LOCAL_BROADCAST = "com.xfhy.casualweather.LOCAL_BROADCAST";
    
            //Do some initialization
            @Nullable
            @Override
            public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
                View view = inflater.inflate(R.layout.choose_area, container, false);
                recyclerView = (RecyclerView)view.findViewById(R.id.recycler_view);
    
                //Get the Local Broadcast Manager Local Broadcast Manager instance
                localBroadcastManager = LocalBroadcastManager.getInstance(getContext());
                localReceiver = new LocalReceiver();
                intentFilter = new IntentFilter();
                intentFilter.addAction(LOCAL_BROADCAST);   //Add action
                localBroadcastManager.registerReceiver(localReceiver,intentFilter);   //Register Local Broadcasting
    
                //Setting up LayoutManager
                LinearLayoutManager linearManager = new LinearLayoutManager(getContext());
                recyclerView.setLayoutManager(linearManager);
    
    
                //Setting up adapter
                adapter = new ProvinceCityAdapter(dataList);
                recyclerView.setAdapter(adapter);
    
                return view;
            }
    
            @Override
            public void onActivityCreated(@Nullable Bundle savedInstanceState) {
                super.onActivityCreated(savedInstanceState);
            }
    
            /**
             * Queries select all cities in the province, first query from the database, if there is no query to the server.
             */
            protected void queryCities() {
                Log.i(TAG, "queryCities: I am queryCities");
            }
    
    
            private class LocalReceiver extends BroadcastReceiver{
                @Override
                public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();
                    if(!action.equals(LOCAL_BROADCAST)){
                        return ;
                    }
    
                    boolean queryCity = intent.getBooleanExtra("query_city",false);  //Determine whether a query city needs to be invoked
    
                    //If it receives broadcasts that need to query city information, it executes the method.
                    if(queryCity){
                        queryCities();
                    }
    
                }
            }
    
            @Override
            public void onDestroy() {
                super.onDestroy();
                localBroadcastManager.unregisterReceiver(localReceiver);    //Cancellation of broadcasting registration
            }
    }
    

Summary: When adapter calls the method in fragment, it actually registers local broadcasting in fragment, and then when adapter needs to call the method in fragment, it sends a broadcasting to adapter itself. Then fragment receives the broadcasting, analyses the data, knows what method to call, and finally calls the method in fragment itself. It's easy to implement.

Posted by Gamic on Sun, 14 Apr 2019 15:03:32 -0700