1ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam/*
2ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * Copyright (C) 2017 The Android Open Source Project
3ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam *
4ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * Licensed under the Apache License, Version 2.0 (the "License");
5ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * you may not use this file except in compliance with the License.
6ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * You may obtain a copy of the License at
7ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam *
8ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam *      http://www.apache.org/licenses/LICENSE-2.0
9ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam *
10ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * Unless required by applicable law or agreed to in writing, software
11ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * distributed under the License is distributed on an "AS IS" BASIS,
12ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * See the License for the specific language governing permissions and
14ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * limitations under the License.
15ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam */
16ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
17ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lampackage com.android.setupwizardlib.items;
18ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
19ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.content.Context;
20ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.content.res.ColorStateList;
21ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.content.res.TypedArray;
22ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.graphics.PorterDuff.Mode;
23ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.graphics.drawable.Drawable;
24ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.os.Build.VERSION;
25ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.os.Build.VERSION_CODES;
26ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.util.AttributeSet;
27ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.view.View;
28ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.view.View.OnClickListener;
29ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.widget.CompoundButton.OnCheckedChangeListener;
30ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport android.widget.TextView;
31ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
32ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport com.android.setupwizardlib.R;
33ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lamimport com.android.setupwizardlib.view.CheckableLinearLayout;
34ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
35ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam/**
36ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * A switch item which is divided into two parts: the start (left for LTR) side shows the title and
37ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * summary, and when that is clicked, will expand to show a longer summary. The end (right for LTR)
38ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * side is a switch which can be toggled by the user.
39ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam *
40ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * Note: It is highly recommended to use this item with recycler view rather than list view, because
41ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * list view draws the touch ripple effect on top of the item, rather than letting the item handle
42ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * it. Therefore you might see a double-ripple, one for the expandable area and one for the entire
43ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam * list item, when using this in list view.
44ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam */
45ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lampublic class ExpandableSwitchItem extends SwitchItem
46ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        implements OnCheckedChangeListener, OnClickListener {
47ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
48ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    private CharSequence mCollapsedSummary;
49ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    private CharSequence mExpandedSummary;
50ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    private boolean mIsExpanded = false;
51ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
52ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public ExpandableSwitchItem() {
53ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        super();
54ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
55ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
56ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public ExpandableSwitchItem(Context context, AttributeSet attrs) {
57ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        super(context, attrs);
58ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        final TypedArray a =
59ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam                context.obtainStyledAttributes(attrs, R.styleable.SuwExpandableSwitchItem);
60ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        mCollapsedSummary = a.getText(R.styleable.SuwExpandableSwitchItem_suwCollapsedSummary);
61ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        mExpandedSummary = a.getText(R.styleable.SuwExpandableSwitchItem_suwExpandedSummary);
62ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        a.recycle();
63ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
64ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
65ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    @Override
66ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    protected int getDefaultLayoutResource() {
67ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        return R.layout.suw_items_expandable_switch;
68ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
69ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
70ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    @Override
71ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public CharSequence getSummary() {
72ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        return mIsExpanded ? getExpandedSummary() : getCollapsedSummary();
73ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
74ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
75ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    /**
76ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     * @return True if the item is currently expanded.
77ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     */
78ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public boolean isExpanded() {
79ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        return mIsExpanded;
80ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
81ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
82ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    /**
83ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     * Sets whether the item should be expanded.
84ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     */
85ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public void setExpanded(boolean expanded) {
86ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        if (mIsExpanded == expanded) {
87ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam            return;
88ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        }
89ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        mIsExpanded = expanded;
90ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        notifyItemChanged();
91ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
92ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
93ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    /**
94ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     * @return The summary shown when in collapsed state.
95ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     */
96ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public CharSequence getCollapsedSummary() {
97ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        return mCollapsedSummary;
98ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
99ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
100ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    /**
101ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     * Sets the summary text shown when the item is collapsed. Corresponds to the
102ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     * {@code app:suwCollapsedSummary} XML attribute.
103ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     */
104ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public void setCollapsedSummary(CharSequence collapsedSummary) {
105ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        mCollapsedSummary = collapsedSummary;
106ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        if (!isExpanded()) {
107ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam            notifyChanged();
108ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        }
109ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
110ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
111ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    /**
112ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     * @return The summary shown when in expanded state.
113ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     */
114ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public CharSequence getExpandedSummary() {
115ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        return mExpandedSummary;
116ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
117ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
118ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    /**
119ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     * Sets the summary text shown when the item is expanded. Corresponds to the
120ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     * {@code app:suwExpandedSummary} XML attribute.
121ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam     */
122ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public void setExpandedSummary(CharSequence expandedSummary) {
123ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        mExpandedSummary = expandedSummary;
124ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        if (isExpanded()) {
125ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam            notifyChanged();
126ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        }
127ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
128ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
129ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    @Override
130ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public void onBindView(View view) {
131ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        // TODO: If it is possible to detect, log a warning if this is being used with ListView.
132ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        super.onBindView(view);
133ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        View content = view.findViewById(R.id.suw_items_expandable_switch_content);
134ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        content.setOnClickListener(this);
135ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
136ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        if (content instanceof CheckableLinearLayout) {
137ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam            ((CheckableLinearLayout) content).setChecked(isExpanded());
138ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        }
139ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
140ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        tintCompoundDrawables(view);
141ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
142ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
143ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    @Override
144ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    public void onClick(View v) {
145ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        setExpanded(!isExpanded());
146ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
147ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
148ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    // Tint the expand arrow with the text color
149ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    private void tintCompoundDrawables(View view) {
150ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        final TypedArray a = view.getContext()
151ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam                .obtainStyledAttributes(new int[] {android.R.attr.textColorPrimary});
152ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        final ColorStateList tintColor = a.getColorStateList(0);
153ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        a.recycle();
154ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
155ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        if (tintColor != null) {
156ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam            TextView titleView = (TextView) view.findViewById(R.id.suw_items_title);
157ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam            for (Drawable drawable : titleView.getCompoundDrawables()) {
158ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam                if (drawable != null) {
159ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam                    drawable.setColorFilter(tintColor.getDefaultColor(), Mode.SRC_IN);
160ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam                }
161ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam            }
162ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam            if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1) {
163ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam                for (Drawable drawable : titleView.getCompoundDrawablesRelative()) {
164ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam                    if (drawable != null) {
165ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam                        drawable.setColorFilter(tintColor.getDefaultColor(), Mode.SRC_IN);
166ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam                    }
167ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam                }
168ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam            }
169ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam
170ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam        }
171ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam    }
172ee2a6a670db446954ee9d532a4a9c565164539ecMaurice Lam}
173