android-fragments RecyclerView JAVA适配器中的片段

qyswt5oh  于 2022-11-13  发布在  Android
关注(0)|答案(1)|浏览(251)

我有一个片段Users,其中有3个片段(标签)。对于一个标签(称为Friends 2Fragment),我做了一个回收器视图,并为它做了一个适配器。在RecyclerView的每一项中,我都有一个按钮“Add friend”,我想从Friends 2Fragment调用它,而不是从适配器调用它,因为我不能正确使用Firestore数据库。

回收机视图界面

public interface RecyclerViewInterface {
    void onItemClick(int position, String button_pressed);
}

朋友2片段. java

public void onStart(){
        super.onStart();

        recyclerView = (RecyclerView) v.findViewById(R.id.recycler);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        friendslist = new ArrayList<>();
        myAdapter = new MyAdapter(friendslist,v.getContext());
        recyclerView.setAdapter(myAdapter);
          ------ Firestore operations ------
}
    @Override
    public void onItemClick(int position, String button_pressed) {
        switch ( button_pressed ){
            case "ADD_FRIEND":
             Log.d(TAG, "item clicked: " + friendslist.get(position).username);

        }
    }

我的适配器.java

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.myViewHolder> {

    Context context;
    public ArrayList<User> userArrayList;

    public MyAdapter(ArrayList<User> userArrayList, Context context)  {
        this.userArrayList = userArrayList;
        this.context = context;
    }

    public Context getContext() {
        return context;
    }

    public ArrayList<User> getUserArrayList() {
        return userArrayList;
    }

    @NonNull
    @Override
    public MyAdapter.myViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
        MyAdapter.myViewHolder myViewHolder = new MyAdapter.myViewHolder(v);
        myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                ((Friends2Fragment)context).onItemClick(myViewHolder.getAdapterPosition(),"ADD_FRIEND");
            }
        });
        return myViewHolder;
}
@Override
    public void onBindViewHolder(@NonNull MyAdapter.myViewHolder holder, int position) {

        User user = userArrayList.get(position);

        holder.usernamerecycle.setText(user.username);
    }

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

    public void filterList(List<User> filteredList){
        userArrayList = (ArrayList<User>) filteredList;
        notifyDataSetChanged();

    }

    public class myViewHolder extends RecyclerView.ViewHolder{

        TextView usernamerecycle;
        Button addbutton;
        View rootview;

        public myViewHolder(@NonNull View itemView) {
            super(itemView);
            rootview = itemView;
            usernamerecycle = itemView.findViewById(R.id.usernamerecycler);
            addbutton = itemView.findViewById(R.id.addfriendbutton);
    }
  }
}

问题出在这一行:“添加_好友”);“添加_好友”**在MyAdapter中的onCreateViewHolder方法中。
我有这个错误:不可转换的类型;无法将'android.content.Context'强制转换为'com.example.birthday.Fragments.Friends2Fragment'
请帮帮我...

ttygqcqt

ttygqcqt1#

Fragment不是Context(它不是它的超类型之一),所以不可能进行转换,这就是为什么会出现错误。
我觉得你应该这样安排:你的Adapter保存了一堆User对象,对吗?它显示这些对象,你在每个ViewHolder上有一个点击监听器,它知道它当前显示的是User列表中的哪个索引,当它被点击时,它想通知一些监听器。那个索引实际上是一个内部细节,查找实际的User会更有意义,并将其提供给收听者。
最简单的方法是将片段作为侦听器提供,首先将其存储在适配器中:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.myViewHolder> {

    // store a reference to your fragment
    private Friends2Fragment listener;

    // add a function to provide that fragment
    public void setListener(Friends2Fragment: listener) {
        this.listener = listener
    }

    ...

    public MyAdapter.myViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        ...
        myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) {
                   // look up the actual user
                   User user = userArrayList.get(myViewHolder.getAdapterPosition());
                   // call a function on your fragment
                   listener.onItemClick(user, "ADD_FRIEND");
                }
            }
        });
    }

然后添加适配器使用的回调函数,并将适配器上的片段设置为 listener

// Friends2Fragment

// You should REALLY be doing this in onViewCreated or something, so this setup happens once.
// You're losing all your state by creating a new adapter whenever the user returns to the app
public void onStart(){
    ...
    myAdapter = new MyAdapter(friendslist,v.getContext());
    // set the fragment as the listener
    myAdapter.setListener(this);
    recyclerView.setAdapter(myAdapter);
}

// now add the function the adapter calls
private void onItemClick(User user, String someString) {
    // handle the clicked user
}

一个更好的方法是创建一个 interface,其中包含所有需要处理的事件,并让你的Fragment实现这些事件。它打破了与Fragment的硬关联,因为你可以传递 * 任何 * 实现这些函数的对象,而且它也更清晰,因为接口记录了适配器产生的所有数据,以及监听器需要能够处理的数据。类似如下:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.myViewHolder> {
    // the listener is now something that implements the Callbacks interface
    private Callbacks listener;
    ...
    // nesting it inside MyAdapter makes the path MyAdapter.Callbacks, which makes it clear
    // exactly what it is and what it relates to, and kinda gives the Adapter "ownership"
    interface Callbacks {
        void addFriend(User user)
    }

然后让Fragment实现该接口

public class Friends2Fragment() extends Fragment implements MyAdapter.Callbacks {
    ...
    // implement all the callbacks you need to handle
    override public void addFriend(User user) {
        // do the thing
    }

    // set it in the same way, since this Fragment implements MyAdapter.Callbacks
    myAdapter.setListener(this);

我认为这样做更简洁、更干净一些--但工作量也稍大一些。另外,如果您注意到的话,我将回调函数从通用的handleItemClick重命名为更具体的addFriend--这样就不必传递String来说明 * 这是什么样的点击 *,您只需为每个要处理的事件指定一个函数,并且可以适当地命名它们

相关问题