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.h6ah4i.android.example.advrecyclerview.demo_eds; import android.graphics.drawable.NinePatchDrawable; import android.os.Build; import android.os.Bundle; import android.os.Parcelable; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.content.ContextCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.h6ah4i.android.example.advrecyclerview.R; import com.h6ah4i.android.example.advrecyclerview.common.data.AbstractExpandableDataProvider; import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator; import com.h6ah4i.android.widget.advrecyclerview.animator.SwipeDismissItemAnimator; import com.h6ah4i.android.widget.advrecyclerview.decoration.ItemShadowDecorator; import com.h6ah4i.android.widget.advrecyclerview.decoration.SimpleListDividerDecorator; import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager; import com.h6ah4i.android.widget.advrecyclerview.expandable.RecyclerViewExpandableItemManager; import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager; import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchActionGuardManager; import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils; public class RecyclerListViewFragment extends Fragment implements RecyclerViewExpandableItemManager.OnGroupCollapseListener, RecyclerViewExpandableItemManager.OnGroupExpandListener { private static final String SAVED_STATE_EXPANDABLE_ITEM_MANAGER = "RecyclerViewExpandableItemManager"; private RecyclerView mRecyclerView; private RecyclerView.LayoutManager mLayoutManager; private RecyclerView.Adapter mAdapter; private RecyclerView.Adapter mWrappedAdapter; private RecyclerViewExpandableItemManager mRecyclerViewExpandableItemManager; private RecyclerViewDragDropManager mRecyclerViewDragDropManager; private RecyclerViewSwipeManager mRecyclerViewSwipeManager; private RecyclerViewTouchActionGuardManager mRecyclerViewTouchActionGuardManager; public RecyclerListViewFragment() { super(); } @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_recycler_list_view, container, false); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); //noinspection ConstantConditions mRecyclerView = (RecyclerView) getView().findViewById(R.id.recycler_view); mLayoutManager = new LinearLayoutManager(getContext()); final Parcelable eimSavedState = (savedInstanceState != null) ? savedInstanceState.getParcelable(SAVED_STATE_EXPANDABLE_ITEM_MANAGER) : null; mRecyclerViewExpandableItemManager = new RecyclerViewExpandableItemManager(eimSavedState); mRecyclerViewExpandableItemManager.setOnGroupExpandListener(this); mRecyclerViewExpandableItemManager.setOnGroupCollapseListener(this); // 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(getContext(), R.drawable.material_shadow_z3)); // swipe manager mRecyclerViewSwipeManager = new RecyclerViewSwipeManager(); //adapter final MyExpandableDraggableSwipeableItemAdapter myItemAdapter = new MyExpandableDraggableSwipeableItemAdapter( mRecyclerViewExpandableItemManager, getDataProvider()); myItemAdapter.setEventListener(new MyExpandableDraggableSwipeableItemAdapter.EventListener() { @Override public void onGroupItemRemoved(int groupPosition) { ((ExpandableDraggableSwipeableExampleActivity) getActivity()).onGroupItemRemoved(groupPosition); } @Override public void onChildItemRemoved(int groupPosition, int childPosition) { ((ExpandableDraggableSwipeableExampleActivity) getActivity()).onChildItemRemoved(groupPosition, childPosition); } @Override public void onGroupItemPinned(int groupPosition) { ((ExpandableDraggableSwipeableExampleActivity) getActivity()).onGroupItemPinned(groupPosition); } @Override public void onChildItemPinned(int groupPosition, int childPosition) { ((ExpandableDraggableSwipeableExampleActivity) getActivity()).onChildItemPinned(groupPosition, childPosition); } @Override public void onItemViewClicked(View v, boolean pinned) { onItemViewClick(v, pinned); } }); mAdapter = myItemAdapter; mWrappedAdapter = mRecyclerViewExpandableItemManager.createWrappedAdapter(myItemAdapter); // wrap for expanding mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(mWrappedAdapter); // wrap for dragging mWrappedAdapter = mRecyclerViewSwipeManager.createWrappedAdapter(mWrappedAdapter); // wrap for swiping final GeneralItemAnimator animator = new SwipeDismissItemAnimator(); // Change animations are enabled by default since support-v7-recyclerview v22. // Disable the change animation in order to make turning back animation of swiped item works properly. // Also need to disable them when using animation indicator. animator.setSupportsChangeAnimations(false); mRecyclerView.setLayoutManager(mLayoutManager); mRecyclerView.setAdapter(mWrappedAdapter); // requires *wrapped* adapter mRecyclerView.setItemAnimator(animator); mRecyclerView.setHasFixedSize(false); // additional decorations //noinspection StatementWithEmptyBody if (supportsViewElevation()) { // Lollipop or later has native drop shadow feature. ItemShadowDecorator is not required. } else { mRecyclerView.addItemDecoration(new ItemShadowDecorator( (NinePatchDrawable) ContextCompat.getDrawable(getContext(), R.drawable.material_shadow_z1))); } mRecyclerView.addItemDecoration(new SimpleListDividerDecorator( ContextCompat.getDrawable(getContext(), R.drawable.list_divider_h), true)); // NOTE: // The initialization order is very important! This order determines the priority of touch event handling. // // priority: TouchActionGuard > Swipe > DragAndDrop > ExpandableItem mRecyclerViewTouchActionGuardManager.attachRecyclerView(mRecyclerView); mRecyclerViewSwipeManager.attachRecyclerView(mRecyclerView); mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView); mRecyclerViewExpandableItemManager.attachRecyclerView(mRecyclerView); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // save current state to support screen rotation, etc... if (mRecyclerViewExpandableItemManager != null) { outState.putParcelable(SAVED_STATE_EXPANDABLE_ITEM_MANAGER, mRecyclerViewExpandableItemManager.getSavedState()); } } @Override public void onDestroyView() { 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 (mRecyclerView != null) { mRecyclerView.setItemAnimator(null); mRecyclerView.setAdapter(null); mRecyclerView = null; } if (mWrappedAdapter != null) { WrapperAdapterUtils.releaseAll(mWrappedAdapter); mWrappedAdapter = null; } mAdapter = null; mLayoutManager = null; super.onDestroyView(); } @Override public void onGroupCollapse(int groupPosition, boolean fromUser) { } @Override public void onGroupExpand(int groupPosition, boolean fromUser) { if (fromUser) { adjustScrollPositionOnGroupExpanded(groupPosition); } } private void adjustScrollPositionOnGroupExpanded(int groupPosition) { int childItemHeight = getActivity().getResources().getDimensionPixelSize(R.dimen.list_item_height); int topMargin = (int) (getActivity().getResources().getDisplayMetrics().density * 16); // top-spacing: 16dp int bottomMargin = topMargin; // bottom-spacing: 16dp mRecyclerViewExpandableItemManager.scrollToGroup(groupPosition, childItemHeight, topMargin, bottomMargin); } private void onItemViewClick(View v, boolean pinned) { final int flatPosition = mRecyclerView.getChildAdapterPosition(v); if (flatPosition == RecyclerView.NO_POSITION) { return; } final long expandablePosition = mRecyclerViewExpandableItemManager.getExpandablePosition(flatPosition); final int groupPosition = RecyclerViewExpandableItemManager.getPackedPositionGroup(expandablePosition); final int childPosition = RecyclerViewExpandableItemManager.getPackedPositionChild(expandablePosition); if (childPosition == RecyclerView.NO_POSITION) { ((ExpandableDraggableSwipeableExampleActivity) getActivity()).onGroupItemClicked(groupPosition); } else { ((ExpandableDraggableSwipeableExampleActivity) getActivity()).onChildItemClicked(groupPosition, childPosition); } } private boolean supportsViewElevation() { return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP); } public AbstractExpandableDataProvider getDataProvider() { return ((ExpandableDraggableSwipeableExampleActivity) getActivity()).getDataProvider(); } public void notifyGroupItemRestored(int groupPosition) { mAdapter.notifyDataSetChanged(); final long expandablePosition = RecyclerViewExpandableItemManager.getPackedPositionForGroup(groupPosition); final int flatPosition = mRecyclerViewExpandableItemManager.getFlatPosition(expandablePosition); mRecyclerView.scrollToPosition(flatPosition); } public void notifyChildItemRestored(int groupPosition, int childPosition) { mAdapter.notifyDataSetChanged(); final long expandablePosition = RecyclerViewExpandableItemManager.getPackedPositionForChild(groupPosition, childPosition); final int flatPosition = mRecyclerViewExpandableItemManager.getFlatPosition(expandablePosition); mRecyclerView.scrollToPosition(flatPosition); } public void notifyGroupItemChanged(int groupPosition) { final long expandablePosition = RecyclerViewExpandableItemManager.getPackedPositionForGroup(groupPosition); final int flatPosition = mRecyclerViewExpandableItemManager.getFlatPosition(expandablePosition); mAdapter.notifyItemChanged(flatPosition); } public void notifyChildItemChanged(int groupPosition, int childPosition) { final long expandablePosition = RecyclerViewExpandableItemManager.getPackedPositionForChild(groupPosition, childPosition); final int flatPosition = mRecyclerViewExpandableItemManager.getFlatPosition(expandablePosition); mAdapter.notifyItemChanged(flatPosition); } }