adapter调用fragment中的方法

adapter调用fragment中的方法

前言:昨天遇到一个技术难题,对于我来说哈.我写的demo需求是在fragment中放一个RecyclerView,然后RecyclerView显示一些简单的数据,这些数据需要请求网络才行.然后我自定义了一个adapter,发现在处理RecyclerView子项的点击事件时,由于adapter不是fragment的内部类,不能直接访问fragment的属性和方法,但是我又必须要通知fragment调用fragment调用一些它自己的方法,比如打开进度条对话框或者关闭等.

好了,现在开始解决该问题:

网上查了好了都没有找到相应的解决办法,大神们说有2种办法:

  • 接口回调
  • 广播

我是用本地广播实现的上面的难题.具体实现如下:

  1. 首先新建一个Adapter继承自RecyclerView.Adapter,具体代码如下:

    public class ProvinceCityAdapter extends
            RecyclerView.Adapter<ProvinceCityAdapter.ViewHolder> {
    
        private static final String TAG = "ProvinceCityAdapter";
    
    
        private List<String> mDataList = new ArrayList<>();   //数据
    
        private LocalBroadcastManager localBroadcastManager;
    
        //用于缓存数据
        static class ViewHolder extends RecyclerView.ViewHolder {
    
            TextView textView;
    
            //构造方法
            public ViewHolder(View itemView) {
                super(itemView);
                textView = (TextView) itemView.findViewById(R.id.tv_prcico);
            }
        }
    
        public ProvinceCityAdapter(List<String> mDataList) {
            this.mDataList = mDataList;
        }
    
        //创建ViewHolder实例
        @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();  //可以获取到点击的索引
                    intent.putExtra("query_city", true);   //通知fragment,让它去调用queryCity()方法
                    localBroadcastManager.sendBroadcast(intent);   //发送本地广播   通知fragment该刷新了
                }
            });
            return viewHolder;
        }
    
        //子项数据进行赋值   当滚动到屏幕内时执行
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            String position_choice = mDataList.get(position);
            holder.textView.setText(position_choice);
        }
    
        //多少个子项
        @Override
        public int getItemCount() {
            return mDataList.size();
        }
    
    }
    
  2. 然后写一个在fragment的代码里面,需要注册本地广播,当接收到adapter发送的广播时,需要作出反应,具体实现如下:

        public class ChooseAreaFragment extends Fragment {
    
            private static final String TAG = "ChooseAreaFragment";
    
    
            private RecyclerView recyclerView;  //列表
            private ProvinceCityAdapter adapter;  //适配器
            private List<String> dataList = new ArrayList<>();   //数据
    
    
    
            private IntentFilter intentFilter;
            private LocalReceiver localReceiver;    //本地广播接收者
            private LocalBroadcastManager localBroadcastManager;   //本地广播管理者   可以用来注册广播
    
            /**
             * 发送本地广播的action
             */
            public static final String LOCAL_BROADCAST = "com.xfhy.casualweather.LOCAL_BROADCAST";
    
            //做一些初始化操作
            @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);
    
                //获取LocalBroadcastManager   本地广播管理者实例
                localBroadcastManager = LocalBroadcastManager.getInstance(getContext());
                localReceiver = new LocalReceiver();
                intentFilter = new IntentFilter();
                intentFilter.addAction(LOCAL_BROADCAST);   //添加action
                localBroadcastManager.registerReceiver(localReceiver,intentFilter);   //注册本地广播
    
                //设置LayoutManager
                LinearLayoutManager linearManager = new LinearLayoutManager(getContext());
                recyclerView.setLayoutManager(linearManager);
    
    
                //设置adapter
                adapter = new ProvinceCityAdapter(dataList);
                recyclerView.setAdapter(adapter);
    
                return view;
            }
    
            @Override
            public void onActivityCreated(@Nullable Bundle savedInstanceState) {
                super.onActivityCreated(savedInstanceState);
            }
    
            /**
             * 查询选中省内所有的市,优先从数据库查询,如果没有查询到再去服务器查询
             */
            protected void queryCities() {
                Log.i(TAG, "queryCities: 我是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);  //判断是否需要调用查询城市
    
                    //如果是接收到需要查询城市信息的广播   则去执行该方法
                    if(queryCity){
                        queryCities();
                    }
    
                }
            }
    
            @Override
            public void onDestroy() {
                super.onDestroy();
                localBroadcastManager.unregisterReceiver(localReceiver);    //取消广播的注册
            }
    }
    

总结:adapter调用fragment中的方法,其实就是在fragment中注册本地广播,然后adapter需要调用fragment里面的方法的时候就adapter自己发送一条广播.然后fragment接收到这条广播,分析数据,知道了应该去调用什么方法,最后去调用fragment自己里面的方法就行了.其实,知道方法知道,接下来实现起来就简单了.

更新: 2017年3月30日

回调接口

  1. 首先在Adapter中写一个

    public interface XXListener {
        public void onXXClick();
    }
    

    然后在Adapter中定义一个属性,XXListener mXXListener,并写如下方法

    public void setOnXXClickListener (XXListener  XXListener) {
        this.mXXListener = XXListener;
    }
    

    这就完成了监听器的初始化,只需要在adapter中的处理点击的事件的地方,调用一下mXXListener.onXXClick()即可.即可回调.

2.在fragment中 当adapter接收到点击事件时,回调该接口,即可在这里接收到消息.

adapter.setOnXXClickListener (new XXListener(){
    @Override
    public void onXXClick(){
    }
});

完成上面的工作,fragment即完成了和adapter通信的任务.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值