GlifRecyclerLayout.java revision 180360409c9e4e9163c670ff48663244b4057eaf
1b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam/* 2b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * Copyright (C) 2015 The Android Open Source Project 3b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * 4b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * Licensed under the Apache License, Version 2.0 (the "License"); 5b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * you may not use this file except in compliance with the License. 6b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * You may obtain a copy of the License at 7b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * 8b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * http://www.apache.org/licenses/LICENSE-2.0 9b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * 10b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * Unless required by applicable law or agreed to in writing, software 11b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * distributed under the License is distributed on an "AS IS" BASIS, 12b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * See the License for the specific language governing permissions and 14b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * limitations under the License. 15b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam */ 16b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 17b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lampackage com.android.setupwizardlib; 18b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 19b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.annotation.TargetApi; 20b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.content.Context; 21b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.content.res.TypedArray; 22180360409c9e4e9163c670ff48663244b4057eafMaurice Lamimport android.graphics.drawable.Drawable; 23180360409c9e4e9163c670ff48663244b4057eafMaurice Lamimport android.os.Build; 24b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.os.Build.VERSION_CODES; 25b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.support.v7.widget.LinearLayoutManager; 26b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.support.v7.widget.RecyclerView; 27b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.util.AttributeSet; 28b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.view.LayoutInflater; 29b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.view.View; 30b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.view.ViewGroup; 31b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.widget.ImageView; 32b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport android.widget.TextView; 33b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 34b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport com.android.setupwizardlib.items.ItemGroup; 35b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport com.android.setupwizardlib.items.ItemInflater; 36b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport com.android.setupwizardlib.items.RecyclerItemAdapter; 37180360409c9e4e9163c670ff48663244b4057eafMaurice Lamimport com.android.setupwizardlib.util.DrawableLayoutDirectionHelper; 38b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lamimport com.android.setupwizardlib.view.HeaderRecyclerView; 39b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 40b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam/** 41b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * A GLIF themed layout with a RecyclerView. {@code android:entries} can also be used to specify an 42b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam * {@link com.android.setupwizardlib.items.ItemHierarchy} to be used with this layout in XML. 43b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam */ 44b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lampublic class GlifRecyclerLayout extends GlifLayout { 45b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 46b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam private RecyclerView mRecyclerView; 47b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam private TextView mHeaderTextView; 48b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam private ImageView mIconView; 49180360409c9e4e9163c670ff48663244b4057eafMaurice Lam private DividerItemDecoration mDividerDecoration; 50180360409c9e4e9163c670ff48663244b4057eafMaurice Lam private Drawable mDefaultDivider; 51180360409c9e4e9163c670ff48663244b4057eafMaurice Lam private Drawable mDivider; 52180360409c9e4e9163c670ff48663244b4057eafMaurice Lam private int mDividerInset; 53b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 54b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public GlifRecyclerLayout(Context context) { 55b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam this(context, 0, 0); 56b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 57b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 58b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public GlifRecyclerLayout(Context context, int template) { 59b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam this(context, template, 0); 60b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 61b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 62b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public GlifRecyclerLayout(Context context, int template, int containerId) { 63b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam super(context, template, containerId); 64b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam init(context, null, 0); 65b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 66b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 67b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public GlifRecyclerLayout(Context context, AttributeSet attrs) { 68b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam super(context, attrs); 69b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam init(context, attrs, 0); 70b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 71b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 72b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @TargetApi(VERSION_CODES.HONEYCOMB) 73b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public GlifRecyclerLayout(Context context, AttributeSet attrs, int defStyleAttr) { 74b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam super(context, attrs, defStyleAttr); 75b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam init(context, attrs, defStyleAttr); 76b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 77b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 78b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam private void init(Context context, AttributeSet attrs, int defStyleAttr) { 79b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam final TypedArray a = context.obtainStyledAttributes(attrs, 80b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam R.styleable.SuwGlifRecyclerLayout, defStyleAttr, 0); 81b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam final int xml = a.getResourceId(R.styleable.SuwGlifRecyclerLayout_android_entries, 0); 82b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (xml != 0) { 83b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam final ItemGroup inflated = (ItemGroup) new ItemInflater(context).inflate(xml); 84b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam setAdapter(new RecyclerItemAdapter(inflated)); 85b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 86180360409c9e4e9163c670ff48663244b4057eafMaurice Lam int dividerInset = 87180360409c9e4e9163c670ff48663244b4057eafMaurice Lam a.getDimensionPixelSize(R.styleable.SuwGlifRecyclerLayout_suwDividerInset, 0); 88180360409c9e4e9163c670ff48663244b4057eafMaurice Lam if (dividerInset == 0) { 89180360409c9e4e9163c670ff48663244b4057eafMaurice Lam dividerInset = getResources() 90180360409c9e4e9163c670ff48663244b4057eafMaurice Lam .getDimensionPixelSize(R.dimen.suw_items_icon_divider_inset); 91180360409c9e4e9163c670ff48663244b4057eafMaurice Lam } 92180360409c9e4e9163c670ff48663244b4057eafMaurice Lam setDividerInset(dividerInset); 93b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam a.recycle(); 94b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 95b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 96b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 97180360409c9e4e9163c670ff48663244b4057eafMaurice Lam protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 98180360409c9e4e9163c670ff48663244b4057eafMaurice Lam super.onLayout(changed, left, top, right, bottom); 99180360409c9e4e9163c670ff48663244b4057eafMaurice Lam if (mDivider == null) { 100180360409c9e4e9163c670ff48663244b4057eafMaurice Lam // Update divider in case layout direction has just been resolved 101180360409c9e4e9163c670ff48663244b4057eafMaurice Lam updateDivider(); 102180360409c9e4e9163c670ff48663244b4057eafMaurice Lam } 103180360409c9e4e9163c670ff48663244b4057eafMaurice Lam } 104180360409c9e4e9163c670ff48663244b4057eafMaurice Lam 105180360409c9e4e9163c670ff48663244b4057eafMaurice Lam @Override 106b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam protected View onInflateTemplate(LayoutInflater inflater, int template) { 107b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (template == 0) { 108b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam template = R.layout.suw_glif_recycler_template; 109b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 110b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return super.onInflateTemplate(inflater, template); 111b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 112b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 113b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 114b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam protected ViewGroup findContainer(int containerId) { 115b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (containerId == 0) { 116b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam containerId = R.id.suw_recycler_view; 117b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 118b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return super.findContainer(containerId); 119b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 120b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 121b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 122b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam protected void onTemplateInflated() { 123180360409c9e4e9163c670ff48663244b4057eafMaurice Lam final Context context = getContext(); 124b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam mRecyclerView = (RecyclerView) findViewById(R.id.suw_recycler_view); 125180360409c9e4e9163c670ff48663244b4057eafMaurice Lam mRecyclerView.setLayoutManager(new LinearLayoutManager(context)); 126b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam if (mRecyclerView instanceof HeaderRecyclerView) { 127b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam final View header = ((HeaderRecyclerView) mRecyclerView).getHeader(); 128b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam mHeaderTextView = (TextView) header.findViewById(R.id.suw_layout_title); 129b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam mIconView = (ImageView) header.findViewById(R.id.suw_layout_icon); 130b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 131180360409c9e4e9163c670ff48663244b4057eafMaurice Lam mDividerDecoration = DividerItemDecoration.getDefault(context); 132180360409c9e4e9163c670ff48663244b4057eafMaurice Lam mRecyclerView.addItemDecoration(mDividerDecoration); 133b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 134b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 135b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 136b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam protected TextView getHeaderTextView() { 137b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return mHeaderTextView; 138b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 139b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 140b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam @Override 141b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam protected ImageView getIconView() { 142b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return mIconView; 143b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 144b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 145b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public RecyclerView getRecyclerView() { 146b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return mRecyclerView; 147b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 148b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 149b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public void setAdapter(RecyclerView.Adapter adapter) { 150b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam getRecyclerView().setAdapter(adapter); 151b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 152b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam 153b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam public RecyclerView.Adapter getAdapter() { 154b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam return getRecyclerView().getAdapter(); 155b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam } 156180360409c9e4e9163c670ff48663244b4057eafMaurice Lam 157180360409c9e4e9163c670ff48663244b4057eafMaurice Lam /** 158180360409c9e4e9163c670ff48663244b4057eafMaurice Lam * Sets the start inset of the divider. This will use the default divider drawable set in the 159180360409c9e4e9163c670ff48663244b4057eafMaurice Lam * theme and inset it {@code inset} pixels to the right (or left in RTL layouts). 160180360409c9e4e9163c670ff48663244b4057eafMaurice Lam * 161180360409c9e4e9163c670ff48663244b4057eafMaurice Lam * @param inset The number of pixels to inset on the "start" side of the list divider. Typically 162180360409c9e4e9163c670ff48663244b4057eafMaurice Lam * this will be either {@code @dimen/suw_items_icon_divider_inset} or 163180360409c9e4e9163c670ff48663244b4057eafMaurice Lam * {@code @dimen/suw_items_text_divider_inset}. 164180360409c9e4e9163c670ff48663244b4057eafMaurice Lam */ 165180360409c9e4e9163c670ff48663244b4057eafMaurice Lam public void setDividerInset(int inset) { 166180360409c9e4e9163c670ff48663244b4057eafMaurice Lam mDividerInset = inset; 167180360409c9e4e9163c670ff48663244b4057eafMaurice Lam updateDivider(); 168180360409c9e4e9163c670ff48663244b4057eafMaurice Lam } 169180360409c9e4e9163c670ff48663244b4057eafMaurice Lam 170180360409c9e4e9163c670ff48663244b4057eafMaurice Lam public int getDividerInset() { 171180360409c9e4e9163c670ff48663244b4057eafMaurice Lam return mDividerInset; 172180360409c9e4e9163c670ff48663244b4057eafMaurice Lam } 173180360409c9e4e9163c670ff48663244b4057eafMaurice Lam 174180360409c9e4e9163c670ff48663244b4057eafMaurice Lam private void updateDivider() { 175180360409c9e4e9163c670ff48663244b4057eafMaurice Lam boolean shouldUpdate = true; 176180360409c9e4e9163c670ff48663244b4057eafMaurice Lam if (Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT) { 177180360409c9e4e9163c670ff48663244b4057eafMaurice Lam shouldUpdate = isLayoutDirectionResolved(); 178180360409c9e4e9163c670ff48663244b4057eafMaurice Lam } 179180360409c9e4e9163c670ff48663244b4057eafMaurice Lam if (shouldUpdate) { 180180360409c9e4e9163c670ff48663244b4057eafMaurice Lam if (mDefaultDivider == null) { 181180360409c9e4e9163c670ff48663244b4057eafMaurice Lam mDefaultDivider = mDividerDecoration.getDivider(); 182180360409c9e4e9163c670ff48663244b4057eafMaurice Lam } 183180360409c9e4e9163c670ff48663244b4057eafMaurice Lam mDivider = DrawableLayoutDirectionHelper.createRelativeInsetDrawable(mDefaultDivider, 184180360409c9e4e9163c670ff48663244b4057eafMaurice Lam mDividerInset /* start */, 0 /* top */, 0 /* end */, 0 /* bottom */, this); 185180360409c9e4e9163c670ff48663244b4057eafMaurice Lam mDividerDecoration.setDivider(mDivider); 186180360409c9e4e9163c670ff48663244b4057eafMaurice Lam } 187180360409c9e4e9163c670ff48663244b4057eafMaurice Lam } 188180360409c9e4e9163c670ff48663244b4057eafMaurice Lam 189180360409c9e4e9163c670ff48663244b4057eafMaurice Lam public Drawable getDivider() { 190180360409c9e4e9163c670ff48663244b4057eafMaurice Lam return mDivider; 191180360409c9e4e9163c670ff48663244b4057eafMaurice Lam } 192b01f3ef075d501d1f61e6f61794a5cadd3ff2026Maurice Lam} 193