[SuwLib] Recycler item adapter support

Implement RecyclerView item adapter for an ItemHierarchy.

Change-Id: Id7e650fafa467ca7ee3c80102efc73d4323e5b1c
This commit is contained in:
Maurice Lam 2015-10-22 11:21:19 -07:00
parent 908e41cdf8
commit a74bc1d5c6
4 changed files with 214 additions and 2 deletions

View file

@ -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 \

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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']
}
}
}