Apply an Android selector to a specific child of the list and disable the selector on other children in the same list item

I have a list view with elements that contain two views (this ListView looks like a GridView with 2 columns). I need a header and footer and they are not available in the GridView , so I switched to using the list view.

I want the selector for a separate child view of each list item, the list selector does not work, it applies the selector to both child views.

What have I tried so far ????

I make the root view of each individual element a FrameLayout , and I use the android:foreground="@drawable/some_selector" attribute android:foreground="@drawable/some_selector" so that I can mimic the drawSelectorOnTop attribute.

My problem:

How to apply a selector only to a pressed child in a list item.

list of view types

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/episode_list" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="@android:color/black" android:dividerHeight="5dp" android:listSelector="@null" android:descendantFocusability="afterDescendants" /> </RelativeLayout> 

episode

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:foreground="@drawable/all_show_cell_background_selector" > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/llEpisode" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#282828" android:paddingBottom="5dp" > <ImageView android:id="@+id/episodeImage" android:layout_width="160dp" android:layout_height="90dp" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_gravity="center_vertical|center_horizontal" android:adjustViewBounds="true" android:contentDescription="@string/app_name" android:scaleType="centerCrop" android:src="@drawable/video_blank" /> <TextView android:id="@+id/episodeDuration" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@id/episodeImage" android:layout_alignLeft="@id/episodeImage" android:background="@android:color/black" android:gravity="right" android:padding="2dp" android:textColor="#FFFFFF" android:textSize="11sp" /> <!-- android:textColor="#b5b4b4" --> <TextView android:layout_marginTop="2dp" android:id="@+id/episodeTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/episodeImage" android:gravity="right" android:paddingRight="5dp" android:singleLine="true" android:text="hdgsagafasfsdafsdfsdfasddfsad" android:textColor="#ffffff" android:textSize="14sp" > </TextView> <TextView android:id="@+id/showName" android:layout_marginTop="2dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/episodeTitle" android:clickable="true" android:gravity="right" android:paddingRight="5dp" android:text="hdgsagafasfsdafsdfsdfasddfsad" android:textColor="#A8A8A8" android:textSize="13sp" > </TextView> <TextView android:layout_marginTop="2dp" android:id="@+id/noOfViewsText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@+id/showName" android:layout_alignParentBottom="true" android:gravity="right" android:paddingRight="5dp" android:text="@string/number_of_views_text" android:textColor="#A8A8A8" android:textSize="11sp" /> <TextView android:id="@+id/episodeNumberOfViews" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/noOfViewsText" android:layout_toLeftOf="@+id/noOfViewsText" android:layout_toRightOf="@+id/fav_img" android:ellipsize="none" android:gravity="right" android:paddingRight="5dp" android:singleLine="true" android:text="fsdafasdfsad" android:textColor="#A8A8A8" android:textSize="11sp" /> <ImageView android:id="@+id/fav_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/episodeNumberOfViews" android:layout_alignParentLeft="true" android:layout_marginLeft="4dp" android:contentDescription="@string/favourite_title_show" android:src="@drawable/fav_episode" /> </RelativeLayout> </FrameLayout> 

a single list item contains 2 episodes

this is a container containing two episodes

  <?xml version="1.0" encoding="utf-8"?> <!-- This container to help emulate a GridView in each ListView item --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="afterDescendants" android:orientation="horizontal" > </LinearLayout> 
+4
source share
4 answers

I have run into this problem before and have a good solution looking here for sample code

+2
source

I'm not sure about the foreground, but what I'm actually doing is using listview. then in the adapter I set two relative layouts for each line in the list, here are my list attributes:

 <ListView android:id="@+id/seccion_list" android:layout_height="wrap_content" android:layout_width="fill_parent" android:divider="@null" android:dividerHeight="0dp"/> 

in my adapter, I set the layout for loading for each line, here is the first relative layout for the first frame in the line:

  <RelativeLayout android:id="@+id/primerContenedor" android:layout_width="wrap_content" android:layout_height="@dimen/seccion_3_imagen_height" android:layout_marginLeft="3dip" android:layout_marginRight="3dip" android:layout_marginTop="5dip" android:layout_weight="1" android:clickable="true" android:focusable="true" android:background="@drawable/layout_selector"> 

so bassist that what I'm doing is to set the relative clickable attribute and the custom attributes true and define a selector:

  <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" android:drawable="@color/blue"/> <item android:state_pressed="true" android:drawable="@color/blue"/> <item android:drawable="@color/grey" /> </selector> 
+4
source

Set @android:listSelector="@null" for your list. Then set the selectors for the individual child representations of the list item.

Also set android:descendantFocusability="afterDescendants" in the list item and set android:duplicateParentState="false" in the episode.

+2
source

I assume that you are using a ListView adapter in which you inflate your own layout with two FrameLayouts with different identifiers for the left and right layouts. If not, this is one solution.

Inside the ListView adapter, add a global int selectedRowId = -1 and short leftRight = -1 (0 means left, 1 means right). In your getView method, when creating a convertView, check if postition == selectedRowId exists. If so, check to see if 0 or 1 remains, which gives you the item you selected, and you can manipulate it. Then add an onClickListener for each FrameLayout in which the RowId = position, leftRight = 0 or 1 repository is selected based on the selection and call notifyDataSetChanged ().

0
source

Source: https://habr.com/ru/post/1441422/


All Articles