如何在Android中同时使用Button和RecycleView

3

https://drive.google.com/open?id=1R964AvU-a7TW8Lfp8VqJnmcbvhc-7gcN

我有一个recycleView(如上图所示)。你可以看到还有两个按钮。这是布局文件file.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@color/white">


  <de.hdodenhof.circleimageview.CircleImageView
      android:layout_marginLeft="10dp"
      android:id="@+id/main_picture"
      android:layout_width="45dp"
      android:layout_height="50dp"
      android:src="@drawable/pfl_img"
      android:layout_centerVertical="true"
      android:layout_alignParentStart="true" />


<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_toRightOf="@id/main_picture"
    android:layout_marginRight="5dp"
    android:layout_marginLeft="10dp"
    android:id="@+id/relativeLayout2">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Edem Palonik"
        android:textSize="17sp"
        android:id="@+id/textName"
        android:textColor="@color/black"
        android:layout_above="@+id/textDescription"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Profession and ..."
        android:textColor="@color/black"
        android:textSize="17sp"
        android:id="@+id/textDescription"
        android:layout_centerVertical="true"
        android:layout_alignParentStart="true" />

    <ImageView
        android:layout_width="20dp"
        android:layout_height="18dp"
        android:layout_marginTop="2dp"
        android:layout_below="@+id/textDescription"
        android:id="@+id/historyIcon"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_marginLeft="5dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/date"
        android:textSize="14sp"
        android:text="17/12/2017/13:46"
        android:layout_marginTop="2dp"
        android:layout_below="@+id/textDescription"
        android:layout_toEndOf="@+id/historyIcon" />
</RelativeLayout>

<Button
    android:id="@+id/call_button"
    android:layout_width="32dp"
    android:layout_height="32dp"
    android:layout_marginRight="10dp"
    android:background="@drawable/call_img"
    android:layout_centerVertical="true"
    android:layout_toStartOf="@+id/sms_button" />

<Button
    android:id="@+id/sms_button"
    android:layout_width="37dp"
    android:layout_height="32dp"
    android:background="@drawable/sms_img"
    android:layout_alignTop="@+id/call_button"
    android:layout_alignParentEnd="true" />

<View
    android:layout_width="match_parent"
    android:layout_height="0.8dp"
    android:layout_alignParentBottom="true"
    android:background="@color/gray" />

我知道,我可以使用recyclerViewItemCLickListener,但是我想单独点击最后2个按钮,那我需要做什么?

所以我想单独点击最后的按钮,而不是整行都被点击,我只想让最后的按钮可以被点击。

以下是java代码。

public class ConnectionsFragment extends Fragment {
private View mainView;
private RecyclerView recyclerView;
private List<Connections_item> list;
private Button call, sms;

public ConnectionsFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    mainView = inflater.inflate(R.layout.connections_fragment, container, false);
    recyclerView = (RecyclerView) mainView.findViewById(R.id.recycler_connection);
    ConnectionsAdapter adapter = new ConnectionsAdapter(getActivity(), list);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setAdapter(adapter);

    init(mainView);
    return mainView;
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    list = new ArrayList<>();
    list.add(new Connections_item(R.drawable.pfl_img, "Anun Azganun1", "Inch vor text", R.drawable.missed, "23/11/1998 00:00"));
    list.add(new Connections_item(R.drawable.pfl_img, "Anun Azganun2", "Inch vor text", R.drawable.callagain, "24/11/1998 01:00"));
    list.add(new Connections_item(R.drawable.pfl_img, "Anun Azganun3", "Inch vor text", R.drawable.missed, "25/11/1998 02:00"));


public void init(View v) {
    call = (Button) v.findViewById(R.id.call_button);
    sms = (Button) v.findViewById(R.id.sms_button);

//        call.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//                Toast.makeText(getActivity(), "Whom you wanna call?", Toast.LENGTH_SHORT).show();
//            }
//        });

//        sms.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//                Toast.makeText(getActivity(), "Whom you wanna send sms?", Toast.LENGTH_SHORT).show();
//            }
//        });
    }
}

这里是适配器的代码。
public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.MyViewHolder> {

Context context;
List<Connections_item> list = new ArrayList<>();

public ConnectionsAdapter(Context context, List<Connections_item> list) {
    this.context = context;
    this.list = list;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v;
    v = LayoutInflater.from(context).inflate(R.layout.connections_view_item, parent, false);
    MyViewHolder holder = new MyViewHolder(v);
    return holder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    holder.mainImage.setImageResource(list.get(position).getMainImage());
    holder.fullName.setText(list.get(position).getFullName());
    holder.description.setText(list.get(position).getDescription());
    holder.historyImage.setImageResource(list.get(position).getHistoryIcon());
    holder.date.setText(list.get(position).getDate());

}

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

public class MyViewHolder extends RecyclerView.ViewHolder {

    ImageView mainImage, historyImage;
    TextView fullName, description, date;
    Button call, sms;

    public MyViewHolder(View v) {
        super(v);

        mainImage = (ImageView) v.findViewById(R.id.main_picture);
        historyImage = (ImageView) v.findViewById(R.id.historyIcon);
        fullName = (TextView) v.findViewById(R.id.textName);
        description = (TextView) v.findViewById(R.id.textDescription);
        date = (TextView) v.findViewById(R.id.date);
        call = (Button) v.findViewById(R.id.call_button);
        sms = (Button) v.findViewById(R.id.sms_button);

    }
  }
}

