[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/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 \
|
||||
|
|
|
@ -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 {
|
||||
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']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue