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