Reputation: 17614
Can anyone explain when exactly View.drawableStateChanged is called? I want to use it in conjunction with ViewGroup.setAddStatesFromChildren to make a complete ViewGroup
"optically" focused, meaning e.g. change background color when e.g. an EditText
of this ViewGroup
gets focus.
When I implement View.drawableStateChanged
it's called very often, how do I know that the current call is the one I care about? What's the advantage over settings focus listeners on the child Views?
Upvotes: 3
Views: 546
Reputation: 86
to make it simple, you want your whole Viewgroup
be focused when one of its children is actually focused for that you only need ViewGroup.setAddStatesFromChildren
create a drawable
file i call it view_focus in my code :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_focused="true">
<shape android:shape="rectangle">
<solid android:color="@color/white"/>
<corners android:radius="19dp"/>
<stroke android:color="@color/green" android:width="2dp"/>
</shape>
</item>
<item android:state_enabled="true" android:state_focused="false">
<shape android:shape="rectangle">
<solid android:color="@color/white"/>
<corners android:radius="19dp"/>
<stroke android:color="@color/black" android:width="2dp"/>
</shape>
</item>
</selector>
now in your activity layout you have to pass the above drawable as a background both in your Viewgroup and its children like the following :
<RelativeLayout
android:background="@drawable/view_focus"
android:layout_centerInParent="true"
android:id="@+id/parentlayout"
android:layout_width="300dp"
android:layout_height="250dp">
<EditText
android:padding="5dp"
android:textSize="20sp"
android:layout_centerInParent="true"
android:background="@drawable/view_focus"
android:id="@+id/edit"
android:layout_width="200dp"
android:layout_height="wrap_content"/>
<EditText
android:padding="5dp"
android:textSize="20sp"
android:layout_centerInParent="true"
android:background="@drawable/view_focus"
android:layout_below="@+id/edit"
android:layout_marginTop="20dp"
android:layout_width="200dp"
android:layout_height="wrap_content"/>
</RelativeLayout>
in this case RelativeLayout
parentlayout is the Viewgroup
and it's children are the two EditText
if you execute this code only the children will gain Focus
once clicked, if you want your whole ViewGroup gain Focus your need to add this line in your Activity Class file :
relativeLayout = findViewById(R.id.parentlayout);
relativeLayout.setAddStatesFromChildren(true);
this is the result after using the above line.
(source: fbcdn.net)
and this before using ViewGroup.setAddStatesFromChildren
(source: fbcdn.net)
Upvotes: 0
Reputation: 1815
You can learn more about it here.
View.drawableStateChanged()
is called whenever the state of the view changes in such a way that it impacts the state of drawables being shown.
If you create drawable like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="#ffff0000"/>
<item android:state_focused="true"
android:color="#ff0000ff"/>
<item android:state_enabled="true"
android:color="#ff00ffff"/>
<item android:color="#ff000000"/>
</selector>
This drawable has mainly different states(like state_pressed
, state_focused
, state_enabled
). If you have set drawable to a particular view and that view is clickable then when you click on of that view, this state generally changes.
You can use setOnFocusChangeListener
to check about focus changes and setOnTouchListener
touch events.
Also, you can check to enable/disable the state onClick()
event of that view.
Update: This method is deprecated, please follow this link for more.
Upvotes: 5
Reputation: 4448
From reading through the documentation which states:
This function is called whenever the state of the view changes in
such a way that it impacts the state of drawables being shown.
It seems that this function will be called by the framework whenever the component needs to be redrawn and you can override it to (for example) perform so application specific logic which you need to do when the component is redrawn, like manually drawing something over the top of the component, or changing the font or doing something which is not possible using the stock attributes.
This question has an example of how you might implement it.
Upvotes: 0