1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.setupwizardlib; 18 19import android.annotation.TargetApi; 20import android.content.Context; 21import android.content.res.TypedArray; 22import android.graphics.drawable.Drawable; 23import android.os.Build; 24import android.os.Build.VERSION_CODES; 25import android.util.AttributeSet; 26import android.util.Log; 27import android.view.LayoutInflater; 28import android.view.View; 29import android.view.ViewGroup; 30import android.widget.ListAdapter; 31import android.widget.ListView; 32 33import com.android.setupwizardlib.util.DrawableLayoutDirectionHelper; 34import com.android.setupwizardlib.util.ListViewRequireScrollHelper; 35import com.android.setupwizardlib.view.NavigationBar; 36 37public class SetupWizardListLayout extends SetupWizardLayout { 38 39 private static final String TAG = "SetupWizardListLayout"; 40 private ListView mListView; 41 private Drawable mDivider; 42 private Drawable mDefaultDivider; 43 private int mDividerInset; 44 45 public SetupWizardListLayout(Context context) { 46 this(context, 0, 0); 47 } 48 49 public SetupWizardListLayout(Context context, int template) { 50 this(context, template, 0); 51 } 52 53 public SetupWizardListLayout(Context context, int template, int containerId) { 54 super(context, template, containerId); 55 init(context, null, 0); 56 } 57 58 public SetupWizardListLayout(Context context, AttributeSet attrs) { 59 super(context, attrs); 60 init(context, attrs, 0); 61 } 62 63 @TargetApi(VERSION_CODES.HONEYCOMB) 64 public SetupWizardListLayout(Context context, AttributeSet attrs, int defStyleAttr) { 65 super(context, attrs, defStyleAttr); 66 init(context, attrs, defStyleAttr); 67 } 68 69 private void init(Context context, AttributeSet attrs, int defStyleAttr) { 70 final TypedArray a = context.obtainStyledAttributes(attrs, 71 R.styleable.SuwSetupWizardListLayout, defStyleAttr, 0); 72 int dividerInset = 73 a.getDimensionPixelSize(R.styleable.SuwSetupWizardListLayout_suwDividerInset, 0); 74 setDividerInset(dividerInset); 75 a.recycle(); 76 } 77 78 @Override 79 protected View onInflateTemplate(LayoutInflater inflater, int template) { 80 if (template == 0) { 81 template = R.layout.suw_list_template; 82 } 83 return super.onInflateTemplate(inflater, template); 84 } 85 86 @Override 87 protected ViewGroup findContainer(int containerId) { 88 if (containerId == 0) { 89 containerId = android.R.id.list; 90 } 91 return super.findContainer(containerId); 92 } 93 94 @Override 95 protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 96 super.onLayout(changed, left, top, right, bottom); 97 if (mDivider == null) { 98 // Update divider in case layout direction has just been resolved 99 updateDivider(); 100 } 101 } 102 103 @Override 104 protected void onTemplateInflated() { 105 mListView = (ListView) findViewById(android.R.id.list); 106 } 107 108 public ListView getListView() { 109 return mListView; 110 } 111 112 public void setAdapter(ListAdapter adapter) { 113 getListView().setAdapter(adapter); 114 } 115 116 @Override 117 public void requireScrollToBottom() { 118 final NavigationBar navigationBar = getNavigationBar(); 119 final ListView listView = getListView(); 120 if (navigationBar != null && listView != null) { 121 ListViewRequireScrollHelper.requireScroll(navigationBar, listView); 122 } else { 123 Log.e(TAG, "Both suw_layout_navigation_bar and list must exist in" 124 + " the template to require scrolling."); 125 } 126 } 127 128 /** 129 * Sets the start inset of the divider. This will use the default divider drawable set in the 130 * theme and inset it {@code inset} pixels to the right (or left in RTL layouts). 131 * 132 * @param inset The number of pixels to inset on the "start" side of the list divider. Typically 133 * this will be either {@code @dimen/suw_items_icon_divider_inset} or 134 * {@code @dimen/suw_items_text_divider_inset}. 135 */ 136 public void setDividerInset(int inset) { 137 mDividerInset = inset; 138 updateDivider(); 139 } 140 141 public int getDividerInset() { 142 return mDividerInset; 143 } 144 145 private void updateDivider() { 146 boolean shouldUpdate = true; 147 if (Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT) { 148 shouldUpdate = isLayoutDirectionResolved(); 149 } 150 if (shouldUpdate) { 151 final ListView listView = getListView(); 152 if (mDefaultDivider == null) { 153 mDefaultDivider = listView.getDivider(); 154 } 155 mDivider = DrawableLayoutDirectionHelper.createRelativeInsetDrawable(mDefaultDivider, 156 mDividerInset /* start */, 0 /* top */, 0 /* end */, 0 /* bottom */, this); 157 listView.setDivider(mDivider); 158 } 159 } 160 161 public Drawable getDivider() { 162 return mDivider; 163 } 164} 165