单击属于 RecyclerView 内 CardView 的 ImageButton

Posted

技术标签:

【中文标题】单击属于 RecyclerView 内 CardView 的 ImageButton【英文标题】:Click an ImageButton which belongs to a CardView inside a RecyclerView 【发布时间】:2016-06-07 01:26:20 【问题描述】:

已解决

我已经把你的答案混在一起了,所以我决定在这里写下来。

关键是 ViewHolder 构造函数:

我删除了setOnClickListener()onClick() 方法,并在ObjectAdapter.java 中定义了这个内部类。

public static class ViewHolder extends RecyclerView.ViewHolder

     public ViewHolder(View itemView) 
            super(itemView);
            card_first_btn.setOnClickListener(new View.OnClickListener() 
                @Override
                public void onClick(View v) 
                    int position = getAdapterPosition();
                    Toast.makeText(v.getContext(), object.get(position).getName(), Toast.LENGTH_SHORT).show();
                
            );
            card_second_btn.setOnClickListener(new View.OnClickListener() 
                @Override
                public void onClick(View v) 
                    Toast.makeText(v.getContext(), "Forward button", Toast.LENGTH_SHORT).show();
                
            );
     

仅此而已。其余的课程都是一样的。

ObjectFragment.java 是:

public class ObjectFragment extends Fragment 

    public void ObjectFragment() 
        // Required empty public constructor
    

    @Override
    public View onCreateView(LayoutInflater layoutInflater, ViewGroup container, Bundle savedInstanceState) 
        // Inflate the layout for this Fragment
        return layoutInflater.inflate(R.layout.fragment_object, container, false);
    

    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
        super.onActivityCreated(savedInstanceState);

        final ArrayList<Object> objects = initializeList();

        if(!objects.isEmpty())    
            RecyclerView recyclerView = (RecyclerView) getActivity().findViewById(R.id.objects_recyclerView);
            recyclerView.setHasFixedSize(true);
            recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            recyclerView.addItemDecoration(new SimpleDivider(getActivity().getApplicationContext()));

            final ObjectAdapter objectAdapter = new ObjectAdapter(objects, R.layout.card_object);    
            recyclerView.setAdapter(objectAdapter);
        
    

    private ArrayList<Object> initializeList() 
        ArrayList<Object> objects= new ArrayList<>();    
        objects.add(new Object(...));    
        return objects;
    

非常感谢你们。


原始问题

我有一个RecyclerView,其中包含一些CardViews。这个CardViews 有两个不同的ImageButton,当你点击它们时会产生不同的效果(很明显)。

这里是card_object.xml

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_
    android:id="@+id/object_card"
    card_view:cardCornerRadius="2dp"
    card_view:cardElevation="2dp"
    card_view:cardBackgroundColor="@color/colorPrimary"
    android:clickable="true">

    <LinearLayout
        android:layout_
        android:layout_
        android:orientation="vertical"
        android:background="@color/colorPrimary">

        <ImageButton
                android:layout_
                android:layout_
                android:id="@+id/object_card_first_button"
                android:src="@drawable/contact_100px"
                android:maxHeight="25dp"
                android:maxWidth="25dp"
                android:adjustViewBounds="true"
                android:scaleType="centerCrop"
                android:background="@color/transparentBackgroundPrimary"
                android:layout_marginRight="54dp"
                android:layout_marginEnd="54dp"/>

        <ImageButton
                android:layout_
                android:layout_
                android:src="@drawable/forward_100px"
                android:maxHeight="25dp"
                android:maxWidth="25dp"
                android:adjustViewBounds="true"
                android:scaleType="centerCrop"
                android:background="@color/transparentBackgroundPrimary"
                android:id="@+id/object_card_second_button" />
    </LinearLayout>
</android.support.v7.widget.CardView>

这是我ObjectAdapter.java的主要代码:

public class ObjectAdapter 
        extends RecyclerView.Adapter<ObjectAdapter.ViewHolder> 
        implements View.OnClickListener 

    private ArrayList<Object> objects;
    private int itemLayout;
    private View.OnClickListener onClickListener;

    public ObjectAdapter(ArrayList<Object> objects, int itemLayout) 
        this.objects = objects;
        this.itemLayout = itemLayout;
    

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) 
        View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(itemLayout, viewGroup, false);

        view.setOnClickListener(this);

        return new ViewHolder(view);
    

    public void setOnClickListener(View.OnClickListener listener) 
        this.onClickListener = listener;
    

    public void onClick(View view) 
        if(onClickListener != null) 
        onClickListener.onClick(view);
     

我的ObjectFragment.java 是下一个:

public class ObjectFragment extends Fragment 

    public void ObjectFragment() 
        // Required empty public constructor
    

    @Override
    public View onCreateView(LayoutInflater layoutInflater, ViewGroup container, Bundle savedInstanceState) 
        // Inflate the layout for this Fragment
        return layoutInflater.inflate(R.layout.fragment_object, container, false);
    

    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
        super.onActivityCreated(savedInstanceState);

        final ArrayList<Object> objects = initializeList();

        if(!objects.isEmpty())    
            RecyclerView recyclerView = (RecyclerView) getActivity().findViewById(R.id.objects_recyclerView);
            recyclerView.setHasFixedSize(true);
            recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            recyclerView.addItemDecoration(new SimpleDivider(getActivity().getApplicationContext()));

            final ObjectAdapter objectAdapter = new ObjectAdapter(objects, R.layout.card_object);
            objectAdapter.setOnClickListener(new View.OnClickListener() 
                @Override
                public void onClick(View v) 
                    // Here I can manage my Object attributes,
                    // but no the ImageButtons itselves
                
            );

            recyclerView.setAdapter(objectAdapter);
        
    

    private ArrayList<Object> initializeList() 
        ArrayList<Object> objects= new ArrayList<>();    
        objects.add(new Object(...));    
        return objects;
    

我可以获取Object 属性的值(名称、标题等),然后单击CardView 等等,但我无法使ImageButton 拥有自己的onClick .

我不知道使用android:onClick()是否可以显示特定卡的信息,但这是另一回事。

所以我的问题是如何让这两个按钮确实有自己的OnClickListener,我应该在哪里声明它以及之后如何处理RecyclerView的每个项目的信息(这部分几乎实现了)。

有什么想法吗?非常感谢!

【问题讨论】:

【参考方案1】:

您可以像这样在 ViewHolder 类中添加按钮事件点击。

public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener

public ButtonImage firstButton;
public ButtonImage secondButton;

public RecyclerViewHolders(View itemView) 
    super(itemView);
    itemView.setOnClickListener(this);
    firstButton = (ImageButton)itemView.findViewById(R.id.object_card_first_button);
    firstButton = (ImageButton)itemView.findViewById(R.id.object_card_second_button);


@Override
public void onClick(View view) 
 int id = view.getId();
 switch (id)
       case R.id.object_card_first_button:
       // button event
       break;
       case R.id.object_card_second_button
       // button event
       break;

 


【讨论】:

我已经尝试过了,这样做的问题是按钮事件不知道哪个CardViewImageButton 的所有者。唯一的方法是传递我正在单击的CardView 的索引,而通过这种方式是不可能的。我想。 你可以在你的 RecycleViewAdapter 中获取位置 - @Override public void onBindViewHolder(RecyclerViewHolders holder, int position) 我不知道该怎么做。你能写一些示例代码吗? @ÓscarGrande 这个答案应该适合你。在 onClick 方法中使用 getAdapterPosition() 来识别被点击的位置 感谢@MuchOverflow。我不知道它是关键!【参考方案2】:

我认为类似于 view.findViewById(R.id.mybutton).setOnClickListener(...);应该做的工作。

让我知道这是否有效。

【讨论】:

我在第一个onClick(...) 中添加了v.findViewById(...).setOnClickListener(...),因为这是查看CardView 的唯一方法,所以我必须先点击卡片,然后点击按钮。这是一个解决方案,但不是最好的。 您必须在适配器的 onCreateViewHolder 中添加我的行,您将拥有我认为所需的所有信息。 你可能会对 v.getParent(); 感兴趣【参考方案3】:

这样的?

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) 
    View view = LayoutInflater.from(viewGroup.getContext())
            .inflate(itemLayout, viewGroup, false);

    view.setOnClickListener(this);

    ImageButton btn = (ImageButton)view.findViewById(R.id. object_card_first_button);

    btn.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                something?
            
        );

    return new ViewHolder(view);

【讨论】:

【参考方案4】:

这是旧的,但经过大量试验和错误后,我有一个适合我的解决方案,并且比其他解决方案更容易。保持 ViewHolder RecycleronClickListeners 相同,adapter 相同:

在Fragment中的onClick()中:

@Override
public void onClick(View view, int position, int id) 
    switch (id) 
        case R.id.button_1:
            ImageButton button = (ImageButton) view;
            button.setImageResource(resource); // Or any other imagebutton action
            break;
        case R.id.button_2:
            ImageButton button = (ImageButton) view;
            button.setImageResource(resource); // Or any other imagebutton action
            break;

【讨论】:

以上是关于单击属于 RecyclerView 内 CardView 的 ImageButton的主要内容,如果未能解决你的问题,请参考以下文章

如何在recyclerView(没有按钮)中单击项目时播放歌曲?

片段内的 RecyclerView 的 Kotlin OnItemClickListener

Android RecyclerView 项目宽度不匹配父和预览不匹配模拟器

如何在recyclerview中获取所选项目,何时在片段内?

关于打开一个新活动以响应对片段内的 RecyclerView 项目的点击

android studio中片段内的RecyclerView使我的应用程序崩溃