1e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam/*
2e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * Copyright (C) 2015 The Android Open Source Project
3e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam *
4e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * Licensed under the Apache License, Version 2.0 (the "License");
5e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * you may not use this file except in compliance with the License.
6e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * You may obtain a copy of the License at
7e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam *
8e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam *      http://www.apache.org/licenses/LICENSE-2.0
9e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam *
10e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * Unless required by applicable law or agreed to in writing, software
11e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * distributed under the License is distributed on an "AS IS" BASIS,
12e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * See the License for the specific language governing permissions and
14e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * limitations under the License.
15e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam */
16e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
17e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lampackage com.android.setupwizardlib;
18e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
19e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport android.annotation.TargetApi;
20e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport android.content.Context;
21e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport android.content.res.TypedArray;
22180360409c9e4e9163c670ff48663244b4057eafMaurice Lamimport android.graphics.drawable.Drawable;
23180360409c9e4e9163c670ff48663244b4057eafMaurice Lamimport android.os.Build;
24e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport android.os.Build.VERSION_CODES;
25e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport android.util.AttributeSet;
26e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport android.view.LayoutInflater;
27e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport android.view.View;
28e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport android.view.ViewGroup;
295a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lamimport android.widget.HeaderViewListAdapter;
30e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport android.widget.ListAdapter;
31e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport android.widget.ListView;
32e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
33e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport com.android.setupwizardlib.items.ItemAdapter;
34e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport com.android.setupwizardlib.items.ItemGroup;
35e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lamimport com.android.setupwizardlib.items.ItemInflater;
36180360409c9e4e9163c670ff48663244b4057eafMaurice Lamimport com.android.setupwizardlib.util.DrawableLayoutDirectionHelper;
37e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
38e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam/**
39e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * A GLIF themed layout with a ListView. {@code android:entries} can also be used to specify an
40e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam * {@link com.android.setupwizardlib.items.ItemHierarchy} to be used with this layout in XML.
41e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam */
42e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lampublic class GlifListLayout extends GlifLayout {
43e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
44180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    /* static section */
45180360409c9e4e9163c670ff48663244b4057eafMaurice Lam
46e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    private static final String TAG = "GlifListLayout";
47180360409c9e4e9163c670ff48663244b4057eafMaurice Lam
48180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    /* non-static section */
49180360409c9e4e9163c670ff48663244b4057eafMaurice Lam
50e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    private ListView mListView;
51180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    private Drawable mDivider;
52180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    private Drawable mDefaultDivider;
53180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    private int mDividerInset;
54e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
55e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    public GlifListLayout(Context context) {
56e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        this(context, 0, 0);
57e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
58e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
59e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    public GlifListLayout(Context context, int template) {
60e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        this(context, template, 0);
61e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
62e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
63e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    public GlifListLayout(Context context, int template, int containerId) {
64e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        super(context, template, containerId);
65e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        init(context, null, 0);
66e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
67e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
68e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    public GlifListLayout(Context context, AttributeSet attrs) {
69e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        super(context, attrs);
70e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        init(context, attrs, 0);
71e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
72e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
73e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    @TargetApi(VERSION_CODES.HONEYCOMB)
74e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    public GlifListLayout(Context context, AttributeSet attrs, int defStyleAttr) {
75e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        super(context, attrs, defStyleAttr);
76e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        init(context, attrs, defStyleAttr);
77e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
78e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
79e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
80e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SuwGlifListLayout,
81e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam                defStyleAttr, 0);
82e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        final int xml = a.getResourceId(R.styleable.SuwGlifListLayout_android_entries, 0);
83e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        if (xml != 0) {
84e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam            final ItemGroup inflated = (ItemGroup) new ItemInflater(context).inflate(xml);
85e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam            setAdapter(new ItemAdapter(inflated));
86e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        }
87180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        int dividerInset =
88180360409c9e4e9163c670ff48663244b4057eafMaurice Lam                a.getDimensionPixelSize(R.styleable.SuwGlifListLayout_suwDividerInset, 0);
89180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        if (dividerInset == 0) {
90180360409c9e4e9163c670ff48663244b4057eafMaurice Lam            dividerInset = getResources()
9115391fc05a0fc45e9af85b653abffa41df575e91Maurice Lam                    .getDimensionPixelSize(R.dimen.suw_items_glif_icon_divider_inset);
92180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        }
93180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        setDividerInset(dividerInset);
94e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        a.recycle();
95e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
96e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
97e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    @Override
98180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
99180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        super.onLayout(changed, left, top, right, bottom);
100180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        if (mDivider == null) {
101180360409c9e4e9163c670ff48663244b4057eafMaurice Lam            // Update divider in case layout direction has just been resolved
102180360409c9e4e9163c670ff48663244b4057eafMaurice Lam            updateDivider();
103180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        }
104180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    }
105180360409c9e4e9163c670ff48663244b4057eafMaurice Lam
106180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    @Override
107e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    protected View onInflateTemplate(LayoutInflater inflater, int template) {
108e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        if (template == 0) {
109e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam            template = R.layout.suw_glif_list_template;
110e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        }
111e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        return super.onInflateTemplate(inflater, template);
112e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
113e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
114e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    @Override
115e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    protected ViewGroup findContainer(int containerId) {
116e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        if (containerId == 0) {
117e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam            containerId = android.R.id.list;
118e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        }
119e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        return super.findContainer(containerId);
120e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
121e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
122e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    @Override
123e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    protected void onTemplateInflated() {
124e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        mListView = (ListView) findViewById(android.R.id.list);
125e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
126e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
127e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    public ListView getListView() {
128e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        return mListView;
129e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
130e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
131e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    public void setAdapter(ListAdapter adapter) {
132e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam        getListView().setAdapter(adapter);
133e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
134e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam
135e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    public ListAdapter getAdapter() {
1365a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam        final ListAdapter adapter = getListView().getAdapter();
1375a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam        if (adapter instanceof HeaderViewListAdapter) {
1385a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam            return ((HeaderViewListAdapter) adapter).getWrappedAdapter();
1395a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam        }
1405a4d6cdfb63240c41527ba80b7baddba8933d770Maurice Lam        return adapter;
141e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam    }
142180360409c9e4e9163c670ff48663244b4057eafMaurice Lam
143180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    /**
144180360409c9e4e9163c670ff48663244b4057eafMaurice Lam     * Sets the start inset of the divider. This will use the default divider drawable set in the
145180360409c9e4e9163c670ff48663244b4057eafMaurice Lam     * theme and inset it {@code inset} pixels to the right (or left in RTL layouts).
146180360409c9e4e9163c670ff48663244b4057eafMaurice Lam     *
147180360409c9e4e9163c670ff48663244b4057eafMaurice Lam     * @param inset The number of pixels to inset on the "start" side of the list divider. Typically
14815391fc05a0fc45e9af85b653abffa41df575e91Maurice Lam     *              this will be either {@code @dimen/suw_items_glif_icon_divider_inset} or
14915391fc05a0fc45e9af85b653abffa41df575e91Maurice Lam     *              {@code @dimen/suw_items_glif_text_divider_inset}.
150180360409c9e4e9163c670ff48663244b4057eafMaurice Lam     */
151180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    public void setDividerInset(int inset) {
152180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        mDividerInset = inset;
153180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        updateDivider();
154180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    }
155180360409c9e4e9163c670ff48663244b4057eafMaurice Lam
156180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    public int getDividerInset() {
157180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        return mDividerInset;
158180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    }
159180360409c9e4e9163c670ff48663244b4057eafMaurice Lam
160180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    private void updateDivider() {
161180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        boolean shouldUpdate = true;
162180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        if (Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT) {
163180360409c9e4e9163c670ff48663244b4057eafMaurice Lam            shouldUpdate = isLayoutDirectionResolved();
164180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        }
165180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        if (shouldUpdate) {
166180360409c9e4e9163c670ff48663244b4057eafMaurice Lam            final ListView listView = getListView();
167180360409c9e4e9163c670ff48663244b4057eafMaurice Lam            if (mDefaultDivider == null) {
168180360409c9e4e9163c670ff48663244b4057eafMaurice Lam                mDefaultDivider = listView.getDivider();
169180360409c9e4e9163c670ff48663244b4057eafMaurice Lam            }
170180360409c9e4e9163c670ff48663244b4057eafMaurice Lam            mDivider = DrawableLayoutDirectionHelper.createRelativeInsetDrawable(mDefaultDivider,
171180360409c9e4e9163c670ff48663244b4057eafMaurice Lam                    mDividerInset /* start */, 0 /* top */, 0 /* end */, 0 /* bottom */, this);
172180360409c9e4e9163c670ff48663244b4057eafMaurice Lam            listView.setDivider(mDivider);
173180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        }
174180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    }
175180360409c9e4e9163c670ff48663244b4057eafMaurice Lam
176180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    public Drawable getDivider() {
177180360409c9e4e9163c670ff48663244b4057eafMaurice Lam        return mDivider;
178180360409c9e4e9163c670ff48663244b4057eafMaurice Lam    }
179e15b8a2489610e3a6fe0a5bc2e26625b067631e0Maurice Lam}
180