[SuwLib] Refactor out TemplateLayout
Refactor TemplateLayout as a base class for SetupWizardLayout, which is a generic layout that takes the "android:layout", inflates that as a template and put its children in the "container". Change-Id: Id7977787ffa6cdb5df7a4cb8172ce1fa6a52ed45
This commit is contained in:
parent
e2eb715ed2
commit
bdfc0132ff
|
@ -37,7 +37,6 @@
|
|||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="SuwSetupWizardLayout">
|
||||
<attr name="android:layout" />
|
||||
<attr name="suwBackground" format="color|reference" />
|
||||
<attr name="suwBackgroundTile" format="color|reference" />
|
||||
<attr name="suwHeaderText" format="string" localization="suggested" />
|
||||
|
@ -48,4 +47,9 @@
|
|||
<attr name="suwIllustrationImage" format="color|reference" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="SuwTemplateLayout">
|
||||
<attr name="android:layout" />
|
||||
<attr name="suwContainer" format="reference" />
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -36,64 +36,47 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewStub;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.setupwizardlib.annotations.Keep;
|
||||
import com.android.setupwizardlib.util.RequireScrollHelper;
|
||||
import com.android.setupwizardlib.view.BottomScrollView;
|
||||
import com.android.setupwizardlib.view.Illustration;
|
||||
import com.android.setupwizardlib.view.NavigationBar;
|
||||
|
||||
public class SetupWizardLayout extends FrameLayout {
|
||||
public class SetupWizardLayout extends TemplateLayout {
|
||||
|
||||
private static final String TAG = "SetupWizardLayout";
|
||||
|
||||
/**
|
||||
* The container of the actual content. This will be a view in the template, which child views
|
||||
* will be added to when {@link #addView(android.view.View)} is called. This will be the layout
|
||||
* in the template that has the ID of {@link #getContainerId()}. For the default implementation
|
||||
* of SetupWizardLayout, that would be @id/suw_layout_content.
|
||||
*/
|
||||
private ViewGroup mContainer;
|
||||
|
||||
public SetupWizardLayout(Context context) {
|
||||
super(context);
|
||||
init(0, null, R.attr.suwLayoutTheme);
|
||||
super(context, 0, 0);
|
||||
init(null, R.attr.suwLayoutTheme);
|
||||
}
|
||||
|
||||
public SetupWizardLayout(Context context, int template) {
|
||||
super(context);
|
||||
init(template, null, R.attr.suwLayoutTheme);
|
||||
this(context, template, 0);
|
||||
}
|
||||
|
||||
public SetupWizardLayout(Context context, int template, int containerId) {
|
||||
super(context, template, containerId);
|
||||
init(null, R.attr.suwLayoutTheme);
|
||||
}
|
||||
|
||||
public SetupWizardLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(0, attrs, R.attr.suwLayoutTheme);
|
||||
init(attrs, R.attr.suwLayoutTheme);
|
||||
}
|
||||
|
||||
@TargetApi(VERSION_CODES.HONEYCOMB)
|
||||
public SetupWizardLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(0, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@TargetApi(VERSION_CODES.HONEYCOMB)
|
||||
public SetupWizardLayout(Context context, int template, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(template, attrs, defStyleAttr);
|
||||
init(attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
// All the constructors delegate to this init method. The 3-argument constructor is not
|
||||
// available in LinearLayout before v11, so call super with the exact same arguments.
|
||||
private void init(int template, AttributeSet attrs, int defStyleAttr) {
|
||||
private void init(AttributeSet attrs, int defStyleAttr) {
|
||||
final TypedArray a = getContext().obtainStyledAttributes(attrs,
|
||||
R.styleable.SuwSetupWizardLayout, defStyleAttr, 0);
|
||||
if (template == 0) {
|
||||
template = a.getResourceId(R.styleable.SuwSetupWizardLayout_android_layout, 0);
|
||||
}
|
||||
inflateTemplate(template);
|
||||
|
||||
// Set the background from XML, either directly or built from a bitmap tile
|
||||
final Drawable background =
|
||||
|
@ -174,52 +157,19 @@ public class SetupWizardLayout extends FrameLayout {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
||||
mContainer.addView(child, index, params);
|
||||
}
|
||||
|
||||
private void addViewInternal(View child) {
|
||||
super.addView(child, -1, generateDefaultLayoutParams());
|
||||
}
|
||||
|
||||
private void inflateTemplate(int templateResource) {
|
||||
final LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||
final View templateRoot = onInflateTemplate(inflater, templateResource);
|
||||
addViewInternal(templateRoot);
|
||||
|
||||
mContainer = (ViewGroup) findViewById(getContainerId());
|
||||
onTemplateInflated();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method inflates the template. Subclasses can override this method to customize the
|
||||
* template inflation, or change to a different default template. The root of the inflated
|
||||
* layout should be returned, and not added to the view hierarchy.
|
||||
*
|
||||
* @param inflater A LayoutInflater to inflate the template.
|
||||
* @param template The resource ID of the template to be inflated, or 0 if no template is
|
||||
* specified.
|
||||
* @return Root of the inflated layout.
|
||||
*/
|
||||
protected View onInflateTemplate(LayoutInflater inflater, int template) {
|
||||
if (template == 0) {
|
||||
template = R.layout.suw_template;
|
||||
}
|
||||
return inflater.inflate(template, this, false);
|
||||
return super.onInflateTemplate(inflater, template);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called after the template has been inflated and added to the view hierarchy.
|
||||
* Subclasses can implement this method to modify the template as necessary, such as caching
|
||||
* views retrieved from findViewById, or other view operations that need to be done in code.
|
||||
* You can think of this as {@link android.view.View#onFinishInflate()} but for inflation of the
|
||||
* template instead of for child views.
|
||||
*/
|
||||
protected void onTemplateInflated() {
|
||||
}
|
||||
|
||||
protected int getContainerId() {
|
||||
return R.id.suw_layout_content;
|
||||
@Override
|
||||
protected ViewGroup findContainer(int containerId) {
|
||||
if (containerId == 0) {
|
||||
containerId = R.id.suw_layout_content;
|
||||
}
|
||||
return super.findContainer(containerId);
|
||||
}
|
||||
|
||||
public NavigationBar getNavigationBar() {
|
||||
|
@ -426,53 +376,6 @@ public class SetupWizardLayout extends FrameLayout {
|
|||
}
|
||||
}
|
||||
|
||||
/* Animator support */
|
||||
|
||||
private float mXFraction;
|
||||
private ViewTreeObserver.OnPreDrawListener mPreDrawListener;
|
||||
|
||||
/**
|
||||
* Set the X translation as a fraction of the width of this view. Make sure this method is not
|
||||
* stripped out by proguard when using ObjectAnimator. You may need to add
|
||||
* -keep @com.android.setupwizardlib.annotations.Keep class *
|
||||
* to your proguard configuration if you are seeing mysterious MethodNotFoundExceptions at
|
||||
* runtime.
|
||||
*/
|
||||
@Keep
|
||||
public void setXFraction(float fraction) {
|
||||
mXFraction = fraction;
|
||||
final int width = getWidth();
|
||||
if (width != 0) {
|
||||
setTranslationX(width * fraction);
|
||||
} else {
|
||||
// If we haven't done a layout pass yet, wait for one and then set the fraction before
|
||||
// the draw occurs using an OnPreDrawListener. Don't call translationX until we know
|
||||
// getWidth() has a reliable, non-zero value or else we will see the fragment flicker on
|
||||
// screen.
|
||||
if (mPreDrawListener == null) {
|
||||
mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
getViewTreeObserver().removeOnPreDrawListener(mPreDrawListener);
|
||||
setXFraction(mXFraction);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the X translation as a fraction of the width, as previously set in setXFraction.
|
||||
*
|
||||
* @see #setXFraction(float)
|
||||
*/
|
||||
@Keep
|
||||
public float getXFraction() {
|
||||
return mXFraction;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
|
||||
protected static class SavedState extends BaseSavedState {
|
||||
|
|
|
@ -22,6 +22,7 @@ import android.os.Build.VERSION_CODES;
|
|||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
|
@ -31,11 +32,15 @@ public class SetupWizardListLayout extends SetupWizardLayout {
|
|||
private ListView mListView;
|
||||
|
||||
public SetupWizardListLayout(Context context) {
|
||||
super(context);
|
||||
this(context, 0, 0);
|
||||
}
|
||||
|
||||
public SetupWizardListLayout(Context context, int template) {
|
||||
super(context, template);
|
||||
this(context, template, 0);
|
||||
}
|
||||
|
||||
public SetupWizardListLayout(Context context, int template, int containerId) {
|
||||
super(context, template, containerId);
|
||||
}
|
||||
|
||||
public SetupWizardListLayout(Context context, AttributeSet attrs) {
|
||||
|
@ -47,18 +52,20 @@ public class SetupWizardListLayout extends SetupWizardLayout {
|
|||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@TargetApi(VERSION_CODES.HONEYCOMB)
|
||||
public SetupWizardListLayout(Context context, int template, AttributeSet attrs,
|
||||
int defStyleAttr) {
|
||||
super(context, template, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View onInflateTemplate(LayoutInflater inflater, int template) {
|
||||
if (template == 0) {
|
||||
template = R.layout.suw_list_template;
|
||||
}
|
||||
return inflater.inflate(template, this, false);
|
||||
return super.onInflateTemplate(inflater, template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ViewGroup findContainer(int containerId) {
|
||||
if (containerId == 0) {
|
||||
containerId = android.R.id.list;
|
||||
}
|
||||
return super.findContainer(containerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,11 +73,6 @@ public class SetupWizardListLayout extends SetupWizardLayout {
|
|||
mListView = (ListView) findViewById(android.R.id.list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getContainerId() {
|
||||
return android.R.id.list;
|
||||
}
|
||||
|
||||
public ListView getListView() {
|
||||
return mListView;
|
||||
}
|
||||
|
|
193
library/main/src/com/android/setupwizardlib/TemplateLayout.java
Normal file
193
library/main/src/com/android/setupwizardlib/TemplateLayout.java
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* 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.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Build;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.setupwizardlib.annotations.Keep;
|
||||
|
||||
/**
|
||||
* A generic template class that inflates a template, provided in the constructor or in
|
||||
* android:layout through XML, and adds its children to a "container" in the template. When
|
||||
* inflating this layout from XML, the {@code android:layout} and {@code suwContainer} attributes
|
||||
* are required.
|
||||
*/
|
||||
public class TemplateLayout extends FrameLayout {
|
||||
|
||||
/**
|
||||
* The container of the actual content. This will be a view in the template, which child views
|
||||
* will be added to when {@link #addView(View)} is called.
|
||||
*/
|
||||
private ViewGroup mContainer;
|
||||
|
||||
public TemplateLayout(Context context, int template, int containerId) {
|
||||
super(context);
|
||||
init(template, containerId, null, R.attr.suwLayoutTheme);
|
||||
}
|
||||
|
||||
public TemplateLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(0, 0, attrs, R.attr.suwLayoutTheme);
|
||||
}
|
||||
|
||||
@TargetApi(VERSION_CODES.HONEYCOMB)
|
||||
public TemplateLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(0, 0, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
// All the constructors delegate to this init method. The 3-argument constructor is not
|
||||
// available in LinearLayout before v11, so call super with the exact same arguments.
|
||||
private void init(int template, int containerId, AttributeSet attrs, int defStyleAttr) {
|
||||
final TypedArray a = getContext().obtainStyledAttributes(attrs,
|
||||
R.styleable.SuwTemplateLayout, defStyleAttr, 0);
|
||||
if (template == 0) {
|
||||
template = a.getResourceId(R.styleable.SuwTemplateLayout_android_layout, 0);
|
||||
}
|
||||
if (containerId == 0) {
|
||||
containerId = a.getResourceId(R.styleable.SuwTemplateLayout_suwContainer, 0);
|
||||
}
|
||||
inflateTemplate(template, containerId);
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
||||
mContainer.addView(child, index, params);
|
||||
}
|
||||
|
||||
private void addViewInternal(View child) {
|
||||
super.addView(child, -1, generateDefaultLayoutParams());
|
||||
}
|
||||
|
||||
private void inflateTemplate(int templateResource, int containerId) {
|
||||
final LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||
final View templateRoot = onInflateTemplate(inflater, templateResource);
|
||||
addViewInternal(templateRoot);
|
||||
|
||||
mContainer = findContainer(containerId);
|
||||
if (mContainer == null) {
|
||||
throw new IllegalArgumentException("Container cannot be null in TemplateLayout");
|
||||
}
|
||||
onTemplateInflated();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method inflates the template. Subclasses can override this method to customize the
|
||||
* template inflation, or change to a different default template. The root of the inflated
|
||||
* layout should be returned, and not added to the view hierarchy.
|
||||
*
|
||||
* @param inflater A LayoutInflater to inflate the template.
|
||||
* @param template The resource ID of the template to be inflated, or 0 if no template is
|
||||
* specified.
|
||||
* @return Root of the inflated layout.
|
||||
*/
|
||||
protected View onInflateTemplate(LayoutInflater inflater, int template) {
|
||||
if (template == 0) {
|
||||
throw new IllegalArgumentException("android:layout not specified for TemplateLayout");
|
||||
}
|
||||
return inflater.inflate(template, this, false);
|
||||
}
|
||||
|
||||
protected ViewGroup findContainer(int containerId) {
|
||||
if (containerId == 0) {
|
||||
// Maintain compatibility with the deprecated way of specifying container ID.
|
||||
containerId = getContainerId();
|
||||
}
|
||||
return (ViewGroup) findViewById(containerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called after the template has been inflated and added to the view hierarchy.
|
||||
* Subclasses can implement this method to modify the template as necessary, such as caching
|
||||
* views retrieved from findViewById, or other view operations that need to be done in code.
|
||||
* You can think of this as {@link View#onFinishInflate()} but for inflation of the
|
||||
* template instead of for child views.
|
||||
*/
|
||||
protected void onTemplateInflated() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ID of the default container for this layout. This will be used to find the container
|
||||
* ViewGroup, which all children views of this layout will be placed in.
|
||||
* @deprecated Use the constructor with containerId argument instead.
|
||||
*/
|
||||
@Deprecated
|
||||
protected int getContainerId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Animator support */
|
||||
|
||||
private float mXFraction;
|
||||
private ViewTreeObserver.OnPreDrawListener mPreDrawListener;
|
||||
|
||||
/**
|
||||
* Set the X translation as a fraction of the width of this view. Make sure this method is not
|
||||
* stripped out by proguard when using ObjectAnimator. You may need to add
|
||||
* -keep @com.android.setupwizardlib.annotations.Keep class *
|
||||
* to your proguard configuration if you are seeing mysterious MethodNotFoundExceptions at
|
||||
* runtime.
|
||||
*/
|
||||
@Keep
|
||||
@TargetApi(VERSION_CODES.HONEYCOMB)
|
||||
public void setXFraction(float fraction) {
|
||||
mXFraction = fraction;
|
||||
final int width = getWidth();
|
||||
if (width != 0) {
|
||||
setTranslationX(width * fraction);
|
||||
} else {
|
||||
// If we haven't done a layout pass yet, wait for one and then set the fraction before
|
||||
// the draw occurs using an OnPreDrawListener. Don't call translationX until we know
|
||||
// getWidth() has a reliable, non-zero value or else we will see the fragment flicker on
|
||||
// screen.
|
||||
if (mPreDrawListener == null) {
|
||||
mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
getViewTreeObserver().removeOnPreDrawListener(mPreDrawListener);
|
||||
setXFraction(mXFraction);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the X translation as a fraction of the width, as previously set in setXFraction.
|
||||
*
|
||||
* @see #setXFraction(float)
|
||||
*/
|
||||
@Keep
|
||||
@TargetApi(VERSION_CODES.HONEYCOMB)
|
||||
public float getXFraction() {
|
||||
return mXFraction;
|
||||
}
|
||||
}
|
30
library/test/res/layout/test_template_layout.xml
Normal file
30
library/test/res/layout/test_template_layout.xml
Normal file
|
@ -0,0 +1,30 @@
|
|||
<!--
|
||||
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.TemplateLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout="@layout/test_template"
|
||||
app:suwContainer="@+id/suw_layout_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/test_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</com.android.setupwizardlib.TemplateLayout>
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.setupwizardlib.TemplateLayout;
|
||||
|
||||
public class TemplateLayoutTest extends InstrumentationTestCase {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mContext = getInstrumentation().getContext();
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testAddView() {
|
||||
TemplateLayout layout = new TemplateLayout(mContext, R.layout.test_template,
|
||||
R.id.suw_layout_content);
|
||||
TextView tv = new TextView(mContext);
|
||||
tv.setId(R.id.test_view_id);
|
||||
layout.addView(tv);
|
||||
View view = layout.findViewById(R.id.test_view_id);
|
||||
assertSame("The view added should be the same text view", tv, view);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testInflateFromXml() {
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
TemplateLayout layout =
|
||||
(TemplateLayout) inflater.inflate(R.layout.test_template_layout, null);
|
||||
View content = layout.findViewById(R.id.test_content);
|
||||
assertTrue("@id/test_content should be a TextView", content instanceof TextView);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testTemplate() {
|
||||
TemplateLayout layout = new TemplateLayout(mContext, R.layout.test_template,
|
||||
R.id.suw_layout_content);
|
||||
View templateView = layout.findViewById(R.id.test_template_view);
|
||||
assertNotNull("@id/test_template_view should exist in template", templateView);
|
||||
|
||||
TextView tv = new TextView(mContext);
|
||||
tv.setId(R.id.test_view_id);
|
||||
layout.addView(tv);
|
||||
|
||||
templateView = layout.findViewById(R.id.test_template_view);
|
||||
assertNotNull("@id/test_template_view should exist in template", templateView);
|
||||
View contentView = layout.findViewById(R.id.test_view_id);
|
||||
assertSame("The view added should be the same text view", tv, contentView);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testNoTemplate() {
|
||||
try {
|
||||
new TemplateLayout(mContext, 0, 0);
|
||||
fail("Inflating TemplateLayout without template should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Expected IllegalArgumentException
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue