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:
-
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(); } }
-
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.