Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RecyclerView Databinding Item click

I am trying to listen for row clicks (item clicks) on my recycler view from the Activity itself (not from adapter).

My Adapter so far looks like this:

public class ListMiestnostiAdapter extends RecyclerView.Adapter<ListMiestnostiAdapter.ViewHolder>{
    private List<Miestnost> data;

    // you provide access to all the views for a data item in a view holder
    public static class ViewHolder extends RecyclerView.ViewHolder {
        public ViewDataBinding binding;

        public ViewHolder(ViewDataBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }

        public void bind(Object obj){
            binding.setVariable(BR.obj, obj);
            binding.executePendingBindings();
        }
    }

    public ListMiestnostiAdapter(List<Miestnost> data) {
        this.data = data;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // create a new view
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        ActivityListMiestnostiRowBinding itemBinding = ActivityListMiestnostiRowBinding.inflate(inflater, parent,false);

        return new ViewHolder(itemBinding);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Miestnost item = data.get(position);
        holder.bind(item);
    }

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

And my row layout like this:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto">
    <data>
        <variable
            name="obj"
            type="com.example.com.projectname.Models.Miestnost" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/selectableItemBackground"
        android:clickable="true"
        android:focusable="true"
        android:orientation="horizontal"
        android:paddingBottom="@dimen/row_padding_vertical"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/row_padding_vertical">

        <TextView
            android:id="@+id/txt_miestnost_row_nazov"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:text="@{obj.Name}"
            android:textSize="16dp" />
    </LinearLayout>
</layout>

As I have already mentioned I am trying to listen to item clicks, but not from Adapter itself (as other posts suggested), but from my Activity which holds this RecyclerView.

Is such action even possible? If yes, then any help would be highly appreciated as I could not find anything on google.

like image 466
Robert J. Avatar asked Jan 15 '18 18:01

Robert J.


1 Answers

You’ll first need an interface that specifies listener’s behavior. In this example, there is a sample model called ContentItem, so the click will return an item of that type:

public interface OnItemClickListener {
    void onItemClick(ContentItem item);
}

The constructor will receive an object that implements this interface, along with the items to be rendered:

private final List<ContentItem> items;
private final OnItemClickListener listener;

public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
    this.items = items;
    this.listener = listener;
}

You could alternatively create a setOnItemClickListener method and assign it that way. Now, in onBindViewHolder the ViewHolder will receive the constructor in the custom bind method:

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.bind(items.get(position), listener);
}

This is how this bind method looks:

public void bind(final ContentItem item, final OnItemClickListener listener) {
    ...
    itemView.setOnClickListener(new View.OnClickListener() {
        @Override public void onClick(View v) {
            listener.onItemClick(item);
        }
    });
}

Use it whenever you need it by creating a new adapter and the listener that will implement the behavior when an item is clicked. A simple example:

recycler.setAdapter(new ContentAdapter(
    items,
    new ContentAdapter.OnItemClickListener() {
        @Override
        public void onItemClick(ContentItem item) {
            Toast.makeText(getContext(), "Item Clicked", Toast.LENGTH_LONG).show();
        }
    }));

Source

like image 92
João Alvares Neto Avatar answered Oct 28 '22 21:10

João Alvares Neto