23

I have a SlidingDrawer element which contains a RelativeLayout element which contains some Button child elements:

<SlidingDrawer>
  <RelativeLayout>
    <LinearLayout>
      <Button android:background="@drawable/foo.xml" android:duplicateParentState="false">
      <Button android:background="@drawable/bar.xml" android:duplicateParentState="false">
    </LinearLayout>
  </RelativeLayout>
</SlidingDrawer>

foo.xml and bar.xml have selectors which apply different images depending on the state:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_focused="true" android:drawable="@drawable/foo_selected" />
  <item android:state_pressed="true" android:drawable="@drawable/foo_selected" />
  <item android:state_enabled="false" android:drawable="@drawable/foo_disabled" />
  <item android:drawable="@drawable/foo_normal" /> 
</selector>

The problem I am seeing is that when I click on the sliding drawer handle, the pressed state gets triggered for the buttons and they look pressed too, even though I've specified duplicateParentState to false.

Raul Agrait
  • 5,938
  • 6
  • 49
  • 72
  • 1
    There is a better solution to this problem by subclassing viewgroup and overriding dispatchSetPressed. I have posted the solution on this thread http://stackoverflow.com/a/12268890/795245 – Gomino Sep 04 '12 at 17:59
  • I think my question can anwser your qustion. http://stackoverflow.com/questions/14179431/android-child-view-sharing-pressed-state-from-its-parent-view-in-jelly-bean – jinglezju Jan 06 '13 at 04:55

3 Answers3

26

Override the LinearLayout class with a subclass. In that subclass override the setPressed method and do nothing like so:

public class UnpressableLinearLayout extends LinearLayout
{
    @Override
    public void setPressed(boolean pressed)
    {
        // Do nothing here. Specifically, do not propagate this message along
        // to our children so they do not incorrectly display a pressed state
        // just because one of their ancestors got pressed.
    }
}

Replace LinearLayout with an instance of UnpressableLinearLayout.

Raul Agrait
  • 5,938
  • 6
  • 49
  • 72
  • 1
    To avoid of writing new custom layout for any other views (`RelativeLayout`, `FrameLayout`…), have a look at [my solution](http://stackoverflow.com/a/13813751/1521536), it's simpler. –  Dec 11 '12 at 04:45
12

There is no need to set duplicateParentState to false. This would happen if you make the parent clickable somehow. By default, the pressed state is propagated to the children. Make sure your LinearLayout and RelativeLayout are not clickable.

Romain Guy
  • 97,993
  • 18
  • 219
  • 200
  • Hi Romain Guy, could you document this somewhere? I got this problem yesterday and I solved this by peeking on the source code of ViewGroup. It seems that some states propagate to children and some do not. – Randy Sugianto 'Yuku' Nov 23 '11 at 06:19
  • 6
    Does this also happens on ICS? I'm having different behaviour on it. Click is not being propagated. – neteinstein Mar 23 '12 at 01:00
0

Got same situation with SeekBar.

setting for SeekBar:

 android:clickable="true"
 android:focusable="true"

worked for me

Vadim
  • 3,855
  • 2
  • 17
  • 22