Click an ImageButton which belongs to a CardView i

2019-02-20 00:18发布

问题:

SOLVED

I've fixed it mixing your answers, so I've decided to write down on here.

The key has been the ViewHolder constructor:

I have deleted the setOnClickListener() and the onClick() methods and I´ve defined this inner class in my 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();
                }
            });
     }
}

And that´s all. The rest of the class is the same.

The ObjectFragment.java is:

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;
    }
}

Thank you very much guys.


Original question

I have a RecyclerView which contains some CardViews. This CardViews have two different ImageButton which make different things when you click them (obvious).

Here is the 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_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/object_card"
    card_view:cardCornerRadius="2dp"
    card_view:cardElevation="2dp"
    card_view:cardBackgroundColor="@color/colorPrimary"
    android:clickable="true">

    <LinearLayout
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:background="@color/colorPrimary">

        <ImageButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                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_width="wrap_content"
                android:layout_height="wrap_content"
                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>

This is the main code of my 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);
    } 
}

My ObjectFragment.java is the next:

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;
    }
}

I can obtain the values of the Object attributes (name, title, whatever), and click on the CardView and so on, but I'm not able to make that the ImageButtonhave their own onClick.

I don't know if using android:onClick() it would be possible to display the information of a specific card, but this is another thing.

So my question is how can I make that this two buttons do have their own OnClickListener, where I should declare it and how can handle the information of each item of the RecyclerView after that (this part is almost achieved).

Any idea? Thanks a lot!

回答1:

You can add the button event clicks in your ViewHolder class like this.

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;

 }

}


回答2:

I think something like view.findViewById(R.id.mybutton).setOnClickListener(...); should do the job.

Let me know if that works.



回答3:

Something like this?

@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:

This is old but I have a solution that works for me, after a lot of trial and error, and is easier than the others. Keeping the ViewHolder RecycleronClickListeners the same and the adapter the same:

in onClick() in the Fragment:

@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;