android-advancedrecyclerview
android-advancedrecyclerview copied to clipboard
already have a wrapped adapter @ Recyclerview include Recyclerview
Dear All
Sorry for my English .
i need " Expandable " + "Drag" + "Swipe"
but i use that at Recyclerview include Recyclerview
the First layout -- only one Recyclerview with ViewType {Header / Body / Footer}
the Second layout @ Body ---use android-advancedrecyclerview
But !!! But !!! But !!!
The GroupViewHolder will bind position 1 two times !!!? ------> get already have a wrapped adapter ----> app crash
Yes !! only position 1 crash !!
if i remark "already have a wrapped adapter"
the position 1 not work !!!!!!!???
attach my project
PureExpandableDraggableSwipeableExampleFragment.java
or
the code is below
`
public class PureExpandableDraggableSwipeableExampleFragment extends Fragment { private static final String TAG = "PureExpandableDraggableSwipeableExampleFragment"; private static final String SAVED_STATE_EXPANDABLE_ITEM_MANAGER = "RecyclerViewExpandableItemManager"; private RecyclerViewExpandableItemManager mRecyclerViewExpandableItemManager; private TypeAdapter mAdapter;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
final Parcelable eimSavedState = (savedInstanceState != null) ? savedInstanceState.getParcelable(SAVED_STATE_EXPANDABLE_ITEM_MANAGER) : null;
mRecyclerViewExpandableItemManager = new RecyclerViewExpandableItemManager(eimSavedState);
final View root = inflater.inflate(R.layout.fragment_recycler_multi_type_view, container, false);
final RecyclerView typerecycle = (RecyclerView) root.findViewById(R.id.recycler_type);
typerecycle.setAdapter(mAdapter = new TypeAdapter());
return root;
}
private final class TypeAdapter extends RecyclerView.Adapter<TypeAdapter.ViewHolder> {
private final int[] mGroups = new int[]{R.layout.list_group_item_header_new, R.layout.layout_item_info, R.layout.list_group_item_footer};
public TypeAdapter() {
}
@Override
public int getItemCount() {
return mGroups.length;
}
@Override
public int getItemViewType(int position) {
return mGroups[position];
}
@Override
public TypeAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
switch (viewType) {
case R.layout.list_group_item_header_new:
return new HeaderViewHolder(view);
case R.layout.layout_item_info:
return new InfoViewHolder(view);
case R.layout.list_group_item_footer:
return new FooterViewHolder(view);
}
throw new IllegalArgumentException("no such view type...");
}
@Override
public void onBindViewHolder(TypeAdapter.ViewHolder holder, int position) {
holder.onBind(position);
}
@Override
public void onViewAttachedToWindow(ViewHolder holder) {
holder.onAttachedToWindow();
}
@Override
public void onViewDetachedFromWindow(ViewHolder holder) {
holder.onDetachedFromWindow();
}
@Override
public void onViewRecycled(final ViewHolder holder) {
holder.onRecycled();
}
public abstract class ViewHolder extends AbstractExpandableItemViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
public abstract void onBind(final int position);
public void onAttachedToWindow() {
}
public void onDetachedFromWindow() {
}
public void onRecycled() {
}
}
public class HeaderViewHolder extends ViewHolder {
private TextView mItineraryName;
private ImageView mItineraryImage;
private LinearLayout mNormalDateLayout;
private TextView mStartDate;
private TextView mEndDate;
private TextView mOTADaysText;
private ImageButton mEditItineraryButton;
private ImageButton mViewAllItineraryDetailButton;
public HeaderViewHolder(View itemView) {
super(itemView);
mItineraryName = (TextView) itemView.findViewById(R.id.itineraryName);
mItineraryImage = (ImageView) itemView.findViewById(R.id.itineraryImage);
mNormalDateLayout = (LinearLayout) itemView.findViewById(R.id.normalDateLayout);
mStartDate = (TextView) itemView.findViewById(R.id.startDateTextView);
mEndDate = (TextView) itemView.findViewById(R.id.endDateTextView);
mOTADaysText = (TextView) itemView.findViewById(R.id.otaDaysText);
mEditItineraryButton = (ImageButton) itemView.findViewById(R.id.editItineraryButton);
mViewAllItineraryDetailButton = (ImageButton) itemView.findViewById(R.id.viewAllItineraryDetailButton);
}
@Override
public void onBind(int position) {
}
}
public class InfoViewHolder extends ViewHolder implements RecyclerViewExpandableItemManager.OnGroupCollapseListener, RecyclerViewExpandableItemManager.OnGroupExpandListener {
private final ExampleExpandableDataProvider mDataProvider = new ExampleExpandableDataProvider();
private RecyclerView mDaysInfo;
private RecyclerView.Adapter mAdapter;
private RecyclerViewDragDropManager mRecyclerViewDragDropManager;
private RecyclerViewSwipeManager mRecyclerViewSwipeManager;
private RecyclerViewTouchActionGuardManager mRecyclerViewTouchActionGuardManager;
public InfoViewHolder(View v) {
super(v);
final Context context = itemView.getContext();
mDaysInfo = (RecyclerView) v.findViewById(R.id.item_section_info);
mDaysInfo.setItemAnimator(new SwipeDismissItemAnimator());
mRecyclerViewExpandableItemManager.setOnGroupExpandListener(this);
mRecyclerViewExpandableItemManager.setOnGroupCollapseListener(this);
}
@Override
public void onBind(int position) {
Log.d(TAG, "InfoViewHolder onBind Position : " + position);
final Context context = itemView.getContext();
//FIXME I Get crash !! will rebind position 1 !! ? let mWrappedAdapter crash !! info : already have a wrapped adapter
// Log.d(TAG, "InfoViewHolder onAttachedToWindow mWrappedAdapter : " + mWrappedAdapter);
// touch guard manager (this class is required to suppress scrolling while swipe-dismiss animation is running) mRecyclerViewTouchActionGuardManager = new RecyclerViewTouchActionGuardManager(); mRecyclerViewTouchActionGuardManager.setInterceptVerticalScrollingWhileAnimationRunning(true); mRecyclerViewTouchActionGuardManager.setEnabled(true); // drag & drop manager mRecyclerViewDragDropManager = new RecyclerViewDragDropManager(); mRecyclerViewDragDropManager.setDraggingItemShadowDrawable((NinePatchDrawable) ContextCompat.getDrawable(context, R.drawable.material_shadow_z3)); // swipe manager mRecyclerViewSwipeManager = new RecyclerViewSwipeManager(); // Wrappe final ExpandableDayListAdapter detailDaysAdapter = new ExpandableDayListAdapter(mDataProvider); detailDaysAdapter.attach(); mAdapter = detailDaysAdapter; RecyclerView.Adapter mwrappedAdapter = mRecyclerViewExpandableItemManager.createWrappedAdapter(detailDaysAdapter);// wrap for expanding mwrappedAdapter = mRecyclerViewSwipeManager.createWrappedAdapter(mwrappedAdapter); // wrap for swiping mwrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(mwrappedAdapter); // wrap for dragging // // NOTE: // // The initialization order is very important! This order determines the priority of touch event handling. priority: TouchActionGuard > Swipe > DragAndDrop > ExpandableItem mRecyclerViewTouchActionGuardManager.attachRecyclerView(mDaysInfo); mRecyclerViewSwipeManager.attachRecyclerView(mDaysInfo); mRecyclerViewDragDropManager.attachRecyclerView(mDaysInfo); mRecyclerViewExpandableItemManager.attachRecyclerView(mDaysInfo); mDaysInfo.swapAdapter(mwrappedAdapter, false); }
@Override
public void onAttachedToWindow() {
Log.d(TAG, "InfoViewHolder onAttachedToWindow Position : " + getAdapterPosition());
final Context context = itemView.getContext();
}
@Override
public void onDetachedFromWindow() {
Log.d(TAG, "InfoViewHolder onDetachedFromWindow Position : " + getAdapterPosition());
if (mRecyclerViewDragDropManager != null) {
mRecyclerViewDragDropManager.release();
mRecyclerViewDragDropManager = null;
}
if (mRecyclerViewSwipeManager != null) {
mRecyclerViewSwipeManager.release();
mRecyclerViewSwipeManager = null;
}
if (mRecyclerViewTouchActionGuardManager != null) {
mRecyclerViewTouchActionGuardManager.release();
mRecyclerViewTouchActionGuardManager = null;
}
// if (mRecyclerViewExpandableItemManager != null) { // mRecyclerViewExpandableItemManager.release(); // mRecyclerViewExpandableItemManager = null; // } // if (mWrappedAdapter != null) { // WrapperAdapterUtils.releaseAll(mWrappedAdapter); // mWrappedAdapter = null; // } mAdapter = null; }
@Override
public void onRecycled() {
Log.d(TAG, "InfoViewHolder onRecycled Position : " + getAdapterPosition());
}
@Override
public void onGroupCollapse(int groupPosition, boolean fromUser, Object payload) {
}
@Override
public void onGroupExpand(int groupPosition, boolean fromUser, Object payload) {
if (fromUser) {
adjustScrollPositionOnGroupExpanded(groupPosition);
}
}
private void adjustScrollPositionOnGroupExpanded(int groupPosition) {
final Context context = itemView.getContext();
int childItemHeight = context.getResources().getDimensionPixelSize(R.dimen.list_item_height);
int topMargin = (int) (context.getResources().getDisplayMetrics().density * 16); // top-spacing: 16dp
int bottomMargin = topMargin; // bottom-spacing: 16dp
mRecyclerViewExpandableItemManager.scrollToGroup(groupPosition, childItemHeight, topMargin, bottomMargin);
}
}
public class FooterViewHolder extends ViewHolder {
private TextView mAddDayText;
public FooterViewHolder(View v) {
super(v);
mAddDayText = (TextView) v.findViewById(R.id.addDayText);
}
@Override
public void onBind(int position) {
mAddDayText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// handleOnClickGroupItemAddAboveButton(groupPosition); } }); } } }
private final class ExpandableDayListAdapter extends AbstractExpandableItemAdapter<ExpandableDayListAdapter.GroupViewHolder, ExpandableDayListAdapter.ChildViewHolder> implements ExpandableDraggableItemAdapter<ExpandableDayListAdapter.GroupViewHolder, ExpandableDayListAdapter.ChildViewHolder>, ExpandableSwipeableItemAdapter<ExpandableDayListAdapter.GroupViewHolder, ExpandableDayListAdapter.ChildViewHolder> {
private ExampleExpandableDataProvider mDataProvider;
private final List<Pair<AbstractExpandableDataProvider.GroupData, List<AbstractExpandableDataProvider.ChildData>>> mDays;
private final int[] mGroupPositionColors = new int[]{R.color.mina_new_lake_blue, R.color.mina_new_pink, R.color.mina_new_green, R.color.mina_new_orange, R.color.mina_new_gray};
private final int[] mChildPositionColors = new int[]{R.color.mina_new_light_lake_blue, R.color.mina_new_light_pink, R.color.mina_new_light_green, R.color.mina_new_light_orange, R.color.mina_new_light_gray};
public ExpandableDayListAdapter(ExampleExpandableDataProvider dataprovider) {
super();
mDataProvider = dataprovider;
mDays = new LinkedList<>();
// ExpandableItemAdapter requires stable ID, and also
// have to implement the getGroupItemId()/getChildItemId() methods appropriately.
setHasStableIds(true);
}
public void attach() {
final int count = mDataProvider.getGroupCount();
for (int i = 0; i < count; i++) {
mDays.add(mDataProvider.getGroupChildsItem(i));
}
notifyDataSetChanged();
}
@Override
public int getGroupCount() {
return mDays.size();
}
@Override
public int getChildCount(int groupPosition) {
return mDays.get(groupPosition).second.size();
}
@Override
public long getGroupId(int groupPosition) {
return mDays.get(groupPosition).first.getGroupId();
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return mDays.get(groupPosition).second.get(childPosition).getChildId();
}
@Override
public GroupViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
return new GroupViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_group_item_draggable_new, parent, false));
}
@Override
public ChildViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
return new ChildViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_detail_first_new, parent, false));
}
@Override
public void onBindGroupViewHolder(final GroupViewHolder holder, int groupPosition, int viewType) {
final Context context = holder.itemView.getContext();
final int positioncolor = groupPosition % 5;
holder.mDay.setTextColor(context.getResources().getColor(mGroupPositionColors[positioncolor]));
holder.mDateInfo.setTextColor(context.getResources().getColor(mGroupPositionColors[positioncolor]));
}
@Override
public void onBindChildViewHolder(ChildViewHolder holder, int groupPosition, final int childPosition, int viewType) {
final Context context = holder.itemView.getContext();
final AbstractExpandableDataProvider.ChildData info = mDays.get(groupPosition).second.get(childPosition);
int typeColor = groupPosition % 5;
holder.mDivideLine.setBackgroundResource(mChildPositionColors[typeColor]);
holder.mPillarImage.setBackgroundResource(mChildPositionColors[typeColor]);
holder.mStartTimeText.setTextColor(context.getResources().getColor(mChildPositionColors[typeColor]));
holder.mNameText.setTextColor(context.getResources().getColor(mChildPositionColors[typeColor]));
holder.mNameText.setText(info.getText());
}
@Override
public boolean onCheckCanExpandOrCollapseGroup(GroupViewHolder holder, int groupPosition, int x, int y, boolean expand) {
return mDays.get(groupPosition).second != null;
}
@Override
public int onGetGroupItemSwipeReactionType(GroupViewHolder holder, int groupPosition, int x, int y) {
if (onCheckGroupCanStartDrag(holder, groupPosition, x, y)) {
return SwipeableItemConstants.REACTION_CAN_NOT_SWIPE_BOTH_H;
}
return SwipeableItemConstants.REACTION_CAN_SWIPE_BOTH_H;
}
@Override
public int onGetChildItemSwipeReactionType(ChildViewHolder holder, int groupPosition, int childPosition, int x, int y) {
return SwipeableItemConstants.REACTION_CAN_NOT_SWIPE_BOTH_H;
}
@Override
public void onSwipeGroupItemStarted(GroupViewHolder holder, int groupPosition) {
notifyDataSetChanged();
}
@Override
public void onSwipeChildItemStarted(ChildViewHolder holder, int groupPosition, int childPosition) {
Log.d(TAG, "onSwipeChildItemStarted Child can not swipe");
}
@Override
public void onSetGroupItemSwipeBackground(GroupViewHolder holder, int groupPosition, int type) {
Log.d(TAG, "onSetGroupItemSwipeBackground");
}
@Override
public void onSetChildItemSwipeBackground(ChildViewHolder holder, int groupPosition, int childPosition, int type) {
Log.d(TAG, "onSetChildItemSwipeBackground");
}
@Override
public boolean onCheckGroupCanStartDrag(GroupViewHolder holder, int groupPosition, int x, int y) {
final View containerView = holder.mContainer;
final int offsetX = containerView.getLeft() + (int) (containerView.getTranslationX() + 0.5f);
final int offsetY = containerView.getTop() + (int) (containerView.getTranslationY() + 0.5f);
return ViewUtils.hitTest(containerView, x - offsetX, y - offsetY);
}
@Override
public boolean onCheckChildCanStartDrag(ChildViewHolder holder, int groupPosition, int childPosition, int x, int y) {
final View containerView = holder.mContainer;
final int offsetX = containerView.getLeft() + (int) (containerView.getTranslationX() + 0.5f);
final int offsetY = containerView.getTop() + (int) (containerView.getTranslationY() + 0.5f);
return ViewUtils.hitTest(containerView, x - offsetX, y - offsetY);
}
@Override
public ItemDraggableRange onGetGroupItemDraggableRange(GroupViewHolder holder, int groupPosition) {
return null;
}
@Override
public ItemDraggableRange onGetChildItemDraggableRange(ChildViewHolder holder, int groupPosition, int childPosition) {
return null;
}
@Override
public void onMoveGroupItem(int fromGroupPosition, int toGroupPosition) {
Log.d(TAG, "onMoveGroupItem");
}
@Override
public void onMoveChildItem(int fromGroupPosition, int fromChildPosition, int toGroupPosition, int toChildPosition) {
Log.d(TAG, "onMoveChildItem");
}
@Override
public boolean onCheckGroupCanDrop(int draggingGroupPosition, int dropGroupPosition) {
return false;
}
@Override
public boolean onCheckChildCanDrop(int draggingGroupPosition, int draggingChildPosition, int dropGroupPosition, int dropChildPosition) {
return true;
}
@Override
public void onGroupDragStarted(int groupPosition) {
notifyDataSetChanged();
}
@Override
public void onChildDragStarted(int groupPosition, int childPosition) {
notifyDataSetChanged();
}
@Override
public void onGroupDragFinished(int fromGroupPosition, int toGroupPosition, boolean result) {
notifyDataSetChanged();
}
@Override
public void onChildDragFinished(int fromGroupPosition, int fromChildPosition, int toGroupPosition, int toChildPosition, boolean result) {
notifyDataSetChanged();
}
@Override
public SwipeResultAction onSwipeGroupItem(GroupViewHolder holder, int groupPosition, int result) {
Log.d(TAG, "onSwipeGroupItem(groupPosition = " + groupPosition + ", result = " + result + ")");
switch (result) {
// swipe right
case SwipeableItemConstants.RESULT_SWIPED_RIGHT:
// if (mProvider.getGroupItem(groupPosition).isPinned()) { // // pinned --- back to default position // return new GroupUnpinResultAction(this, groupPosition); // } else { // return null; // } // swipe left -- pin return null; case SwipeableItemConstants.RESULT_SWIPED_LEFT: // return new GroupSwipeLeftResultAction(this, groupPosition); return null; // other --- do nothing case SwipeableItemConstants.RESULT_CANCELED: default: // if (groupPosition != RecyclerView.NO_POSITION) { // return new GroupUnpinResultAction(this, groupPosition); // } else { // return null; // } return null; } }
@Override
public SwipeResultAction onSwipeChildItem(ChildViewHolder holder, int groupPosition, int childPosition, int result) {
Log.d(TAG, "onSwipeChildItem(groupPosition = " + groupPosition + ", childPosition = " + childPosition + ", result = " + result + ")");
return null;
}
private abstract class ExpandableDraggableSwipeableViewHolder extends AbstractDraggableSwipeableItemViewHolder implements ExpandableItemViewHolder {
public ConstraintLayout mContainer;
public View mDragHandle;
@ExpandableItemStateFlags
private int mExpandStateFlags;
@DraggableItemStateFlags
private int mDragStateFlags;
public ExpandableDraggableSwipeableViewHolder(View v) {
super(v);
mContainer = v.findViewById(R.id.container);
mDragHandle = v.findViewById(R.id.drag_handle);
}
@Override
public int getExpandStateFlags() {
return mExpandStateFlags;
}
@Override
public void setExpandStateFlags(int flag) {
mExpandStateFlags = flag;
}
@Override
public View getSwipeableContainerView() {
return mContainer;
}
@Override
public void setDragStateFlags(int flags) {
mDragStateFlags = flags;
}
@Override
public int getDragStateFlags() {
return mDragStateFlags;
}
}
public class GroupViewHolder extends ExpandableDraggableSwipeableViewHolder {
private final SparseBooleanArray mSelectedItems;
private TextView mDay;
private TextView mDateInfo;
private ImageView mDashLine;
private ImageView mState;
private ImageButton mDeleteDayButton;
public GroupViewHolder(View v) {
super(v);
mSelectedItems = new SparseBooleanArray();
mDay = (TextView) v.findViewById(R.id.day);
mDateInfo = (TextView) v.findViewById(R.id.dateinfo);
mDashLine = (ImageView) v.findViewById(R.id.dashLine);
mState = (ImageView) v.findViewById(R.id.state);
mDeleteDayButton = (ImageButton) v.findViewById(R.id.deleteDayButton);
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "TripScheduleViewHolder GroupViewHolder itemview click ");
int flatPosition = getAdapterPosition();
if (flatPosition == RecyclerView.NO_POSITION) {
return;
}
long expandablePosition = mRecyclerViewExpandableItemManager.getExpandablePosition(flatPosition);
final int groupPosition = RecyclerViewExpandableItemManager.getPackedPositionGroup(expandablePosition);
final int childPosition = RecyclerViewExpandableItemManager.getPackedPositionChild(expandablePosition);
if (childPosition == RecyclerView.NO_POSITION) {
expandablePosition = RecyclerViewExpandableItemManager.getPackedPositionForGroup(groupPosition);
flatPosition = mRecyclerViewExpandableItemManager.getFlatPosition(expandablePosition);
mAdapter.notifyItemChanged(flatPosition);
} else {
Log.d(TAG, "has childPosition !! ChildItemChanged ??");
expandablePosition = RecyclerViewExpandableItemManager.getPackedPositionForChild(groupPosition, childPosition);
flatPosition = mRecyclerViewExpandableItemManager.getFlatPosition(expandablePosition);
mAdapter.notifyItemChanged(flatPosition);
}
final boolean isselected = mSelectedItems.get(flatPosition);
Log.d(TAG, "Show click Pinned " + isselected);
Log.d(TAG, "Show click Pinned save " + mSelectedItems);
if (!isselected) {
mSelectedItems.put(flatPosition, true);
} else {
mSelectedItems.delete(flatPosition);
}
Log.d(TAG, "Show click Pinned save d " + mSelectedItems);
}
});
// set swiping properties
// holder.setSwipeItemHorizontalSlideAmount( // item.isPinned() ? Swipeable.OUTSIDE_OF_THE_WINDOW_LEFT : 0); setMaxLeftSwipeAmount(-0.15f); // setSwipeItemHorizontalSlideAmount( item.isPinned() ? -0.15f : 0); } }
public class ChildViewHolder extends ExpandableDraggableSwipeableViewHolder {
public TextView mNameText;
public ImageView mDivideLine;
public ImageView mPillarImage;
public ImageView mCategoryImage;
public ConstraintLayout mInnerLayout;
public TextView mOrderText;
public TextView mStartTimeText;
public TextView mStayTimeText;
public ImageButton mTrafficButton;
public TextView mTrafficTimeText;
public ImageButton mBuyButton;
public ImageButton mAlarmButton;
public ImageButton mDeleteButton;
public ChildViewHolder(View itemView) {
super(itemView);
mNameText = (TextView) itemView.findViewById(R.id.nameText);
mDivideLine = (ImageView) itemView.findViewById(R.id.divideLine);
mPillarImage = (ImageView) itemView.findViewById(R.id.pillarImage);
mCategoryImage = (ImageView) itemView.findViewById(R.id.categoryImage);
mStartTimeText = (TextView) itemView.findViewById(R.id.startTimeText);
mStayTimeText = (TextView) itemView.findViewById(R.id.stayTimeText);
mInnerLayout = (ConstraintLayout) itemView.findViewById(R.id.innerLayout);
mOrderText = (TextView) itemView.findViewById(R.id.orderText);
mTrafficButton = (ImageButton) itemView.findViewById(R.id.trafficButton);
mTrafficTimeText = (TextView) itemView.findViewById(R.id.trafficTimeText);
mBuyButton = (ImageButton) itemView.findViewById(R.id.buyButton);
mAlarmButton = (ImageButton) itemView.findViewById(R.id.alarmButton);
mDeleteButton = (ImageButton) itemView.findViewById(R.id.deleteButton);
}
}
}
}
`