-1

I'm using a RecyclerView to display some data. For each item I have a custom layout which holds beside some text views a RecyclerView:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:layout_width="180dp"
        android:layout_height="45dp"
        android:id="@+id/recycler_view"/>

    //Other text views
</RelativeLayout>

This is my adapter class:

class UserViewHolder extends RecyclerView.ViewHolder {
    View itemView;
    RecyclerView recyclerView;

    UserViewHolder(View itemView) {
        super(itemView);
        this.itemView = itemView;
        recyclerView = itemView.findViewById(R.id.recycler_view);
    }

    void bind(User user) {
        itemView.setOnClickListener(view -> {
            //Move to user Activity
        });

        UserAdapter adapter = new UserAdapter(user.list);
        recyclerView.setAdapter(adapter);

        itemView.bringToFront(); //Doesn't work!!!
    }
}

I have set on click listener on the entire itemView so I can be redirected to user's activity. The problem is that when I click on the elements that exist in the RecyclerView, I'm not redirected. I tried to bring the itemView in front of the RecyclerView but with no luck. How should I do so I can be redirected to the user activity even if I click on the RecyclerView? Thanks!

Edit:

This is how my itemView layout looks like:

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusable="true"
    android:clickable="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        //One TextView
        //One ImageView
        //One RecyclerView
    </RelativeLayout>
</android.support.v7.widget.CardView>

This is an image of it:

enter image description here

Johans Bormman
  • 855
  • 2
  • 11
  • 23

3 Answers3

2

Simple, instead of trying to navigate on that new screen from within the adapter, you can implement an interface and use it from the activity / fragment in which the RecyclerView is visible..

Demonstration

class UserViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
    View itemView;
    RecyclerView recyclerView;

    UserViewHolder(View itemView) {
        super(itemView);
        this.itemView = itemView;
        recyclerView = itemView.findViewById(R.id.recycler_view);
    }

    @Override
    public void onClick(View v) {
        if (listener != null)
           listener.onItemListClicked(getAdapterPosition());
    }

    void bind(User user) {
        itemView.setOnClickListener(this);

        UserAdapter adapter = new UserAdapter(user.list);
        recyclerView.setAdapter(adapter);

        itemView.bringToFront(); //Doesn't work!!!
    }
}

The interface should placed outside the UserViewHolder class.

public interface MyClickListener{
    void onItemListClicked(int position);
}

You will have a public method in the adapter, that will set the listener

public void setListenerForAdapter(MyClickListener listener) {
    this.listener = listener;
}

Finally in your activity will set the listener to the adapter

adapter.setListener(/*here you will implement your custom listener and start a new activity / fragment based on which position was clicked*/);

For any other questions, feel free to ask. Happy coding !

Johans Bormman
  • 855
  • 2
  • 11
  • 23
Ionut J. Bejan
  • 734
  • 11
  • 28
  • Thanks for taking the time to answer my question but I just tried your solution and it's the same as before. I think it's because I set the listener on the same `itemView` object. I also think it's something with that `RecyclerView`, it behaves different than the other views. Nothing happens when I click on the `RecyclerView` :( Have you tried it or is there any other solution? – Johans Bormman Mar 28 '19 at 15:41
  • I have tested instead of a RecyclerView with an ImageView and TextView and it work perfect, with a RecyclerView is not working. I think it's because when I click, it tries to scroll the elements instead of keeping the click of the parent `itemView`. I have also tried to disable click on the it and doesn't help. – Johans Bormman Mar 28 '19 at 15:59
  • Do you have any other idea? – Johans Bormman Mar 28 '19 at 16:53
  • @JohansBormman let me understand it better, you are having some nested `RecyclerViews` and you want a click on the whole `RecyclerView` item ?? (the nested one) – Ionut J. Bejan Mar 29 '19 at 08:05
  • No, I have a RecyclerView which contains some items. Each item has a TextView, an ImageView and a RecyclerView. **[This](https://ibb.co/SQG484b)** is how an `itemView` looks like. I'm redirected fine when I click on the ImageView, TextView but not on a click on a RecyclerView. If I remove the RecyclerView or add another ImageView instead of the RecyclerView, everything works fine but with RecyclerView the click doesn't work. Hope I've been clear now, or? – Johans Bormman Mar 29 '19 at 09:34
  • So I have no interest in clicking an item from the nested RecyclerView or the nested RecyclerView itself, I want to be redirected on a click on the entire `itemView`, no matter on which view I'm clicking.. – Johans Bormman Mar 29 '19 at 09:51
  • So you cannot intercept the click on the area where the `RecyclerView` is visible, mostly because of the behavior of rv itself. You can try to set next attributes on the rv `android:focusable="false" android:clickable="false"` – Ionut J. Bejan Mar 29 '19 at 10:01
  • Setting those details didn't help. Ok, that's the nature of the RecyclerView but it cannot be changed somehow? Is there any other approach? – Johans Bormman Mar 29 '19 at 11:53
  • Hmm, as a workaround, you could implement same interface for the `nested RecyclerView` and in the activity, if that click is intercepted, take same action, or trigger the parent `RecyclerView` click. Might do the trick :D – Ionut J. Bejan Mar 29 '19 at 14:21
  • Solved the issue using Rainmaker's answer. Anyhow, thanks for showing the way for handling the click event, Voted-up, thanks! – Johans Bormman Mar 30 '19 at 08:37
2

From what I understand you want to redirect user by click on the while recycler row/item. Then you need to make your parent layout of itemView clickable and focusable. You didn't provide the xml layout for itemView but I will try to explain. Your itemView is a separate xml layout file which contains images and text boxes, they all are added to the parent Linear/Constraint/Relative Layout. This parent layout needs to have clickable = true and focusable = true in order to accept click events.

The problem as we established is that the nested recycler consumes the click event. If the nested recycler is not expected to be scrollable the way to block this event is to add setLayoutFrozen(true) to the nested recycler. Tutorial link and docs

Rainmaker
  • 10,294
  • 9
  • 54
  • 89
  • Hi and thank you too for taking the time to answer my question. Please see my edited question where I have added the layout file for the `itemView`. I have added `android:focusable="false"` and `android:clickable="false"` to my `CradView` but it doesn't work either. Please take a look. – Johans Bormman Mar 29 '19 at 16:43
  • my answer suggests adding clickable TRUE and focusable TRUE as you are trying to invoke the click :) – Rainmaker Mar 29 '19 at 16:45
  • Sorry about that but I also set both to true and it doesn't work either. How you have any idea why? – Johans Bormman Mar 29 '19 at 16:47
  • I see now ,your nested recycler captures the click event , did you already try making the CHILD recycler (inside itemview) clickable false ? – Rainmaker Mar 29 '19 at 16:57
  • Yes, this is what is happening, the nested RecyclerView captures the click event. Yes I did in the first place and it doesn't work :( Do you have any other idea? – Johans Bormman Mar 29 '19 at 16:59
  • if your nested recycler is not supposed to be scrollable then you can do setLayoutFrozen(true) on the nested recycler after setting the adapter – Rainmaker Mar 29 '19 at 18:03
  • glad it helped! – Rainmaker Mar 29 '19 at 18:47
  • One more little thing, you said I should set the adapter in the activity but I do not understand why. Should I not create an adapter for each nested RecyclerView that exist within my `itemView`? Shouldn't each RecyclerView have it's own adapter? Should I use only one? Thanks in advance! – Johans Bormman Mar 30 '19 at 11:52
  • I have also asked a [question](https://stackoverflow.com/questions/55515177/how-to-set-the-adapter-for-an-inner-recyclerview-item-without-skipping-the-layou) for that. – Johans Bormman Apr 04 '19 at 11:55
  • sorry for the late response, I didn't realize it was a nested recycler, i th ink it looks fine, let me edit the answer – Rainmaker Apr 05 '19 at 22:28
0

If it is a static activity and it won't change over time you can make something like this, Otherwise use an interface.

class UserViewHolder extends RecyclerView.ViewHolder {
View itemView;
RecyclerView recyclerView;

UserViewHolder(View itemView) {
    super(itemView);
    this.itemView = itemView;
    recyclerView = itemView.findViewById(R.id.recycler_view);
}

void bind(User user) {
    itemView.setOnClickListener(view -> {
        view?.context?.startActivity(Intent(view?.context, YourDestinationActivity::class.java))
    // this is kotlin code just parse it to java 
    });

    UserAdapter adapter = new UserAdapter(user.list);
    recyclerView.setAdapter(adapter);

    itemView.bringToFront(); //Doesn't work!!!
}
Juan Hurtado
  • 358
  • 1
  • 7
  • Hi Juan Hurtado! The problem isn't the redirect part, the problem is that I cannot click on the `RecyclerView`. See my comments from Ionut J. Bejan's answer. – Johans Bormman Mar 29 '19 at 09:36