【问题标题】:How to send data from recycler adapter to fragment | How to call fragment function from recyclerview adapter如何将数据从回收器适配器发送到片段 |如何从 recyclerview 适配器调用片段函数
【发布时间】:2018-02-19 23:11:52
【问题描述】:

我在 Fragment 中有代码:

InfoAdapter adapter = new InfoAdapter(getContext(), R.layout.lv_info, infoList );

            listingsView = (RecyclerView) rootView.findViewById(R.id.lvInfo);
            RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
            listingsView.setLayoutManager(layoutManager);
            listingsView.setHasFixedSize(true);
            listingsView.setAdapter(adapter);

如何处理对该片段中项目的点击? 例如调用具有 ID 项的函数(位于片段中的函数)(例如 public void onItemClick(int item_id) {} )

我的适配器:

public class InfoAdapter extends RecyclerView.Adapter<InfoHolder> {

    private final List<Info> infos;
    private Context context;
    private int itemResource;


    public InfoAdapter(Context context, int itemResource, List<Info> infos) {

        this.infos = infos;
        this.context = context;
        this.itemResource = itemResource;
    }

    @Override
    public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext())
                .inflate(this.itemResource, parent, false);
        return new InfoHolder(this.context, view);
    }

    @Override
    public void onBindViewHolder(InfoHolder holder, int position) {

        Info info = this.infos.get(position);
        holder.bindInfo(info);
    }

    @Override
    public int getItemCount() {
        return this.infos.size();
    }
 }

【问题讨论】:

  • 你可以尝试实现回调

标签: android android-fragments android-recyclerview fragment


【解决方案1】:

您可以使用界面来达到您想要的结果。 只需使用要传递给片段的参数在适配器中声明一个接口。并在您的片段中初始化接口并将其传递给适配器的构造函数。

你可以这样做:

在你的片段中

public class MainFragment extends Fragment {

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    // Pass your adapter interface in the constructor
    InfoAdapter adapter = new InfoAdapter(getContext(), R.layout.lv_info, infoList, adapterInterface );
}

// This is the interface declared inside your adapter.
InfoAdapter.InfoAdapterInterface adapterInterface = new InfoAdapter.InfoAdapterInterface() {
    @Override
    public void OnItemClicked(int item_id) {
        // Do whatever you wants to do with this data that is coming from your adapter
    }
};

}

在您的适配器中

public class InfoAdapter extends RecyclerView.Adapter<InfoHolder> {

    private final List<Info> infos;
    private Context context;
    private int itemResource;

    // Interface Object
    private InfoAdapterInterface adapterInterface;

    public InfoAdapter(Context context, int itemResource, List<Info> infos, InfoAdapterInterface adapterInterface) {

        this.infos = infos;
        this.context = context;
        this.itemResource = itemResource;

        // Initialize your interface to send updates to fragment.
        this.adapterInterface = adapterInterface;
    }

    @Override
    public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext())
                .inflate(this.itemResource, parent, false);
        return new InfoHolder(this.context, view);
    }

    @Override
    public void onBindViewHolder(InfoHolder holder, int position) {

        Info info = this.infos.get(position);
        holder.bindInfo(info);

        // You can pass any data here that is defined in your interface's params
        adapterInterface.OnItemClicked(3);
    }

    @Override
    public int getItemCount() {
        return this.infos.size();
    }

    // Your interface to send data to your fragment
    public interface InfoAdapterInterface{
        void OnItemClicked(int item_id);
    }

 }

您可以在界面中创建多个方法,并且可以轻松地在界面中获取所需的数据。另一个技巧是使用抽象方法。

我希望这会对你有所帮助。如果您遇到任何困难,请告诉我:)


编辑显示如何将接口从适配器传递到 ViewHolder

在您的适配器类中执行此操作

@Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext())
            .inflate(this.itemResource, parent, false);

    // Pass the interface that you've created in the constructor of your viewholder
    return new InfoHolder(view, adapterInterface);
}

在您的 ViewHolder 中,您可以获得这样的界面,并在您的 ViewHolder 中的任何地方使用它:

public class InfoHolder extends RecyclerView.ViewHolder {

    public InfoHolder(View itemView, final InfoAdapter.InfoAdapterInterface adapterInterface) {
        super(itemView);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                adapterInterface.OnItemClicked(2);

            }
        });

    }

}

这应该可以解决您的接口问题^_^

【讨论】:

  • 谢谢!我用 BroadcastReceiver 解决了这个问题
  • 好吧,我将避免为此使用广播接收器,因为在广播接收器中,您必须注意注册和注销您的接收器,并且广播接收器在多线程或在服务中使用时非常有用。但是在您的情况下,您不需要使用它们。是的,您可以使用 BR 获得相同的结果,但是如果我们在所有情况下都使用 BR,那么他们为什么要制作接口或抽象或处理程序之类的概念.. 但是您仍然可以使用 BR,就好像您对它们更满意 :)
  • 我想重新制作使用界面,但是点击处理程序在InfoHolder中,而不是在InfoAdapter中(
  • 我很高兴它成功了......请将答案标记为正确,以便它可以帮助其他人^_^
  • 好的兄弟!)我发现了一个有趣的课程gist.github.com/nesquena/231e356f372f214c4fe6,我会在以后查找它
【解决方案2】:

在你的 onBindViewHolder 方法中,在绑定视图中设置 onclicklistener 并通过 Bundle 传递其参数。

【讨论】:

    【解决方案3】:

    只需将 Fragment 实例传递给适配器。

    例如:

    在片段中: recyclerAdapter = new RecyclerAdapter(getActivity(), MyFragment.this); recyclerView.setAdapter(recyclerAdapter); recyclerAdapter.notifyDataSetChanged(); 在适配器中: 1. 创建适配器构造器,如

    MyFragment myFragment;
    public RecyclerAdapter(Context context, MyFragment myFragment){
        this.context = context;
        this.myFragment = myFragment;
    }
    
    1. onBindViewHolder 下

    调用 myFragment.yourMethodName;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多