/* * Copyright (C) 2015 Haruki Hasegawa * * 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.h6ah4i.android.widget.advrecyclerview.utils; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.ViewGroup; import java.lang.ref.WeakReference; public class BaseWrapperAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> { private static final String TAG = "ARVBaseWrapperAdapter"; private static final boolean LOCAL_LOGD = false; private RecyclerView.Adapter<VH> mWrappedAdapter; private BridgeObserver mBridgeObserver; public BaseWrapperAdapter(RecyclerView.Adapter<VH> adapter) { mWrappedAdapter = adapter; mBridgeObserver = new BridgeObserver<>(this); mWrappedAdapter.registerAdapterDataObserver(mBridgeObserver); super.setHasStableIds(mWrappedAdapter.hasStableIds()); } public void release() { onRelease(); if (mWrappedAdapter != null && mBridgeObserver != null) { mWrappedAdapter.unregisterAdapterDataObserver(mBridgeObserver); } mWrappedAdapter = null; mBridgeObserver = null; } protected void onRelease() { // override this method if needed } public RecyclerView.Adapter<VH> getWrappedAdapter() { return mWrappedAdapter; } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { mWrappedAdapter.onAttachedToRecyclerView(recyclerView); } @Override public void onDetachedFromRecyclerView(RecyclerView recyclerView) { mWrappedAdapter.onDetachedFromRecyclerView(recyclerView); } @Override public void onViewAttachedToWindow(VH holder) { mWrappedAdapter.onViewAttachedToWindow(holder); } @Override public void onViewDetachedFromWindow(VH holder) { mWrappedAdapter.onViewDetachedFromWindow(holder); } @Override public void onViewRecycled(VH holder) { mWrappedAdapter.onViewRecycled(holder); } @Override public void setHasStableIds(boolean hasStableIds) { super.setHasStableIds(hasStableIds); mWrappedAdapter.setHasStableIds(hasStableIds); } @Override public VH onCreateViewHolder(ViewGroup parent, int viewType) { return mWrappedAdapter.onCreateViewHolder(parent, viewType); } @Override public void onBindViewHolder(VH holder, int position) { mWrappedAdapter.onBindViewHolder(holder, position); } @Override public int getItemCount() { return mWrappedAdapter.getItemCount(); } @Override public long getItemId(int position) { return mWrappedAdapter.getItemId(position); } @Override public int getItemViewType(int position) { return mWrappedAdapter.getItemViewType(position); } protected void onHandleWrappedAdapterChanged() { notifyDataSetChanged(); } protected void onHandleWrappedAdapterItemRangeChanged(int positionStart, int itemCount) { notifyItemRangeChanged(positionStart, itemCount); } protected void onHandleWrappedAdapterItemRangeInserted(int positionStart, int itemCount) { notifyItemRangeInserted(positionStart, itemCount); } protected void onHandleWrappedAdapterItemRangeRemoved(int positionStart, int itemCount) { notifyItemRangeRemoved(positionStart, itemCount); } protected void onHandleWrappedAdapterRangeMoved(int fromPosition, int toPosition, int itemCount) { if (itemCount != 1) { throw new IllegalStateException("itemCount should be always 1 (actual: " + itemCount + ")"); } notifyItemMoved(fromPosition, toPosition); } /*package*/ final void onWrappedAdapterChanged() { if (LOCAL_LOGD) { Log.d(TAG, "onWrappedAdapterChanged"); } onHandleWrappedAdapterChanged(); } /*package*/ final void onWrappedAdapterItemRangeChanged(int positionStart, int itemCount) { if (LOCAL_LOGD) { Log.d(TAG, "onWrappedAdapterItemRangeChanged(positionStart = " + positionStart + ", itemCount = " + itemCount + ")"); } onHandleWrappedAdapterItemRangeChanged(positionStart, itemCount); } /*package*/ final void onWrappedAdapterItemRangeInserted(int positionStart, int itemCount) { if (LOCAL_LOGD) { Log.d(TAG, "onWrappedAdapterItemRangeInserted(positionStart = " + positionStart + ", itemCount = " + itemCount + ")"); } onHandleWrappedAdapterItemRangeInserted(positionStart, itemCount); } /*package*/ final void onWrappedAdapterItemRangeRemoved(int positionStart, int itemCount) { if (LOCAL_LOGD) { Log.d(TAG, "onWrappedAdapterItemRangeRemoved(positionStart = " + positionStart + ", itemCount = " + itemCount + ")"); } onHandleWrappedAdapterItemRangeRemoved(positionStart, itemCount); } /*package*/ final void onWrappedAdapterRangeMoved(int fromPosition, int toPosition, int itemCount) { if (LOCAL_LOGD) { Log.d(TAG, "onWrappedAdapterRangeMoved(fromPosition = " + fromPosition + ", toPosition = " + toPosition + ", itemCount = " + itemCount + ")"); } onHandleWrappedAdapterRangeMoved(fromPosition, toPosition, itemCount); } private static final class BridgeObserver<VH extends RecyclerView.ViewHolder> extends RecyclerView.AdapterDataObserver { private WeakReference<BaseWrapperAdapter<VH>> mRefHolder; public BridgeObserver(BaseWrapperAdapter<VH> holder) { mRefHolder = new WeakReference<>(holder); } @Override public void onChanged() { final BaseWrapperAdapter<VH> holder = mRefHolder.get(); if (holder != null) { holder.onWrappedAdapterChanged(); } } @Override public void onItemRangeChanged(int positionStart, int itemCount) { final BaseWrapperAdapter<VH> holder = mRefHolder.get(); if (holder != null) { holder.onWrappedAdapterItemRangeChanged(positionStart, itemCount); } } @Override public void onItemRangeInserted(int positionStart, int itemCount) { final BaseWrapperAdapter<VH> holder = mRefHolder.get(); if (holder != null) { holder.onWrappedAdapterItemRangeInserted(positionStart, itemCount); } } @Override public void onItemRangeRemoved(int positionStart, int itemCount) { final BaseWrapperAdapter<VH> holder = mRefHolder.get(); if (holder != null) { holder.onWrappedAdapterItemRangeRemoved(positionStart, itemCount); } } @Override public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { final BaseWrapperAdapter<VH> holder = mRefHolder.get(); if (holder != null) { holder.onWrappedAdapterRangeMoved(fromPosition, toPosition, itemCount); } } } }