adapter调用fragment中的方法

转载自:http://blog.csdn.net/xfhy_/article/details/61195558

前言:昨天遇到一个技术难题,对于我来说哈.我写的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();
    }

}

然后写一个在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通信的任务.




  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值