Android pass parent view's 'pressed' state to child views

2.6k views Asked by At

There are many question here on SO asking for a way to prevent a child view from copying its parents pressed or selected states. However, I'm asking for the other way around here :) - I've seen a very weird behavior in one of my apps:

When running the App on a 4.0.4 device (API 15) the behavior I saw matched the apparent default, which is: The parent forwards its state down to all of its child views.

When running the same App without any changes on a higher API level (Android 4.4) this behavior changes: The parent does NOT forward its state.

I introduced duplicateParentState in the xml layout for all relevant child views, but this does not seem to help here.

Is this a known 'issue' or a planned change in behavior from API 15 to API >> 15?
How can I make sure the states are properly forwarded across all API levels?

If it is of any help / relevance here: The subview I want to duplicate its parents state is a custom ImageView which adds tintColors - Since the behavior is correct on 4.0.4 there should not be any mistakes in this class?

public class INCImageView extends ImageView {

    private int _tintColor;
    private int _highlightedTintColor;
    private int _selectedTintColor;

    public INCImageView(Context context, AttributeSet attrs) {
        super(context, attrs);

        this.setFocusable(true);
        this.setClickable(true);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.INCImageView);

        _tintColor = array.getInt(R.styleable.INCImageView_tintColor, getResources().getColor(R.color.inc_tint));
        this.setColorFilter(_tintColor);

        _selectedTintColor = array.getInt(R.styleable.INCImageView_selectedTintColor, _tintColor);
        _highlightedTintColor = array.getInt(R.styleable.INCImageView_highlightedTintColor, _tintColor);

        array.recycle();
    }

    @Override
    public void setSelected(boolean selected) {
        super.setSelected(selected);

        this.setColorFilter((selected ? _selectedTintColor : _tintColor));
    }

    @Override
    public void setPressed(boolean pressed) {
        super.setPressed(pressed);

        this.setColorFilter((pressed ? _highlightedTintColor : (this.isSelected() ? _selectedTintColor : _tintColor)));
    }
}
1

There are 1 answers

1
CodingMeSwiftly On BEST ANSWER

I found the solution:

If you have a look at the ImageView subclass above, in the constructor clickable & focusable are set to true.

Turns out this was the mistake. The parent won't forward its state when the child itself is clickable. - That still does not explain why the above code works on 4.0.4 but breaks on 4.4

Anyway, leaving the clickable & focusable = false solves the problem.