summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorMaurice Lam <yukl@google.com>2015-10-22 11:21:19 -0700
committerMaurice Lam <yukl@google.com>2015-10-26 15:47:20 -0700
commita74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2 (patch)
treea5364e166ab6db590624deea5bd07de526bcc273 /library
parent908e41cdf8cd689fe436699ab8fc7f9bf8558cec (diff)
downloadsetupwizard-a74bc1d5c6d7cb9e0f5add4c56a983cb492cb3c2.tar.gz
[SuwLib] Recycler item adapter support
Implement RecyclerView item adapter for an ItemHierarchy. Change-Id: Id7e650fafa467ca7ee3c80102efc73d4323e5b1c
Diffstat (limited to 'library')
-rw-r--r--library/Android.mk2
-rw-r--r--library/full-support/src/com/android/setupwizardlib/items/RecyclerItemAdapter.java141
-rw-r--r--library/full-support/test/src/com/android/setupwizardlib/test/RecyclerItemAdapterTest.java67
-rw-r--r--library/rules.gradle6
4 files changed, 214 insertions, 2 deletions
diff --git a/library/Android.mk b/library/Android.mk
index bcbd0e9..543b840 100644
--- a/library/Android.mk
+++ b/library/Android.mk
@@ -58,7 +58,7 @@ LOCAL_RESOURCE_DIR := \
frameworks/support/v7/appcompat/res \
frameworks/support/v7/recyclerview/res
LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := $(call all-java-files-under, main/src eclair-mr1/src)
+LOCAL_SRC_FILES := $(call all-java-files-under, main/src eclair-mr1/src full-support/src)
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-v4 \
android-support-v7-appcompat \
diff --git a/library/full-support/src/com/android/setupwizardlib/items/RecyclerItemAdapter.java b/library/full-support/src/com/android/setupwizardlib/items/RecyclerItemAdapter.java
new file mode 100644
index 0000000..314314e
--- /dev/null
+++ b/library/full-support/src/com/android/setupwizardlib/items/RecyclerItemAdapter.java
@@ -0,0 +1,141 @@
+/*
+ * 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.items;
+
+import android.content.res.TypedArray;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.setupwizardlib.R;
+
+/**
+ * An adapter used with RecyclerView to display an {@link ItemHierarchy}. The item hierarchy used to
+ * create this adapter can be inflated by {@link com.android.setupwizardlib.items.ItemInflater} from
+ * XML.
+ */
+public class RecyclerItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
+ implements ItemHierarchy.Observer {
+
+ private static final int[] SELECTABLE_ITEM_BACKGROUND = new int[] {
+ R.attr.selectableItemBackground
+ };
+
+ public interface OnItemSelectedListener {
+ void onItemSelected(IItem item);
+ }
+
+ private static class GenericViewHolder extends RecyclerView.ViewHolder {
+
+ public GenericViewHolder(View itemView) {
+ super(itemView);
+ }
+ }
+
+ private final ItemHierarchy mItemHierarchy;
+ private OnItemSelectedListener mListener;
+
+ public RecyclerItemAdapter(ItemHierarchy hierarchy) {
+ mItemHierarchy = hierarchy;
+ mItemHierarchy.registerObserver(this);
+ setHasStableIds(true);
+ }
+
+ public IItem getItem(int position) {
+ return mItemHierarchy.getItemAt(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ IItem mItem = getItem(position);
+ if (mItem instanceof AbstractItem) {
+ return ((AbstractItem) mItem).getId();
+ } else {
+ return RecyclerView.NO_ID;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return mItemHierarchy.getCount();
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+ final View view = inflater.inflate(viewType, parent, false);
+ final GenericViewHolder viewHolder = new GenericViewHolder(view);
+
+ final TypedArray typedArray = parent.getContext()
+ .obtainStyledAttributes(SELECTABLE_ITEM_BACKGROUND);
+ view.setBackgroundDrawable(typedArray.getDrawable(0));
+ typedArray.recycle();
+
+ view.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ final IItem item = getItem(viewHolder.getAdapterPosition());
+ if (mListener != null && item.isEnabled()) {
+ mListener.onItemSelected(item);
+ }
+ }
+ });
+
+ return viewHolder;
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ final IItem item = getItem(position);
+ item.onBindView(holder.itemView);
+ if (item.isEnabled()) {
+ holder.itemView.setClickable(true);
+ holder.itemView.setEnabled(true);
+ holder.itemView.setFocusable(true);
+ } else {
+ holder.itemView.setClickable(false);
+ holder.itemView.setEnabled(false);
+ holder.itemView.setFocusable(false);
+ }
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ // Use layout resource as item view type. RecyclerView item type does not have to be
+ // contiguous.
+ IItem item = getItem(position);
+ return item.getLayoutResource();
+ }
+
+ @Override
+ public void onChanged(ItemHierarchy hierarchy) {
+ notifyDataSetChanged();
+ }
+
+ public ItemHierarchy findItemById(int id) {
+ return mItemHierarchy.findItemById(id);
+ }
+
+ public ItemHierarchy getRootItemHierarchy() {
+ return mItemHierarchy;
+ }
+
+ public void setOnItemSelectedListener(OnItemSelectedListener listener) {
+ mListener = listener;
+ }
+}
diff --git a/library/full-support/test/src/com/android/setupwizardlib/test/RecyclerItemAdapterTest.java b/library/full-support/test/src/com/android/setupwizardlib/test/RecyclerItemAdapterTest.java
new file mode 100644
index 0000000..d3061b1
--- /dev/null
+++ b/library/full-support/test/src/com/android/setupwizardlib/test/RecyclerItemAdapterTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.setupwizardlib.items.Item;
+import com.android.setupwizardlib.items.ItemGroup;
+import com.android.setupwizardlib.items.ItemHierarchy;
+import com.android.setupwizardlib.items.RecyclerItemAdapter;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class RecyclerItemAdapterTest extends AndroidTestCase {
+
+ private Item[] mItems = new Item[5];
+ private ItemGroup mItemGroup = new ItemGroup();
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ for (int i = 0; i < 5; i++) {
+ Item item = new Item();
+ item.setTitle("TestTitle" + i);
+ item.setId(i);
+ // Layout resource: 0 -> 1, 1 -> 11, 2 -> 21, 3 -> 1, 4 -> 11.
+ // (Resource IDs cannot be 0)
+ item.setLayoutResource((i % 3) * 10 + 1);
+ mItems[i] = item;
+ mItemGroup.addChild(item);
+ }
+ }
+
+ @SmallTest
+ public void testAdapter() {
+ RecyclerItemAdapter adapter = new RecyclerItemAdapter(mItemGroup);
+ assertEquals("Adapter should have 5 items", 5, adapter.getItemCount());
+ assertEquals("Adapter should return the first item", mItems[0], adapter.getItem(0));
+ assertEquals("ID should be same as position", 2, adapter.getItemId(2));
+
+ // ViewType is same as layout resource for RecyclerItemAdapter
+ assertEquals("Second item should have view type 21", 21, adapter.getItemViewType(2));
+ }
+
+ @SmallTest
+ public void testGetRootItemHierarchy() {
+ RecyclerItemAdapter adapter = new RecyclerItemAdapter(mItemGroup);
+ ItemHierarchy root = adapter.getRootItemHierarchy();
+ assertSame("Root item hierarchy should be mItemGroup", mItemGroup, root);
+ }
+}
diff --git a/library/rules.gradle b/library/rules.gradle
index 8021372..7660853 100644
--- a/library/rules.gradle
+++ b/library/rules.gradle
@@ -86,7 +86,7 @@ android {
}
fullSupport {
- java.srcDirs = ['eclair-mr1/src']
+ java.srcDirs = ['eclair-mr1/src', 'full-support/src']
res.srcDirs = ['eclair-mr1/res', 'full-support/res']
}
@@ -95,5 +95,9 @@ android {
java.srcDirs = ['test/src']
res.srcDirs = ['test/res']
}
+
+ androidTestFullSupport {
+ java.srcDirs = ['full-support/test/src']
+ }
}
}