[SuwLib] Support preference v14

Add SetupWizardPreferenceLayout to support Preference v14 framework.

Bug: 26994868
Change-Id: I3b7a4b57cb4df6c46fdd868357bcbdaad39f1feb
This commit is contained in:
Maurice Lam 2016-02-08 17:58:09 -08:00
parent 15391fc05a
commit 3885d8491a
18 changed files with 710 additions and 205 deletions

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.setupwizardlib.view.StickyHeaderRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/suw_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:scrollbars="vertical"
app:suwHeader="@layout/suw_list_header" />

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/suw_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/suw_layout_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.android.setupwizardlib.view.NavigationBar
android:id="@+id/suw_layout_navigation_bar"
style="@style/SuwNavBarTheme"
android:layout_width="match_parent"
android:layout_height="@dimen/suw_navbar_height" />
</LinearLayout>

View file

@ -17,6 +17,8 @@
<resources>
<item name="suw_preference_recycler_view" type="layout">@layout/suw_preference_recycler_view_normal</item>
<item name="suw_preference_template" type="layout">@layout/suw_no_scroll_template_header_collapsed</item>
<item name="suw_recycler_template" type="layout">@layout/suw_recycler_template_header_collapsed</item>
<item name="suw_recycler_template_short" type="layout">@layout/suw_recycler_template_header_collapsed</item>

View file

@ -17,6 +17,8 @@
<resources>
<item name="suw_preference_recycler_view" type="layout">@layout/suw_preference_recycler_view_normal</item>
<item name="suw_preference_template" type="layout">@layout/suw_no_scroll_template_card_wide</item>
<item name="suw_recycler_template" type="layout">@layout/suw_recycler_template_card_wide</item>
<item name="suw_recycler_template_short" type="layout">@layout/suw_recycler_template_card_wide</item>

View file

@ -17,6 +17,8 @@
<resources>
<item name="suw_preference_recycler_view" type="layout">@layout/suw_preference_recycler_view_normal</item>
<item name="suw_preference_template" type="layout">@layout/suw_no_scroll_template_card</item>
<item name="suw_recycler_template" type="layout">@layout/suw_recycler_template_card</item>
<item name="suw_recycler_template_short" type="layout">@layout/suw_recycler_template_card</item>

View file

@ -17,6 +17,8 @@
<resources>
<item name="suw_preference_recycler_view" type="layout">@layout/suw_preference_recycler_view_header</item>
<item name="suw_preference_template" type="layout">@layout/suw_preference_template_header</item>
<item name="suw_recycler_template" type="layout">@layout/suw_recycler_template_header</item>
<item name="suw_recycler_template_short" type="layout">@layout/suw_recycler_template_header_collapsed</item>

View file

@ -0,0 +1,120 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.setupwizardlib;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A layout to be used with {@code PreferenceFragment} in v14 support library. This can be specified
* as the {@code android:layout} in the {@code app:preferenceFragmentStyle} in
* {@code app:preferenceTheme}.
*
* <p />Example:
* <pre>{@code
* &lt;style android:name="MyActivityTheme">
* &lt;item android:name="preferenceTheme">@style/MyPreferenceTheme&lt;/item>
* &lt;/style>
*
* &lt;style android:name="MyPreferenceTheme">
* &lt;item android:name="preferenceFragmentStyle">@style/MyPreferenceFragmentStyle&lt;/item>
* &lt;/style>
*
* &lt;style android:name="MyPreferenceFragmentStyle">
* &lt;item android:name="android:layout">@layout/my_preference_layout&lt;/item>
* &lt;/style>
* }</pre>
*
* where {@code my_preference_layout} is a layout that contains
* {@link com.android.setupwizardlib.SetupWizardPreferenceLayout}.
*
* <p />Example:
* <pre>{@code
* &lt;com.android.setupwizardlib.SetupWizardPreferenceLayout
* xmlns:android="http://schemas.android.com/apk/res/android"
* android:id="@id/list_container"
* android:layout_width="match_parent"
* android:layout_height="match_parent" />
* }</pre>
*
* <p />Fragments using this layout <em>must</em> delegate {@code onCreateRecyclerView} to the
* implementation in this class:
* {@link #onCreateRecyclerView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)}
*/
public class SetupWizardPreferenceLayout extends SetupWizardRecyclerLayout {
private RecyclerView mRecyclerView;
public SetupWizardPreferenceLayout(Context context) {
super(context);
}
public SetupWizardPreferenceLayout(Context context, int template, int containerId) {
super(context, template, containerId);
}
public SetupWizardPreferenceLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SetupWizardPreferenceLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public RecyclerView getRecyclerView() {
return mRecyclerView;
}
@Override
protected ViewGroup findContainer(int containerId) {
if (containerId == 0) {
containerId = R.id.suw_layout_content;
}
return super.findContainer(containerId);
}
/**
* This method must be called in {@code PreferenceFragment#onCreateRecyclerView}.
*/
public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
return mRecyclerView;
}
@Override
protected View onInflateTemplate(LayoutInflater inflater, int template) {
if (template == 0) {
template = R.layout.suw_preference_template;
}
return super.onInflateTemplate(inflater, template);
}
@Override
protected void onTemplateInflated() {
// Inflate the recycler view here, so attributes on the decoration views can be applied
// immediately.
final LayoutInflater inflater = LayoutInflater.from(getContext());
mRecyclerView = (RecyclerView) inflater.inflate(R.layout.suw_preference_recycler_view,
this, false);
initRecyclerView(mRecyclerView);
}
}

View file