你尝试过为特定按钮使用ClickListener吗? - Bunny
只需在您的视图持有者中将这两个按钮添加进去,进行初始化。然后在onBindViewHolder方法中设置点击监听器。 - Vidhi Dave
展示Java代码。 - Bunny
我添加了Java代码。 - Hayk Mkrtchyan
我编辑了代码,并在下面添加了按钮。 - Hayk Mkrtchyan
显示剩余9条评论
3个回答

5
使用接口可以实现这一功能。
public class TestAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    Context mContext;
    ArrayList<Data> mData;
    OnButtonClickListeners onButtonClickListeners;


    public TestAdapter(Context mContext, ArrayList<String> mData) {
        this.mContext = mContext;
        this.mData = mData;
    }

    public void setOnButtonClickListeners(OnButtonClickListeners listener){
        this.onButtonClickListeners = listener;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        MyViewHolder vh;
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        vh = new MyViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        //Bind holder here
    }


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


    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener  {


        @Bind(R.id.call_button)
        Button btnCall;

        @Bind(R.id.sms_button)
        Button btnSms;


        public MyViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);

            btnCall.setOnClickListener(this);
            btnSms.setOnClickListener(this);


        }


        @Override
        public void onClick(View v) {

            if(this.onButtonClickListeners!=null){

                switch (v.getId()) {
                    case R.id.call_button:
                        onButtonClickListeners.onCallClick(getAdapterPosition());
                        break;
                    case R.id.sms_button:
                        onButtonClickListeners.onSmsClick(getAdapterPosition());
                        break;
                }
            }

        }

    }

    public interface OnButtonClickListeners{

        void onCallClick(int position);
        void onSmsClick(int position);
    }

}

然后,您可以像下面这样从Activity和Fragment中调用此接口:
private void setUpRecyclerView(){
        mAdapter = new ProfileAdapter(mContext,new ArrayList<String>());
        lm = new LinearLayoutManager(getActivity());
        rvFeeds.setLayoutManager(lm);
        rvFeeds.setAdapter(mAdapter);

        mAdapter.setOnButtonClickListeners(new OnButtonClickListeners() {
            @Override
            public void onCallClick(int position) {
                    //To do your code here
            }

            @Override
            public void onSmsClick(int position) {
                    //To do your code here
            }
        })
    }

3

由于适配器包含recyclerView项目,而按钮位于项目中,所以与按钮相关的所有代码都只能在适配器中。

在适配器中修改代码:

@Override

    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.mainImage.setImageResource(list.get(position).getMainImage());
        holder.fullName.setText(list.get(position).getFullName());
        holder.description.setText(list.get(position).getDescription());
        holder.historyImage.setImageResource(list.get(position).getHistoryIcon());
        holder.date.setText(list.get(position).getDate());

        holder.call.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                   Toast.makeText(getActivity(), "Whom you wanna call?", Toast.LENGTH_SHORT).show();
                }
           });

        holder.sms.setOnClickListener(new View.OnClickListener() {
               @Override
                public void onClick(View view) {
                    Toast.makeText(getActivity(), "Whom you wanna send sms?",                                }
            });

    }

在Java文件中,只需删除通话和短信按钮的初始化和监听器。


刚才我也是这样做的,所以在MainActivity中还需要写些什么吗? - Hayk Mkrtchyan
没有什么需要,所有的东西都在适配器中。适配器持有回收视图项,按钮都在该项中。 - Vidhi Dave
是的,那个有效,非常感谢。我现在会接受你的答案。请问你能投票支持我的问题吗?我需要一点声望。 - Hayk Mkrtchyan
哦不,它说我只能在24小时后接受这个答案((( - Hayk Mkrtchyan

0

当您在RecyclerView的ViewHolder中创建视图时,可以尝试为按钮实现onClickListener。然后传递一个带有两个方法的接口给两个按钮,并在需要的任何位置实现该接口。

就像这个例子:

public class MyViewHolder extends RecyclerView.ViewHolder {
  public MyViewHolder(View itemView, ButtonClickListener listner) {
    super(itemView);
    Button b1 = itemView.findViewById(...);
    Button b2 = itemView.findViewById(...);

    b1.setOnClickListener(view -> listener.onButton1Click());
    b2.setOnClickListener(view -> listener.onButton2Click());
  }
}

现在是接口部分

public interface ButtonClickListener {
  void onButton1Click();
  void onButton2Click();
}

否则,如果您习惯于使用bus,可以使用它来代替接口。这将使代码更加清晰。

为什么要添加那么多代码、接口等呢?我可以简单地在holder中初始化按钮。 - Hayk Mkrtchyan
在我看来,它提供了更多的灵活性来处理数据对象。比如说,如果你依赖于某些其他数据来响应按钮点击事件,在这种情况下,你需要将附加的数据集传递给适配器。相反,如果你在你的活动/片段类中实现接口,那么处理数据就会更容易。在另一种情况下,如果你需要基于点击在不同的线程上执行某些操作,你会更喜欢使用活动或片段类。此外,我们尽量使我们的视图持有者和适配器尽可能轻量级,因此分离点击监听器是更好的选择。 - arnab.p
好的,谢谢。还有一个问题,我的recyclerView没有onItemClickListener怎么办? - Hayk Mkrtchyan
你可以按照我展示的方式去做。只需在构造函数中实现一个 onClickListener 到整个 itemView 上即可。 - arnab.p

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接