Java tutorial
/* * 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.lzh.yuanstrom.adapter; import android.support.v4.view.ViewCompat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TextView; import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemConstants; import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange; import com.h6ah4i.android.widget.advrecyclerview.expandable.ExpandableDraggableItemAdapter; import com.h6ah4i.android.widget.advrecyclerview.expandable.ExpandableItemConstants; import com.h6ah4i.android.widget.advrecyclerview.expandable.ExpandableItemViewHolder; import com.h6ah4i.android.widget.advrecyclerview.expandable.RecyclerViewExpandableItemManager; import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder; import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractExpandableItemAdapter; import com.h6ah4i.android.widget.advrecyclerview.utils.RecyclerViewAdapterUtils; import com.lzh.yuanstrom.R; import com.lzh.yuanstrom.bean.SimpleDeviceBean; import com.lzh.yuanstrom.common.AbstractExpandableDataProvider; import com.lzh.yuanstrom.common.ExampleExpandableDataProvider; import com.lzh.yuanstrom.utils.DrawableUtils; import com.lzh.yuanstrom.utils.ViewUtils; import com.lzh.yuanstrom.widget.ExpandableItemIndicator; import static com.h6ah4i.android.widget.advrecyclerview.expandable.ExpandableItemConstants.STATE_FLAG_HAS_EXPANDED_STATE_CHANGED; public class ExpandableDraggableSwipeableExampleAdapter extends AbstractExpandableItemAdapter<ExpandableDraggableSwipeableExampleAdapter.MyGroupViewHolder, ExpandableDraggableSwipeableExampleAdapter.MyChildViewHolder> implements ExpandableDraggableItemAdapter<ExpandableDraggableSwipeableExampleAdapter.MyGroupViewHolder, ExpandableDraggableSwipeableExampleAdapter.MyChildViewHolder> { private static final String TAG = "MyEDSItemAdapter"; // NOTE: Make accessible with short name private interface Expandable extends ExpandableItemConstants { } private interface Draggable extends DraggableItemConstants { } private ExampleExpandableDataProvider mProvider; private EventListener mEventListener; private View.OnClickListener mItemViewOnClickListener; private View.OnClickListener mSwipeableViewContainerOnClickListener; public interface EventListener { void onItemViewClicked(View v, boolean pinned); } public static abstract class MyBaseViewHolder extends AbstractDraggableSwipeableItemViewHolder implements ExpandableItemViewHolder { public FrameLayout mContainer; public View mDragHandle; public TextView mTextView; private int mExpandStateFlags; public MyBaseViewHolder(View v) { super(v); mContainer = (FrameLayout) v.findViewById(R.id.container); mDragHandle = v.findViewById(R.id.drag_handle); mTextView = (TextView) v.findViewById(android.R.id.text1); } @Override public int getExpandStateFlags() { return mExpandStateFlags; } @Override public void setExpandStateFlags(int flag) { mExpandStateFlags = flag; } @Override public View getSwipeableContainerView() { return mContainer; } } public static class MyGroupViewHolder extends MyBaseViewHolder { public ExpandableItemIndicator mIndicator; public MyGroupViewHolder(View v) { super(v); mIndicator = (ExpandableItemIndicator) v.findViewById(R.id.indicator); } } public static class MyChildViewHolder extends MyBaseViewHolder { public MyChildViewHolder(View v) { super(v); } } public ExpandableDraggableSwipeableExampleAdapter(RecyclerViewExpandableItemManager expandableItemManager, ExampleExpandableDataProvider dataProvider) { mProvider = dataProvider; mItemViewOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { onItemViewClick(v); } }; mSwipeableViewContainerOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { onSwipeableViewContainerClick(v); } }; // ExpandableItemAdapter, ExpandableDraggableItemAdapter and ExpandableSwipeableItemAdapter // require stable ID, and also have to implement the getGroupItemId()/getChildItemId() methods appropriately. setHasStableIds(true); } private void onItemViewClick(View v) { if (mEventListener != null) { mEventListener.onItemViewClicked(v, true); // true --- pinned } } private void onSwipeableViewContainerClick(View v) { if (mEventListener != null) { mEventListener.onItemViewClicked(RecyclerViewAdapterUtils.getParentViewHolderItemView(v), false); // false --- not pinned } } @Override public int getGroupCount() { return mProvider.getGroupCount(); } @Override public int getChildCount(int groupPosition) { return mProvider.getChildCount(groupPosition); } @Override public long getGroupId(int groupPosition) { return mProvider.getGroupItem(groupPosition).getGroupId(); } @Override public long getChildId(int groupPosition, int childPosition) { return mProvider.getChildItem(groupPosition, childPosition).getId(); } @Override public int getGroupItemViewType(int groupPosition) { return 0; } @Override public int getChildItemViewType(int groupPosition, int childPosition) { return 0; } @Override public MyGroupViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) { final LayoutInflater inflater = LayoutInflater.from(parent.getContext()); final View v = inflater.inflate(R.layout.list_group_item_draggable, parent, false); MyGroupViewHolder groupViewHolder = new MyGroupViewHolder(v); return groupViewHolder; } @Override public MyChildViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) { final LayoutInflater inflater = LayoutInflater.from(parent.getContext()); final View v = inflater.inflate(R.layout.list_item_draggable, parent, false); return new MyChildViewHolder(v); } @Override public void onBindGroupViewHolder(MyGroupViewHolder holder, int groupPosition, int viewType) { // group item final AbstractExpandableDataProvider.GroupData item = mProvider.getGroupItem(groupPosition); // set listeners holder.itemView.setOnClickListener(mItemViewOnClickListener); // set text holder.mTextView.setText(item.getText()); // set background resource (target view ID: container) final int dragState = holder.getDragStateFlags(); final int expandState = holder.getExpandStateFlags(); if (((dragState & Draggable.STATE_FLAG_IS_UPDATED) != 0) || ((expandState & Expandable.STATE_FLAG_IS_UPDATED) != 0)) { int bgResId; boolean isExpanded; boolean animateIndicator = ((expandState & STATE_FLAG_HAS_EXPANDED_STATE_CHANGED) != 0); if ((dragState & Draggable.STATE_FLAG_IS_ACTIVE) != 0) { bgResId = R.drawable.bg_group_item_dragging_active_state; // need to clear drawable state here to get correct appearance of the dragging item. DrawableUtils.clearState(holder.mContainer.getForeground()); } else if ((dragState & Draggable.STATE_FLAG_DRAGGING) != 0) { bgResId = R.drawable.bg_group_item_dragging_state; } else if ((expandState & Expandable.STATE_FLAG_IS_EXPANDED) != 0) { bgResId = R.drawable.bg_group_item_expanded_state; } else { bgResId = R.drawable.bg_group_item_normal_state; } if ((expandState & Expandable.STATE_FLAG_IS_EXPANDED) != 0) { isExpanded = true; } else { isExpanded = false; } holder.mContainer.setBackgroundResource(bgResId); holder.mIndicator.setExpandedState(isExpanded, animateIndicator); } } @Override public void onBindChildViewHolder(MyChildViewHolder holder, int groupPosition, int childPosition, int viewType) { // child item final SimpleDeviceBean item = mProvider.getChildItem(groupPosition, childPosition); // set listeners // (if the item is *pinned*, click event comes to the itemView) holder.itemView.setOnClickListener(mItemViewOnClickListener); // (if the item is *not pinned*, click event comes to the mContainer) holder.mContainer.setOnClickListener(mSwipeableViewContainerOnClickListener); // set text holder.mTextView.setText(item.getDevName()); final int dragState = holder.getDragStateFlags(); if (((dragState & Draggable.STATE_FLAG_IS_UPDATED) != 0)) { int bgResId; if ((dragState & Draggable.STATE_FLAG_IS_ACTIVE) != 0) { bgResId = R.drawable.bg_item_dragging_active_state; // need to clear drawable state here to get correct appearance of the dragging item. DrawableUtils.clearState(holder.mContainer.getForeground()); } else if ((dragState & Draggable.STATE_FLAG_DRAGGING) != 0) { bgResId = R.drawable.bg_item_dragging_state; } else { bgResId = R.drawable.bg_item_normal_state; } holder.mContainer.setBackgroundResource(bgResId); } } @Override public boolean onCheckCanExpandOrCollapseGroup(MyGroupViewHolder holder, int groupPosition, int x, int y, boolean expand) { // check the item is *not* pinned if (mProvider.getGroupItem(groupPosition).isPinned()) { // return false to raise View.OnClickListener#onClick() event return false; } // check is enabled if (!(holder.itemView.isEnabled() && holder.itemView.isClickable())) { return false; } final View containerView = holder.mContainer; final View dragHandleView = holder.mDragHandle; final int offsetX = containerView.getLeft() + (int) (ViewCompat.getTranslationX(containerView) + 0.5f); final int offsetY = containerView.getTop() + (int) (ViewCompat.getTranslationY(containerView) + 0.5f); return !ViewUtils.hitTest(dragHandleView, x - offsetX, y - offsetY); } @Override public boolean onCheckGroupCanStartDrag(MyGroupViewHolder holder, int groupPosition, int x, int y) { // x, y --- relative from the itemView's top-left final View containerView = holder.mContainer; final View dragHandleView = holder.mDragHandle; final int offsetX = containerView.getLeft() + (int) (ViewCompat.getTranslationX(containerView) + 0.5f); final int offsetY = containerView.getTop() + (int) (ViewCompat.getTranslationY(containerView) + 0.5f); return ViewUtils.hitTest(dragHandleView, x - offsetX, y - offsetY); } @Override public boolean onCheckChildCanStartDrag(MyChildViewHolder holder, int groupPosition, int childPosition, int x, int y) { // x, y --- relative from the itemView's top-left final View containerView = holder.mContainer; final View dragHandleView = holder.mDragHandle; final int offsetX = containerView.getLeft() + (int) (ViewCompat.getTranslationX(containerView) + 0.5f); final int offsetY = containerView.getTop() + (int) (ViewCompat.getTranslationY(containerView) + 0.5f); return ViewUtils.hitTest(dragHandleView, x - offsetX, y - offsetY); } @Override public ItemDraggableRange onGetGroupItemDraggableRange(MyGroupViewHolder holder, int groupPosition) { // no drag-sortable range specified return null; } @Override public ItemDraggableRange onGetChildItemDraggableRange(MyChildViewHolder holder, int groupPosition, int childPosition) { // no drag-sortable range specified return null; } @Override public boolean onCheckGroupCanDrop(int draggingGroupPosition, int dropGroupPosition) { return true; } @Override public boolean onCheckChildCanDrop(int draggingGroupPosition, int draggingChildPosition, int dropGroupPosition, int dropChildPosition) { return true; } @Override public void onMoveGroupItem(int fromGroupPosition, int toGroupPosition) { mProvider.moveGroupItem(fromGroupPosition, toGroupPosition); } @Override public void onMoveChildItem(int fromGroupPosition, int fromChildPosition, int toGroupPosition, int toChildPosition) { mProvider.moveChildItem(fromGroupPosition, fromChildPosition, toGroupPosition, toChildPosition); } public void setEventListener(EventListener eventListener) { mEventListener = eventListener; } public ExampleExpandableDataProvider getProvider() { return mProvider; } }