@ -17,193 +17,25 @@
package com.android.setupwizardlib;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.setupwizardlib.items.ItemGroup;
import com.android.setupwizardlib.items.ItemInflater;
import com.android.setupwizardlib.items.RecyclerItemAdapter;
import com.android.setupwizardlib.util.DrawableLayoutDirectionHelper;
import com.android.setupwizardlib.util.RecyclerViewRequireScrollHelper;
import com.android.setupwizardlib.view.HeaderRecyclerView;
import com.android.setupwizardlib.view.NavigationBar;
/**
* A SetupWizardLayout for use with {@link com.android.setupwizardlib.items.RecyclerItemAdapter},
* which displays a list of items using a RecyclerView. The items XML file can be specified through
* {@code android:entries} attribute in the layout.
*
* @see com.android.setupwizardlib.SetupWizardItemsLayout
* @deprecated Use {@link com.android.setupwizardlib.SetupWizardRecyclerLayout}
*/
public class SetupWizardRecyclerItemsLayout extends SetupWizardLayout {
private static final String TAG = "RecyclerItemsLayout";
private RecyclerItemAdapter mAdapter;
private RecyclerView mRecyclerView;
private TextView mHeaderTextView;
private View mDecorationView;
private DividerItemDecoration mDividerDecoration;
private Drawable mDefaultDivider;
private Drawable mDivider;
private int mDividerInset;
@Deprecated
public class SetupWizardRecyclerItemsLayout extends SetupWizardRecyclerLayout {
public SetupWizardRecyclerItemsLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public SetupWizardRecyclerItemsLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SuwSetupWizardRecyclerItemsLayout, defStyleAttr, 0);
final int xml = a.getResourceId(
R.styleable.SuwSetupWizardRecyclerItemsLayout_android_entries, 0);
if (xml != 0) {
final ItemGroup inflated = (ItemGroup) new ItemInflater(context).inflate(xml);
mAdapter = new RecyclerItemAdapter(inflated);
mAdapter.setHasStableIds(a.getBoolean(
R.styleable.SuwSetupWizardRecyclerItemsLayout_suwHasStableIds, false));
setAdapter(mAdapter);
}
int dividerInset = a.getDimensionPixelSize(
R.styleable.SuwSetupWizardRecyclerItemsLayout_suwDividerInset, 0);
if (dividerInset == 0) {
dividerInset = getResources()
.getDimensionPixelSize(R.dimen.suw_items_icon_divider_inset);
}
setDividerInset(dividerInset);
a.recycle();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mDivider == null) {
// Update divider in case layout direction has just been resolved
updateDivider();
}
}
public RecyclerItemAdapter getAdapter() {
return mAdapter;
}
public void setAdapter(RecyclerItemAdapter adapter) {
mAdapter = adapter;
getRecyclerView().setAdapter(adapter);
}
public RecyclerView getRecyclerView() {
return mRecyclerView;
}
@Override
protected ViewGroup findContainer(int containerId) {
if (containerId == 0) {
containerId = R.id.suw_recycler_view;
}
return super.findContainer(containerId);
}
@Override
protected void onTemplateInflated() {
mRecyclerView = (RecyclerView) findViewById(R.id.suw_recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
if (mRecyclerView instanceof HeaderRecyclerView) {
final View header = ((HeaderRecyclerView) mRecyclerView).getHeader();
mHeaderTextView = (TextView) header.findViewById(R.id.suw_layout_title);
mDecorationView = header.findViewById(R.id.suw_layout_decor);
}
mDividerDecoration = DividerItemDecoration.getDefault(getContext());
mRecyclerView.addItemDecoration(mDividerDecoration);
}
@Override
protected View onInflateTemplate(LayoutInflater inflater, int template) {
if (template == 0) {
template = R.layout.suw_recycler_template;
}
return super.onInflateTemplate(inflater, template);
}
@Override
protected TextView getHeaderTextView() {
if (mHeaderTextView != null) {
return mHeaderTextView;
} else {
return super.getHeaderTextView();
}
}
@Override
protected View getDecorationView() {
if (mDecorationView != null) {
return mDecorationView;
} else {
return super.getDecorationView();
}
}
@Override
public void requireScrollToBottom() {
final NavigationBar navigationBar = getNavigationBar();
final RecyclerView recyclerView = getRecyclerView();
if (navigationBar != null && recyclerView != null) {
RecyclerViewRequireScrollHelper.requireScroll(navigationBar, recyclerView);
} else {
Log.e(TAG, "Both suw_layout_navigation_bar and suw_recycler_view must exist in"
+ " the template to require scrolling.");
}
}
/**
* Sets the start inset of the divider. This will use the default divider drawable set in the
* theme and inset it {@code inset} pixels to the right (or left in RTL layouts).
*
* @param inset The number of pixels to inset on the "start" side of the list divider. Typically
* this will be either {@code @dimen/suw_items_icon_divider_inset} or
* {@code @dimen/suw_items_text_divider_inset}.
*/
public void setDividerInset(int inset) {
mDividerInset = inset;
updateDivider();
}
public int getDividerInset() {
return mDividerInset;
}
private void updateDivider() {
boolean shouldUpdate = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
shouldUpdate = isLayoutDirectionResolved();
}
if (shouldUpdate) {
if (mDefaultDivider == null) {
mDefaultDivider = mDividerDecoration.getDivider();
}
mDivider = DrawableLayoutDirectionHelper.createRelativeInsetDrawable(mDefaultDivider,
mDividerInset /* start */, 0 /* top */, 0 /* end */, 0 /* bottom */, this);
mDividerDecoration.setDivider(mDivider);
}
}
public Drawable getDivider() {
return mDivider;
return (RecyclerItemAdapter) super.getAdapter();
}
}

View file

