简体   繁体   中英

Android xml selector for layouts

I was wanting to know if there is a selector for layouts like there is for drawables.

Example of selector with drawable:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- When selected -->
<item android:drawable="@drawable/tab_library_clicked"
      android:state_selected="true" />
<!-- When not selected -->
<item android:drawable="@drawable/tab_library_not_clicked" />

But is it possible to have something like this (This code below didn't work for me but it should give you an idea of what I am trying to accomplish):

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- When selected -->
<item android:layout="@layout/tab_library_clicked"
      android:state_selected="true" />
<!-- When not selected -->
<item android:layout="@layout/tab_library_not_clicked" />

I might be wrong, but I'm pretty sure this doesn't exist.

The most "sophisticated" you'll be able to do with a selector in XML probably is using a drawable layer list to combine several drawables onto one state.

Alternatively you can try using the touch_down and touch_up events to programmatically call setVisibility() on the layouts, but I imagine the performance will be very poor.

Ok, what you are looking for is a way to propagate parent's state to its child views. That way whenever the indicator state changes (selected, not) the imageview state changes.

android already have an xml attribute for that.

android:duplicateParentState="true"

use this with your child views in the layout file and combine it with the selector. for example:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#f00" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="Large Text"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:duplicateParentState="true"
     />

<ImageView
    android:id="@+id/imageView1"
    android:duplicateParentState="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center_horizontal"
    android:src="@drawable/selector" />

Default Selector mechanism only provides alternatives for properties (such as drawable to use etc), depending on a view's state. It does not replace the Views themselves. The functionality you are asking for is not available.

Selected state for a View is bound to one of the values of *_STATE_SET fields in the View class. Combined state of a view is retrieved via getDrawableState() .

You can extend a View class and make use of these states to do something custom. Or, you can develop a custom layout controller, that watches state changes across the View tree and replaces child views according to an xml resource.

But the effort is not worth it because:

  1. The view/layout structure must remain the same during a user's interaction with it. You shouldn't change a button into a check-box when user selects it, replacing views/layouts like that is simply confusing UX-wise.

  2. You only need to modify the looks of a view on user interaction, which is already provided by selector based draw-ables and colors.

There's no such attribute android:layout for item in the documentation . It is supposed to be used with android:drawable .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM