[SuwLib] Recycler item adapter support
Implement RecyclerView item adapter for an ItemHierarchy. Change-Id: Id7e650fafa467ca7ee3c80102efc73d4323e5b1c
This commit is contained in:
parent
908e41cdf8
commit
a74bc1d5c6
|
@ -58,7 +58,7 @@ LOCAL_RESOURCE_DIR := \
|
||||||
frameworks/support/v7/appcompat/res \
|
frameworks/support/v7/appcompat/res \
|
||||||
frameworks/support/v7/recyclerview/res
|
frameworks/support/v7/recyclerview/res
|
||||||
LOCAL_SDK_VERSION := current
|
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 := \
|
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||||
android-support-v4 \
|
android-support-v4 \
|
||||||
android-support-v7-appcompat \
|
android-support-v7-appcompat \
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -86,7 +86,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
fullSupport {
|
fullSupport {
|
||||||
java.srcDirs = ['eclair-mr1/src']
|
java.srcDirs = ['eclair-mr1/src', 'full-support/src']
|
||||||
res.srcDirs = ['eclair-mr1/res', 'full-support/res']
|
res.srcDirs = ['eclair-mr1/res', 'full-support/res']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,5 +95,9 @@ android {
|
||||||
java.srcDirs = ['test/src']
|
java.srcDirs = ['test/src']
|
||||||
res.srcDirs = ['test/res']
|
res.srcDirs = ['test/res']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
androidTestFullSupport {
|
||||||
|
java.srcDirs = ['full-support/test/src']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue