Android RecyclerView OnClickListener not reacting

579 views Asked by At

Ok, so I'm using RecyclerView in my project and need to implement click listener for each list item and an icon in each of the items.

What I tried was this solution: https://stackoverflow.com/a/24933117/722462 cause it looks pretty nice for me. But I couldn't get click listener to react for any click events. Any ideas what is wrong with my implementation? All the files listed below.

fragment_search.xml:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivityFragment">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/search_recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:id="@+id/search_empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical|center_horizontal"
        android:orientation="vertical"
        android:visibility="gone">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/icon_search_empty"
            android:background="@drawable/ic_info_outline_black_48dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="Brak wyników wyszukiwania"
            android:id="@+id/text_search_empty" />
    </LinearLayout>

</RelativeLayout>

list item:

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_station_layout"
    android:layout_width="match_parent"
    android:clickable="true"
    android:layout_height="48dp">

    <ImageView
        android:id="@+id/icon_item_station_fav"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:background="@drawable/ic_favorite_border_blue_24dp"
        android:clickable="true"
        android:paddingLeft="16dp"
        android:tint="#E3F2FD"/>

    <TextView
        android:id="@+id/item_station_name"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:paddingLeft="58dp"
        android:gravity="start|center_vertical"
        android:clickable="true"
        android:ellipsize="end"
        android:maxLines="1"
        android:singleLine="true"
        android:textSize="16sp" />

</RelativeLayout>

and finaly SearchAdapter.java:

    public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.ViewHolder> {

    private List<StationDTO> stations;

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

        public TextView stationName;
        public ImageView favIcon;

        private IHasSearchViewHolderCallback hasSearchViewHolderCallback;

        public ViewHolder(View itemView, IHasSearchViewHolderCallback hasSearchViewHolderCallback) {
            super(itemView);

            this.hasSearchViewHolderCallback = hasSearchViewHolderCallback;

            favIcon = (ImageView) itemView.findViewById(R.id.icon_item_station_fav);
            stationName = (TextView) itemView.findViewById(R.id.item_station_name);

            itemView.setOnClickListener(this);
            favIcon.setOnClickListener(this);

            Context ctx = itemView.getContext().getApplicationContext();
            FontHelper.ROBOTO_REGULAR.on(ctx, stationName);
        }

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.item_station_layout:
                    hasSearchViewHolderCallback.onItemLayout(getAdapterPosition());
                    break;
                case R.id.icon_item_station_fav:
                    hasSearchViewHolderCallback.onFavIcon(getAdapterPosition());
                    break;
                case R.id.item_station_name:
                    hasSearchViewHolderCallback.onStationName(getAdapterPosition());
                    break;
            }
        }

        public interface IHasSearchViewHolderCallback {
            void onItemLayout(int position);
            void onFavIcon(int position);
            void onStationName(int position);
        }
    }

    public SearchAdapter(List<StationDTO> stations) {
        this.stations = stations;
    }

    @Override
    public SearchAdapter.ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {

        View item = LayoutInflater
                .from(parent.getContext())
                .inflate(R.layout.item_station, parent, false);

        ViewHolder vh = new ViewHolder(item, new ViewHolder.IHasSearchViewHolderCallback() {
            @Override
            public void onItemLayout(int position) {
                Toast.makeText(parent.getContext(), "LAYOUT #" + position, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFavIcon(int position) {
                Toast.makeText(parent.getContext(), "FAV #" + position, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onStationName(int position) {
                Toast.makeText(parent.getContext(), "NAME #" + position, Toast.LENGTH_SHORT).show();
            }
        });

        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        StationDTO dto = stations.get(position);

        holder.stationName.setText(dto.getName());
    }

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

}
1

There are 1 answers

0
Kevin Cronly On

Try changing:

@Override
public void onClick(View v) {
            switch (v.getId()) {
                case R.id.item_station_layout:
                    hasSearchViewHolderCallback.onItemLayout(getAdapterPosition());
                    break;
                case R.id.icon_item_station_fav:
                    hasSearchViewHolderCallback.onFavIcon(getAdapterPosition());
                    break;
                case R.id.item_station_name:
                    hasSearchViewHolderCallback.onStationName(getAdapterPosition());
                    break;
            }
        }

to

itemView.setOnClickListener(new View.OnClickListener {
    @Override
    public void onClick(View v) {
    // appropriate code in here
    }
});

and do the same for favIcon. I have a feeling your problem is arising from the fact that your OnClickListener is on your ViewHolder and not actually on the TextView and ImageView.