@ -0,0 +1,222 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.setupwizardlib;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.setupwizardlib.items.ItemGroup;
import com.android.setupwizardlib.items.ItemInflater;
import com.android.setupwizardlib.items.RecyclerItemAdapter;
import com.android.setupwizardlib.util.DrawableLayoutDirectionHelper;
import com.android.setupwizardlib.util.RecyclerViewRequireScrollHelper;
import com.android.setupwizardlib.view.HeaderRecyclerView;
import com.android.setupwizardlib.view.NavigationBar;
/**
* A setup wizard layout for use with {@link android.support.v7.widget.RecyclerView}.
* {@code android:entries} can also be used to specify an
* {@link com.android.setupwizardlib.items.ItemHierarchy} to be used with this layout in XML.
*
* @see SetupWizardItemsLayout
*/
public class SetupWizardRecyclerLayout extends SetupWizardLayout {
private static final String TAG = "RecyclerLayout";
private RecyclerView.Adapter mAdapter;
private RecyclerView mRecyclerView;
private TextView mHeaderTextView;
private View mDecorationView;
private DividerItemDecoration mDividerDecoration;
private Drawable mDefaultDivider;
private Drawable mDivider;
private int mDividerInset;
public SetupWizardRecyclerLayout(Context context) {
this(context, 0, 0);
}
public SetupWizardRecyclerLayout(Context context, int template, int containerId) {
super(context, template, containerId);
init(context, null, 0);
}
public SetupWizardRecyclerLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public SetupWizardRecyclerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.SuwSetupWizardRecyclerItemsLayout, defStyleAttr, 0);
final int xml = a.getResourceId(
R.styleable.SuwSetupWizardRecyclerItemsLayout_android_entries, 0);
if (xml != 0) {
final ItemGroup inflated = (ItemGroup) new ItemInflater(context).inflate(xml);
mAdapter = new RecyclerItemAdapter(inflated);
mAdapter.setHasStableIds(a.getBoolean(
R.styleable.SuwSetupWizardRecyclerItemsLayout_suwHasStableIds, false));
setAdapter(mAdapter);
}
int dividerInset = a.getDimensionPixelSize(
R.styleable.SuwSetupWizardRecyclerItemsLayout_suwDividerInset, 0);
if (dividerInset == 0) {
dividerInset = getResources()
.getDimensionPixelSize(R.dimen.suw_items_icon_divider_inset);
}
setDividerInset(dividerInset);
a.recycle();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mDivider == null) {
// Update divider in case layout direction has just been resolved
updateDivider();
}
}
public RecyclerView.Adapter getAdapter() {
return mAdapter;
}
public void setAdapter(RecyclerView.Adapter adapter) {
mAdapter = adapter;
getRecyclerView().setAdapter(adapter);
}
public RecyclerView getRecyclerView() {
return mRecyclerView;
}
@Override
protected ViewGroup findContainer(int containerId) {
if (containerId == 0) {
containerId = R.id.suw_recycler_view;
}
return super.findContainer(containerId);
}
@Override
protected void onTemplateInflated() {
initRecyclerView((RecyclerView) findViewById(R.id.suw_recycler_view));
}
protected void initRecyclerView(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
if (mRecyclerView instanceof HeaderRecyclerView) {
final View header = ((HeaderRecyclerView) mRecyclerView).getHeader();
mHeaderTextView = (TextView) header.findViewById(R.id.suw_layout_title);
mDecorationView = header.findViewById(R.id.suw_layout_decor);
}
mDividerDecoration = DividerItemDecoration.getDefault(getContext());
mRecyclerView.addItemDecoration(mDividerDecoration);
}
@Override
protected View onInflateTemplate(LayoutInflater inflater, int template) {
if (template == 0) {
template = R.layout.suw_recycler_template;
}
return super.onInflateTemplate(inflater, template);
}
@Override
protected TextView getHeaderTextView() {
if (mHeaderTextView != null) {
return mHeaderTextView;
} else {
return super.getHeaderTextView();
}
}
@Override
protected View getDecorationView() {
if (mDecorationView != null) {
return mDecorationView;
} else {
return super.getDecorationView();
}
}
@Override
public void requireScrollToBottom() {
final NavigationBar navigationBar = getNavigationBar();
final RecyclerView recyclerView = getRecyclerView();
if (navigationBar != null && recyclerView != null) {
RecyclerViewRequireScrollHelper.requireScroll(navigationBar, recyclerView);
} else {
Log.e(TAG, "Both suw_layout_navigation_bar and suw_recycler_view must exist in"
+ " the template to require scrolling.");
}
}
/**
* Sets the start inset of the divider. This will use the default divider drawable set in the
* theme and inset it {@code inset} pixels to the right (or left in RTL layouts).
*
* @param inset The number of pixels to inset on the "start" side of the list divider. Typically
* this will be either {@code @dimen/suw_items_icon_divider_inset} or
* {@code @dimen/suw_items_text_divider_inset}.
*/
public void setDividerInset(int inset) {
mDividerInset = inset;
updateDivider();
}
public int getDividerInset() {
return mDividerInset;
}
private void updateDivider() {
boolean shouldUpdate = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
shouldUpdate = isLayoutDirectionResolved();
}
if (shouldUpdate) {
if (mDefaultDivider == null) {
mDefaultDivider = mDividerDecoration.getDivider();
}
mDivider = DrawableLayoutDirectionHelper.createRelativeInsetDrawable(mDefaultDivider,
mDividerInset /* start */, 0 /* top */, 0 /* end */, 0 /* bottom */, this);
mDividerDecoration.setDivider(mDivider);
}
}
public Drawable getDivider() {
return mDivider;
}
}

View file

@ -0,0 +1,20 @@
<!--
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.setupwizardlib.SetupWizardRecyclerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" />

View file

@ -0,0 +1,115 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.setupwizardlib.test;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.os.Build;
import android.support.v7.widget.RecyclerView;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.setupwizardlib.SetupWizardPreferenceLayout;
public class SetupWizardPreferenceLayoutTest extends InstrumentationTestCase {
private Context mContext;
@Override
protected void setUp() throws Exception {
super.setUp();
mContext = new ContextThemeWrapper(getInstrumentation().getContext(),
R.style.SuwThemeMaterial_Light);
}
@SmallTest
public void testDefaultTemplate() {
SetupWizardPreferenceLayout layout = new TestLayout(mContext);
assertPreferenceTemplateInflated(layout);
}
@SmallTest
public void testGetRecyclerView() {
SetupWizardPreferenceLayout layout = new TestLayout(mContext);
assertPreferenceTemplateInflated(layout);
assertNotNull("getRecyclerView should not be null", layout.getRecyclerView());
}
@SmallTest
public void testOnCreateRecyclerView() {
SetupWizardPreferenceLayout layout = new TestLayout(mContext);
assertPreferenceTemplateInflated(layout);
final RecyclerView recyclerView = layout.onCreateRecyclerView(LayoutInflater.from(mContext),
layout, null /* savedInstanceState */);
assertNotNull("RecyclerView created should not be null", recyclerView);
}
@SmallTest
public void testDividerInset() {
SetupWizardPreferenceLayout layout = new TestLayout(mContext);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
layout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
}
assertPreferenceTemplateInflated(layout);
layout.addView(layout.onCreateRecyclerView(LayoutInflater.from(mContext), layout,
null /* savedInstanceState */));
layout.setDividerInset(10);
assertEquals("Divider inset should be 10", 10, layout.getDividerInset());
final Drawable divider = layout.getDivider();
assertTrue("Divider should be instance of InsetDrawable", divider instanceof InsetDrawable);
}
private void assertPreferenceTemplateInflated(SetupWizardPreferenceLayout layout) {
View contentContainer = layout.findViewById(R.id.suw_layout_content);
assertTrue("@id/suw_layout_content should be a ViewGroup",
contentContainer instanceof ViewGroup);
if (layout instanceof TestLayout) {
assertNotNull("Header text view should not be null",
((TestLayout) layout).getHeaderTextView());
assertNotNull("Decoration view should not be null",
((TestLayout) layout).getDecorationView());
}
}
// Make some methods public for testing
public static class TestLayout extends SetupWizardPreferenceLayout {
public TestLayout(Context context) {
super(context);
}
@Override
public TextView getHeaderTextView() {
return super.getHeaderTextView();
}
@Override
public View getDecorationView() {
return super.getDecorationView();
}
}
}

View file

@ -0,0 +1,132 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.setupwizardlib.test;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.os.Build;
import android.support.v7.widget.RecyclerView;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.setupwizardlib.SetupWizardRecyclerLayout;
public class SetupWizardRecyclerLayoutTest extends InstrumentationTestCase {
private Context mContext;
@Override
protected void setUp() throws Exception {
super.setUp();
mContext = new ContextThemeWrapper(getInstrumentation().getContext(),
R.style.SuwThemeMaterial_Light);
}
@SmallTest
public void testDefaultTemplate() {
SetupWizardRecyclerLayout layout = new TestLayout(mContext);
assertRecyclerTemplateInflated(layout);
}
@SmallTest
public void testInflateFromXml() {
LayoutInflater inflater = LayoutInflater.from(mContext);
SetupWizardRecyclerLayout layout = (SetupWizardRecyclerLayout)
inflater.inflate(R.layout.test_recycler_layout, null);
assertRecyclerTemplateInflated(layout);
}
@SmallTest
public void testGetRecyclerView() {
SetupWizardRecyclerLayout layout = new TestLayout(mContext);
assertRecyclerTemplateInflated(layout);
assertNotNull("getRecyclerView should not be null", layout.getRecyclerView());
}
@SmallTest
public void testAdapter() {
SetupWizardRecyclerLayout layout = new TestLayout(mContext);
assertRecyclerTemplateInflated(layout);
final RecyclerView.Adapter adapter = new RecyclerView.Adapter() {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
return new RecyclerView.ViewHolder(new View(parent.getContext())) {};
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
};
layout.setAdapter(adapter);
final RecyclerView.Adapter gotAdapter = layout.getAdapter();
// Note: The wrapped adapter should be returned, not the HeaderAdapter.
assertSame("Adapter got from SetupWizardLayout should be same as set",
adapter, gotAdapter);
}
@SmallTest
public void testDividerInset() {
SetupWizardRecyclerLayout layout = new TestLayout(mContext);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
layout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
}
assertRecyclerTemplateInflated(layout);
layout.setDividerInset(10);
assertEquals("Divider inset should be 10", 10, layout.getDividerInset());
final Drawable divider = layout.getDivider();
assertTrue("Divider should be instance of InsetDrawable", divider instanceof InsetDrawable);
}
private void assertRecyclerTemplateInflated(SetupWizardRecyclerLayout layout) {
View recyclerView = layout.findViewById(R.id.suw_recycler_view);
assertTrue("@id/suw_recycler_view should be a RecyclerView",
recyclerView instanceof RecyclerView);
if (layout instanceof TestLayout) {
assertNotNull("Header text view should not be null",
((TestLayout) layout).getHeaderTextView());
}
}
// Make some methods public for testing
public static class TestLayout extends SetupWizardRecyclerLayout {
public TestLayout(Context context) {
super(context);
}
@Override
public TextView getHeaderTextView() {
return super.getHeaderTextView();
}
}
}

View file

@ -55,14 +55,7 @@
<FrameLayout
android:id="@+id/suw_layout_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Temporary solution to work with PreferenceFragment v14 -->
<FrameLayout android:id="@+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
android:layout_height="match_parent" />
<include layout="@layout/suw_progress_bar_stub" />

View file

@ -56,14 +56,7 @@
<FrameLayout
android:id="@+id/suw_layout_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Temporary solution to work with PreferenceFragment v14 -->
<FrameLayout android:id="@+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
android:layout_height="match_parent" />
<include layout="@layout/suw_progress_bar_stub" />

View file

@ -56,14 +56,7 @@
android:id="@+id/suw_layout_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<!-- Temporary solution to work with PreferenceFragment v14 -->
<FrameLayout android:id="@+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
android:layout_weight="1" />
</LinearLayout>

View file

@ -45,14 +45,7 @@
<FrameLayout android:id="@+id/suw_layout_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<!-- Temporary solution to work with PreferenceFragment v14 -->
<FrameLayout android:id="@+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
android:layout_weight="1" />
<com.android.setupwizardlib.view.NavigationBar
android:id="@+id/suw_layout_navigation_bar"

View file

@ -7,7 +7,7 @@ apply plugin: 'dist'
apply from: 'build.gradle'
apply from: '../tools/gradle/docs.gradle'
task docs(dependsOn: 'javadocPlatformRelease')
task docs(dependsOn: 'javadocFullSupportRelease')
android.lintOptions {
abortOnError true