diff options
author | Maurice Lam <yukl@google.com> | 2015-12-04 12:37:34 -0800 |
---|---|---|
committer | Maurice Lam <yukl@google.com> | 2015-12-04 12:49:03 -0800 |
commit | 5a4d6cdfb63240c41527ba80b7baddba8933d770 (patch) | |
tree | 6215ac882adfbbb245c346b5a1e0c10bb44bf6ad /library | |
parent | 678740df07b7df6708d7b1dafd492e3e4236cea2 (diff) | |
download | setupwizard-5a4d6cdfb63240c41527ba80b7baddba8933d770.tar.gz |
[SuwLib] GLIF layout adjustment for headers
- Store the list item directly in the view holder and update in
onBindViewHolder, so that the click handler is not prone to adapter
position changes.
- Glif[List/Recycler]Layout now returns the wrapped adapter when
getAdapter is called.
- Disable dividers for header views
Change-Id: Ie782a4de06e2296d4996cb8b81b5d7d3fc834ccf
Diffstat (limited to 'library')
7 files changed, 75 insertions, 26 deletions
diff --git a/library/full-support/src/com/android/setupwizardlib/GlifRecyclerLayout.java b/library/full-support/src/com/android/setupwizardlib/GlifRecyclerLayout.java index ef29db8..3b8f71a 100644 --- a/library/full-support/src/com/android/setupwizardlib/GlifRecyclerLayout.java +++ b/library/full-support/src/com/android/setupwizardlib/GlifRecyclerLayout.java @@ -151,7 +151,11 @@ public class GlifRecyclerLayout extends GlifLayout { } public RecyclerView.Adapter getAdapter() { - return getRecyclerView().getAdapter(); + final RecyclerView.Adapter adapter = getRecyclerView().getAdapter(); + if (adapter instanceof HeaderRecyclerView.HeaderAdapter) { + return ((HeaderRecyclerView.HeaderAdapter) adapter).getWrappedAdapter(); + } + return adapter; } /** diff --git a/library/full-support/src/com/android/setupwizardlib/items/ItemViewHolder.java b/library/full-support/src/com/android/setupwizardlib/items/ItemViewHolder.java index 1519235..8f89603 100644 --- a/library/full-support/src/com/android/setupwizardlib/items/ItemViewHolder.java +++ b/library/full-support/src/com/android/setupwizardlib/items/ItemViewHolder.java @@ -25,6 +25,7 @@ class ItemViewHolder extends RecyclerView.ViewHolder implements DividerItemDecoration.DividedViewHolder { private boolean mIsEnabled; + private IItem mItem; public ItemViewHolder(View itemView) { super(itemView); @@ -46,4 +47,12 @@ class ItemViewHolder extends RecyclerView.ViewHolder itemView.setEnabled(isEnabled); itemView.setFocusable(isEnabled); } + + public void setItem(IItem item) { + mItem = item; + } + + public IItem getItem() { + return mItem; + } } diff --git a/library/full-support/src/com/android/setupwizardlib/items/RecyclerItemAdapter.java b/library/full-support/src/com/android/setupwizardlib/items/RecyclerItemAdapter.java index 6f5b719..ae39cc0 100644 --- a/library/full-support/src/com/android/setupwizardlib/items/RecyclerItemAdapter.java +++ b/library/full-support/src/com/android/setupwizardlib/items/RecyclerItemAdapter.java @@ -82,14 +82,9 @@ public class RecyclerItemAdapter extends RecyclerView.Adapter<ItemViewHolder> view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - final int position = viewHolder.getAdapterPosition(); - // Position can be NO_POSITION = -1 if the item is being removed asynchronously - // from the RecyclerView. - if (position != RecyclerView.NO_POSITION) { - final IItem item = getItem(position); - if (mListener != null && item.isEnabled()) { - mListener.onItemSelected(item); - } + final IItem item = viewHolder.getItem(); + if (mListener != null && item != null && item.isEnabled()) { + mListener.onItemSelected(item); } } }); @@ -102,6 +97,7 @@ public class RecyclerItemAdapter extends RecyclerView.Adapter<ItemViewHolder> final IItem item = getItem(position); item.onBindView(holder.itemView); holder.setEnabled(item.isEnabled()); + holder.setItem(item); } @Override diff --git a/library/full-support/src/com/android/setupwizardlib/view/HeaderRecyclerView.java b/library/full-support/src/com/android/setupwizardlib/view/HeaderRecyclerView.java index d96b05f..f164a23 100644 --- a/library/full-support/src/com/android/setupwizardlib/view/HeaderRecyclerView.java +++ b/library/full-support/src/com/android/setupwizardlib/view/HeaderRecyclerView.java @@ -26,6 +26,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; +import com.android.setupwizardlib.DividerItemDecoration; import com.android.setupwizardlib.R; import com.android.setupwizardlib.annotations.VisibleForTesting; @@ -36,11 +37,22 @@ import com.android.setupwizardlib.annotations.VisibleForTesting; */ public class HeaderRecyclerView extends RecyclerView { - private static class HeaderViewHolder extends ViewHolder { + private static class HeaderViewHolder extends ViewHolder + implements DividerItemDecoration.DividedViewHolder { public HeaderViewHolder(View itemView) { super(itemView); } + + @Override + public boolean isDividerAllowedAbove() { + return false; + } + + @Override + public boolean isDividerAllowedBelow() { + return false; + } } /** @@ -48,12 +60,43 @@ public class HeaderRecyclerView extends RecyclerView { */ public static class HeaderAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + private static final int HEADER_VIEW_TYPE = Integer.MAX_VALUE; + private RecyclerView.Adapter mAdapter; private View mHeader; - private static final int HEADER_VIEW_TYPE = Integer.MAX_VALUE; + + private final AdapterDataObserver mObserver = new AdapterDataObserver() { + + @Override + public void onChanged() { + notifyDataSetChanged(); + } + + @Override + public void onItemRangeChanged(int positionStart, int itemCount) { + notifyItemRangeChanged(positionStart, itemCount); + } + + @Override + public void onItemRangeInserted(int positionStart, int itemCount) { + notifyItemRangeInserted(positionStart, itemCount); + } + + @Override + public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { + // Why is there no notifyItemRangeMoved? + notifyDataSetChanged(); + } + + @Override + public void onItemRangeRemoved(int positionStart, int itemCount) { + notifyItemRangeRemoved(positionStart, itemCount); + } + }; public HeaderAdapter(RecyclerView.Adapter adapter) { mAdapter = adapter; + mAdapter.registerAdapterDataObserver(mObserver); setHasStableIds(mAdapter.hasStableIds()); } diff --git a/library/full-support/test/src/com/android/setupwizardlib/test/GlifRecyclerLayoutTest.java b/library/full-support/test/src/com/android/setupwizardlib/test/GlifRecyclerLayoutTest.java index d8761cd..d51a999 100644 --- a/library/full-support/test/src/com/android/setupwizardlib/test/GlifRecyclerLayoutTest.java +++ b/library/full-support/test/src/com/android/setupwizardlib/test/GlifRecyclerLayoutTest.java @@ -88,13 +88,9 @@ public class GlifRecyclerLayoutTest extends InstrumentationTestCase { layout.setAdapter(adapter); final RecyclerView.Adapter gotAdapter = layout.getAdapter(); - if (gotAdapter instanceof HeaderRecyclerView.HeaderAdapter) { - assertSame("Adapter got from GlifRecyclerLayout should be same as set", - adapter, ((HeaderRecyclerView.HeaderAdapter) gotAdapter).getWrappedAdapter()); - } else { - assertSame("Adapter got from GlifRecyclerLayout should be same as set", - adapter, gotAdapter); - } + // Note: The wrapped adapter should be returned, not the HeaderAdapter. + assertSame("Adapter got from GlifRecyclerLayout should be same as set", + adapter, gotAdapter); } @SmallTest diff --git a/library/main/src/com/android/setupwizardlib/GlifListLayout.java b/library/main/src/com/android/setupwizardlib/GlifListLayout.java index 4a1859f..77065c8 100644 --- a/library/main/src/com/android/setupwizardlib/GlifListLayout.java +++ b/library/main/src/com/android/setupwizardlib/GlifListLayout.java @@ -26,6 +26,7 @@ import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.HeaderViewListAdapter; import android.widget.ListAdapter; import android.widget.ListView; @@ -132,7 +133,11 @@ public class GlifListLayout extends GlifLayout { } public ListAdapter getAdapter() { - return getListView().getAdapter(); + final ListAdapter adapter = getListView().getAdapter(); + if (adapter instanceof HeaderViewListAdapter) { + return ((HeaderViewListAdapter) adapter).getWrappedAdapter(); + } + return adapter; } /** diff --git a/library/test/src/com/android/setupwizardlib/test/GlifListLayoutTest.java b/library/test/src/com/android/setupwizardlib/test/GlifListLayoutTest.java index c6a1211..c56b134 100644 --- a/library/test/src/com/android/setupwizardlib/test/GlifListLayoutTest.java +++ b/library/test/src/com/android/setupwizardlib/test/GlifListLayoutTest.java @@ -88,13 +88,9 @@ public class GlifListLayoutTest extends InstrumentationTestCase { layout.setAdapter(adapter); final ListAdapter gotAdapter = layout.getAdapter(); - if (gotAdapter instanceof HeaderViewListAdapter) { - assertSame("Adapter got from GlifListLayout should be same as set", - adapter, ((HeaderViewListAdapter) gotAdapter).getWrappedAdapter()); - } else { - assertSame("Adapter got from GlifListLayout should be same as set", - adapter, gotAdapter); - } + // Note: the wrapped adapter should be returned directly, not the HeaderViewListAdapter. + assertSame("Adapter got from GlifListLayout should be same as set", + adapter, gotAdapter); } @SmallTest |