Search code examples
androidandroid-layoutandroid-recyclerviewandroid-imageviewandroid-viewholder

Selector state pressed doesn't seem to be working


I have a RecyclerView that has a ImageView as it's ViewHolder. I'd like to add a white border around the ImageView that I clicked on. Since all those states are pretty confusing (pressed, selected, focused), all of them could mean the same thing, I'd like to ask for this specific case..

This is the adapter's ViewHolder xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_margin="10dp"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<com.myproject.RoundRectCornerImageView
    android:id="@+id/imageHolder"
    android:layout_width="56dp"
    android:layout_height="56dp"
    android:background="@drawable/image_details_selector"
    android:clickable="true"
    android:scaleType="centerCrop"
    android:src="@drawable/thumbnail"
    android:focusable="true" />

And this is the selector I'm using:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:state_selected="true">
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
        <stroke android:width="4dp" android:color="#fff" />
        <padding android:bottom="1dp" android:left="1dp" android:right="1dp" android:top="1dp" />
    </shape>
</item>

<item android:state_pressed="false" android:state_selected="false">
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
        <stroke android:width="1dp" android:color="@android:color/transparent" />
        <padding android:bottom="1dp" android:left="1dp" android:right="1dp" android:top="1dp" />
    </shape>

</item>

So what I want to do here is, have a list of images in horizontal RecyclerView and if I click on one of those images, it will get this white border around itself, all the other ImageViews won't. I implemented onClick listener that loads the image in the background and it's working, but I can't get this selector to work like I want. Any ideas?


Solution

  • First, you have to set your selector like this:

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true">
        <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
            <stroke android:width="4dp" android:color="#fff" />
            <padding android:bottom="1dp" android:left="1dp" android:right="1dp" android:top="1dp" />
        </shape>
    </item>
    
    <item android:state_selected="false">
        <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
            <stroke android:width="1dp" android:color="@android:color/transparent" />
            <padding android:bottom="1dp" android:left="1dp" android:right="1dp" android:top="1dp" />
        </shape>
    
    </item>
    

    Only selected will work in this case. Then you have to set the selection manually in your adapter's getView() method, like this:

    ImageView iv = (ImageView) findViewById(R.id.image_view);
        iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(lastImageView != null)
                    lastImageView.setSelected(false);
                lastImageView = (ImageView) view;
                lastImageView.setSelected(true);
            }
        });
    

    And set this on the adapter as Global

    private ImageView lastImageView = null;