Achieve drag effect two: use RecyclerView + ItemTouchHelper drag, delete, slide delete effect
Because demo adapted to the company’s business, the specific layer is not easy to put out, uncomfortable. But after all, this is just a record of learning, it is good to know the realization of their own!
I used to use GridView to achieve drag and drop effect, but actually there was a problem, which involved my own business at that time, so it was difficult to implement using that, so I found this.
The GridView has a problem with horizontal scrolling, paging, and drag and drop swaps. Different tragers are also possible, but not very convenient, so using ItemTouchHelper is very convenient. Horizontal scrolling paging use RecyclerView+ItemTouchHelper itself is much simpler than GridView implementation, and is Google official support, no panic.
In order to complete those aspects, we need to pay attention to the following points:
- To decouple! Don’t uninstall a whole bunch of files in one or two Java files, looking at the skull pain, let the person who took over the head maintenance.
- Implementation of business requirements: paging and spacing. Interval is essential, secondly used recyclerView all know that recyclerView can be arbitrary scrolling, to achieve paging, like GridView+ViewPage effect, that can not make it can be arbitrary scrolling, but the number of columns in a scrolling response (because I here is horizontal scrolling, Vertical similar).
- Interactive effects also need to vibrate, change the background color and so on
- Persist, click copy heavy and so on
This implementation method is much simpler than GridView implementation, mainly code decoupling ah, understand the following recyclerView and ItemTouchHelper understanding ah and specific business requirements.
The decoupling
To decouple first, my file directory is as follows:
From the top down
- Helper for paging effects
- The adapter
- This is the integrated ItemTouchHelper. Callback that implements the drag effect.
- The interface between itemTouchHelper and the adapter is decoupled and the adapter does all the work
- interval
ItemTouchHelper implementation
ItemTouchHelper is a wrapper class that Google encapsulated for us and implemented by recyclerView that can drag and drop items and swipe to delete items.
We’ll do this by integrating the ItemTouchHelper.callback interface.
There are three functions that must be done:
- GetMovementFlags: Sets drag and slide directions.
- OnMove: drag-and-drop monitor when moving.
- OnSwiped: Enables sliding deletion
In addition, we need to implement the following superclass functions:
- IsLongPressDragEnabled () : Whether long press deletion is supported (not possible)
- IsItemViewSwipeEnable () : whether or not swipeenable is supported.
- OnSelectdChanged () : This method is called when it is selected, where long press the selection to vibrate, change the background, and so on
- ClearView () : The event is over and the Up finger is Up. This is also a call to the cancel action that implements onSelectedChanged to set the background color change
- OnChildDraw (): Implement your own custom interaction rules here, or animation effects here, I finished dragging and removing custom interaction effects here.
The complete source code is as follows, with specific comments:
public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback { private MyItemTouchHelperListener mListener; // The interface between the adapter and itemTouchHelper is decoupled. private Boolean up; public MyItemTouchHelperCallback(MyItemTouchHelperListener mListener){ this.mListener = mListener; } @param recyclerView @param viewHolder @return @override public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { int dragFlags = 0; int swipeFlags = ItemTouchHelper.UP; if (recyclerView.getLayoutManager() instanceof GridLayoutManager || recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager){ dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT; } else { dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; } return makeMovementFlags(dragFlags,swipeFlags); } @param recyclerView @param viewHolder @param target @return */ @override public Boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { int fromPosition = viewHolder.getAdapterPosition(); int toPosition = target.getAdapterPosition(); mListener.onItemMove(fromPosition,toPosition); return true; } @override public void onSwiped(@nonnull recyclerView.viewholder viewHolder, int direction) { // mListener.onItemDelete(viewHolder.getAdapterPosition()); } @override public Boolean isLongPressDragEnabled(){return true; } @override public Boolean isItemViewSwipeEnabled(){return false; } /** * when selected, Call @param viewHolder @param actionState @override public void onSelectedChanged(@nullable) Recyclerview. ViewHolder ViewHolder, int actionState) {// if (actionState! = ItemTouchHelper.ACTION_STATE_IDLE){ up = false; mListener.onSelectedItem(viewHolder); } super.onSelectedChanged(viewHolder, actionState); } @param recyclerView @param viewHolder @override public void clearView(@nonnull recyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { mListener.onSelectedFinish(viewHolder); super.clearView(recyclerView, viewHolder); } @override public void onChildDraw(@nonnull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { if (mListener == null) return; // Log.d(TAG, "onChildDraw:dY " + dY); / / because dY is itself to coordinate, so as long as he is negative, the upward downward for positive, so to / / records related changes, control has draw the interface is completely delete int result = viewHolder. ItemView. GetBottom (); float res = result+dY; int index = viewHolder.getAdapterPosition(); // Log.d(TAG, "onChildDraw:Result " + res); // Log.d(TAG, "onChildDraw:Position " + viewHolder.getAdapterPosition()); If (res < 0){if (up){// If (up){// If (up){// If (up){// If (up){// If (up){// If (up){// If (up){// If (up){// If (up){// If (up){// MListener.onItemDelete (index); up = false; } // Log.d(TAG, "onChildDraw: "+index); } super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); } @Override public long getAnimationDuration(RecyclerView recyclerView, int animationType, float animateDx, Float animateDy) {float animateDy = true; return super.getAnimationDuration(recyclerView, animationType, animateDx, animateDy); }}Copy the code
This is the interface between the adapter and itemTouchHelper
The following interfaces are implemented in adapter and then used in itemTouchHelper to decouple.
Public interface MyItemTouchHelperListener {/ * * * listening to drag events * itemMovie * / void onItemMove (int fromPosition, int toPosition); Void onItemDelete(int position); /** * onItemDelete(int position); / / void onSelectedItem(recyclerView.viewholder ViewHolder); / / void onSelectedFinish(recyclerView.viewholder ViewHolder); }Copy the code
Here is the Adapter implementation
The mData custom serialization implementation here is more convenient to use string directly. Of course, I also put out the corresponding bean.
public class MyItemTouchHelperAdapter extends RecyclerView.Adapter<MyItemTouchHelperAdapter.ItemViewHolder> implements MyItemTouchHelperListener { private ArrayList<ItemData> mData; private Context mContext; private OnItemClickListener mOnItemClickListener; public MyItemTouchHelperAdapter(Context mContext,ArrayList<ItemData> mData){ this.mData = mData; this.mContext = mContext; } class ItemViewHolder extends RecyclerView.ViewHolder{ TextView textView; ImageView imageView; public ItemViewHolder(@NonNull View itemView) { super(itemView); textView = itemView.findViewById(R.id.tv_item_recyclerView); imageView = itemView.findViewById(R.id.iv_item_recyclerView); }} public void onItemMove(int) {public void onItemMove(int) fromPosition, int toPosition) { if (fromPosition < toPosition) { for (int i = fromPosition; i < toPosition; i++) { Collections.swap(mData, i, i + 1); } } else { for (int i = fromPosition; i > toPosition; i--) { Collections.swap(mData, i, i - 1); } } updateDataHome(); notifyItemMoved(fromPosition,toPosition); } @param position */ @override public void onItemDelete(int position) {ItemData item = mData.get(position); mData.remove(position); notifyItemRemoved(position); notifyDataSetChanged(); updateDataHome(); updateDataMore(item); } private void updateDataHome(){acache.get (mContext).put("itemsHome",mData); } private void updateDataMore(ItemData itemData){ ArrayList<ItemData> hideData = (ArrayList<ItemData>) ACache.get(mContext).getAsObject("itemsMore"); hideData.add(itemData); ACache.get(mContext).put("itemsMore",hideData); } @override public void onSelectedItem(recyclerView.viewholder viewHolder) { / / get vibration system Service Vibrator Vibrator = (Vibrator) mContext. GetSystemService (Service. VIBRATOR_SERVICE); vibrator.vibrate(70); viewHolder.itemView.setBackgroundColor(Color.LTGRAY); } @override public void onSelectedFinish(recyclerView.viewholder viewHolder) { viewHolder.itemView.setBackgroundColor(Color.TRANSPARENT); } @NonNull @Override public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recyclerview,parent,false); ItemViewHolder viewHolder = new ItemViewHolder(view); viewHolder.itemView.setOnClickListener(view1 -> { if (mOnItemClickListener ! = null) { mOnItemClickListener.onItemClick(view1, viewHolder.getAdapterPosition()); }}); Resources Resources = McOntext.getresources (); DisplayMetrics dm = resources.getDisplayMetrics(); int width = dm.widthPixels; int height = dm.heightPixels; int myWidth = (width - 6*2 - 3)/3; view.getLayoutParams().width = myWidth; return viewHolder ; } @Override public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { holder.textView.setText(mData.get(position).getResId()); holder.imageView.setBackgroundResource(mData.get(position).getBitmap()); } @Override public int getItemCount() { return mData ! = null ? mData.size() : 0; } /** * listen interface, @param mOnItemClickListener */ public void setOnItemClickListener(OnItemClickListener mOnItemClickListener){ this.mOnItemClickListener = mOnItemClickListener; } public interface OnItemClickListener{ void onItemClick(View view,int position); }}Copy the code
This is the corresponding recyclerView XML file and bean file.
<? The XML version = "1.0" encoding = "utf-8"? > <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="match_parent"> <ImageView android:id="@+id/iv_item_recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:id="@+id/tv_item_recyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="bottom" Android :layout_marginBottom="20dp" Android :text=" test "/> </FrameLayout>Copy the code
public class ItemData implements Serializable { private int resId; private int bitmap; //background private Bitmap itemImgBitmap; //itemImage public ItemData(int resId, int bitmap) { this.resId = resId; this.bitmap = bitmap; } public ItemData(int resId, int bitmap, Bitmap itemImgBitmap) { this.resId = resId; this.bitmap = bitmap; this.itemImgBitmap = itemImgBitmap; } public int getResId() { return resId; } public void setResId(int resId) { this.resId = resId; } public int getBitmap() { return bitmap; } public void setBitmap(int bitmap) { this.bitmap = bitmap; } public Bitmap getItemImgBitmap() { return itemImgBitmap; } public void setItemImgBitmap(Bitmap itemImgBitmap) { this.itemImgBitmap = itemImgBitmap; }}Copy the code
interval
The next step is to set paging and spacing based on your business needs.
First, because of the business requirements, I have a grid layout here, so load the layout manager, GridLayoutManager and implement horizontal scrolling.
Then how to realize interval, the first reaction is certainly recyclerView. AddItemDecoration, right to use the little trouble all have no, so use this, and then customize the interval. The code is as follows:
public class SpaceItemDecoration extends RecyclerView.ItemDecoration { Context mContext; float space; public SpaceItemDecoration(Context mContext,float space) { this.space = space; this.mContext = mContext; } @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.getItemOffsets(outRect,view,parent,state); int item = parent.getChildAdapterPosition(view) %6; int spacing = DimensionConvert.dip2px(mContext,space); switch (item){ case 0: outRect.left = DimensionConvert.dip2px(mContext,3); outRect.top = spacing; outRect.bottom = (spacing / 2); break; case 2: case 4: outRect.top = spacing; outRect.left = spacing; // outRect.right = DimensionConvert.dip2px(mContext,3); outRect.bottom = (spacing / 2); break; case 1: outRect.left = DimensionConvert.dip2px(mContext,3); // outRect.bottom = spacing; outRect.top = (spacing / 2); break; case 3: case 5: outRect.top = (spacing / 2); outRect.left = spacing; // outRect.right = DimensionConvert.dip2px(mContext,3); // outRect.bottom = spacing; break; }}}Copy the code
By the way, this involves a conversion between PX and DP, the tool file is as follows, of course, do not convert direct use is also no problem.
import android.content.Context; /** * Created by shichaohui on 2015/7/10 0010. */ public Class DimensionConvert {/** * Convert from DP to PX ** according to the phone resolution Public static int dip2px(context, dpValue); float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; Return (int) (dpValue * scale + 0.5f); } public static int px2dip(context); public static int px2dip(context) context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; Return (int) (pxValue/scale + 0.5f); }}Copy the code
paging
To achieve paging effect, in fact, Android official provides us with the helper class SnapHelper, interested can go to know, but it does not meet my business needs, because I want to achieve similar paging effect, the official provided PagerSnapHelper I here may be because of the horizontal scrolling cause, I can do one column at a time, but I want three columns to do something like paging, so I have to do it myself. The specific code is as follows:
import android.graphics.PointF;
import android.util.DisplayMetrics;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearSmoothScroller;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SnapHelper;
/**
* Created by Muyuki on 2019/11/8
* 网格布局分页效果
* 仅限布局为GridLayoutManager使用
*/
public class GridPagerSnapHelper extends SnapHelper {
@Nullable
private OrientationHelper mVerticalHelper;
@Nullable
private OrientationHelper mHorizontalHelper;
private RecyclerView recyclerView;
private int rowCount = 1;
private int columCount = 1;
/**
* @param row 行
* @param column 列
*/
public GridPagerSnapHelper(int row,int column) {
this.rowCount = row;
this.columCount = column;
}
@Override
public void attachToRecyclerView(@Nullable RecyclerView recyclerView) throws IllegalStateException {
super.attachToRecyclerView(recyclerView);
this.recyclerView = recyclerView;
}
@Nullable
@Override
public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager, @NonNull View targetView) {
int[] out = new int[2];
if (layoutManager.canScrollHorizontally()) {
out[0] = this.distanceToStart(layoutManager, targetView, this.getHorizontalHelper(layoutManager));
} else {
out[0] = 0;
}
if (layoutManager.canScrollVertically()) {
out[1] = this.distanceToStart(layoutManager, targetView, this.getVerticalHelper(layoutManager));
} else {
out[1] = 0;
}
return out;
}
@Nullable
@Override
public View findSnapView(RecyclerView.LayoutManager layoutManager) {
if (layoutManager.canScrollVertically()) {
return this.findStartSnapView(layoutManager, this.getVerticalHelper(layoutManager));
} else {
return layoutManager.canScrollHorizontally() ? this.findStartSnapView(layoutManager, this.getHorizontalHelper(layoutManager)) : null;
}
}
@Override
public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
int itemCount = layoutManager.getItemCount();
if (itemCount == 0) {
return -1;
} else {
View mStartMostChildView = null;
if (layoutManager.canScrollVertically()) {
mStartMostChildView = this.findStartView(layoutManager, this.getVerticalHelper(layoutManager));
} else if (layoutManager.canScrollHorizontally()) {
mStartMostChildView = this.findStartView(layoutManager, this.getHorizontalHelper(layoutManager));
}
if (mStartMostChildView == null) {
return -1;
} else {
int centerPosition = layoutManager.getPosition(mStartMostChildView);
if (centerPosition == -1) {
return -1;
} else {
// 计算当前页面索引
int pagerIndex = centerPosition / (rowCount * columCount);
// 是否滑向下一页
boolean forwardDirection;
if (layoutManager.canScrollHorizontally()) {
forwardDirection = velocityX > 0;
} else {
forwardDirection = velocityY > 0;
}
// 条目是否是翻转模式
boolean reverseLayout = false;
if (layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider) {
RecyclerView.SmoothScroller.ScrollVectorProvider vectorProvider = (RecyclerView.SmoothScroller.ScrollVectorProvider) layoutManager;
PointF vectorForEnd = vectorProvider.computeScrollVectorForPosition(itemCount - 1);
if (vectorForEnd != null) {
reverseLayout = vectorForEnd.x < 0.0F || vectorForEnd.y < 0.0F;
}
}
int targetPosition = -1;
if (reverseLayout) {
targetPosition = (forwardDirection ? (pagerIndex - 1) * (rowCount * columCount) : (pagerIndex) * (rowCount * columCount));
} else {
targetPosition = (forwardDirection ? (pagerIndex + 1) * (rowCount * columCount) : (pagerIndex) * (rowCount * columCount));
}
return targetPosition;
}
}
}
}
@Override
protected LinearSmoothScroller createSnapScroller(RecyclerView.LayoutManager layoutManager) {
return !(layoutManager instanceof RecyclerView.SmoothScroller.ScrollVectorProvider) ? null : new LinearSmoothScroller(this.recyclerView.getContext()) {
protected void onTargetFound(View targetView, RecyclerView.State state, Action action) {
int[] snapDistances = GridPagerSnapHelper.this.calculateDistanceToFinalSnap(GridPagerSnapHelper.this.recyclerView.getLayoutManager(), targetView);
int dx = snapDistances[0];
int dy = snapDistances[1];
int time = this.calculateTimeForDeceleration(Math.max(Math.abs(dx), Math.abs(dy)));
if (time > 0) {
action.update(dx, dy, time, this.mDecelerateInterpolator);
}
}
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return 100.0F / (float) displayMetrics.densityDpi;
}
protected int calculateTimeForScrolling(int dx) {
return Math.min(100, super.calculateTimeForScrolling(dx));
}
};
}
private int distanceToStart(@NonNull RecyclerView.LayoutManager layoutManager, @NonNull View targetView, OrientationHelper helper) {
int childStart = helper.getDecoratedStart(targetView);
int containerStart;
if (layoutManager.getClipToPadding()) {
containerStart = helper.getStartAfterPadding();
} else {
containerStart = 0;
}
return childStart - containerStart;
}
@Nullable
private View findStartSnapView(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) {
int childCount = layoutManager.getChildCount();
if (childCount == 0) {
return null;
} else {
View closestChild = null;
int start;
if (layoutManager.getClipToPadding()) {
start = helper.getStartAfterPadding();
} else {
start = 0;
}
int absClosest = 2147483647;
for (int i = 0; i < childCount; ++i) {
View child = layoutManager.getChildAt(i);
int childStart = helper.getDecoratedStart(child);
int absDistance = Math.abs(childStart - start);
if (absDistance < absClosest) {
absClosest = absDistance;
closestChild = child;
}
}
return closestChild;
}
}
@Nullable
private View findStartView(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) {
int childCount = layoutManager.getChildCount();
if (childCount == 0) {
return null;
} else {
View closestChild = null;
int startest = 2147483647;
for (int i = 0; i < childCount; ++i) {
View child = layoutManager.getChildAt(i);
int childStart = helper.getDecoratedStart(child);
if (childStart < startest) {
startest = childStart;
closestChild = child;
}
}
return closestChild;
}
}
@NonNull
private OrientationHelper getVerticalHelper(@NonNull RecyclerView.LayoutManager layoutManager) {
if (this.mVerticalHelper == null || this.mVerticalHelper.getLayoutManager() != layoutManager) {
this.mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
}
return this.mVerticalHelper;
}
@NonNull
private OrientationHelper getHorizontalHelper(@NonNull RecyclerView.LayoutManager layoutManager) {
if (this.mHorizontalHelper == null || this.mHorizontalHelper.getLayoutManager() != layoutManager) {
this.mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
}
return this.mHorizontalHelper;
}
}
Copy the code
persistence
For persistence, you can go to the end of implementation 1 in my previous article and see ACache as a lightweight persistence for Android.
Implementation: MainActivity
public class MainActivity extends AppCompatActivity { private boolean isFirst; private static final String TAG = "MainActivity"; private MyItemTouchHelperAdapter myItemTouchHelperAdapter; RecyclerView recyclerView; ArrayList<ItemData> mData; private ACache aCache; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d(TAG, "onCreate: period "); isFirst = true; init(); } private void init(){ initData(); recyclerView = findViewById(R.id.main_recyclerView); / / set the grid layout GridLayoutManager manager = new GridLayoutManager (this, 2, LinearLayoutManager. HORIZONTAL, false); recyclerView.setLayoutManager(manager); / / set the interval recyclerView. AddItemDecoration (new SpaceItemDecoration (this, 6)); New GridPagerSnapHelper(2,3). AttachToRecyclerView (recyclerView); MyItemTouchHelperAdapter = new myItemTouchHelperAdapter (this,mData); MyItemTouchHelperCallback myItemTouchHelperCallback = new MyItemTouchHelperCallback(myItemTouchHelperAdapter); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(myItemTouchHelperCallback); itemTouchHelper.attachToRecyclerView(recyclerView); recyclerView.setAdapter(myItemTouchHelperAdapter); / / set to monitor myItemTouchHelperAdapter. SetOnItemClickListener (new myItemTouchHelperAdapter. OnItemClickListener () {/ / If you need to customize the click interval, @singleclick (2000) @override public void onItemClick(View, View) int position) { switch (mData.get(position).getResId()) { case R.string.version_more: Intent intent = new Intent(MainActivity.this, GetMoreActivity.class); MainActivity.this.startActivity(intent); break; case R.string.trans_order_pay_new: Log.d(TAG, "onItemClick: "); break; }}}); } private void addSource(int resId, int bitmapId){ if (resId ==0 || bitmapId ==0) return; mData.add(new ItemData(resId,bitmapId)); Private void initData(){aCache = acache.get (mainactivity.this); if (aCache.getAsObject("itemsHome") ! = null){ mData = (ArrayList<ItemData>) aCache.getAsObject("itemsHome"); } else { mData = new ArrayList<>(); addSource(R.string.trans_order_pay_new, R.drawable.item_ordernew); addSource(R.string.trans_ant_credit_pay, R.drawable.item_antcredit); addSource(R.string.qrcode_trans, R.drawable.item_qrcode_trade); addSource(R.string.trans_membersale, R.drawable.item_membersale); addSource(R.string.trans_sale, R.drawable.item_sale); addSource(R.string.trans_auth, R.drawable.item_auth); addSource(R.string.trans_orderrefund, R.drawable.order_refund_icon); addSource(R.string.trans_sale_void, R.drawable.item_void); addSource(R.string.trans_refund, R.drawable.item_refund); addSource(R.string.trans_login, R.drawable.item_login); addSource(R.string.trans_query, R.drawable.item_quey_money); addSource(R.string.trans_detail, R.drawable.item_detail); addSource(R.string.trans_print, R.drawable.item_print); addSource(R.string.logout_settle, R.drawable.item_settle); addSource(R.string.trans_cashout, R.drawable.item_cash_out); addSource(R.string.lock_terminal, R.drawable.item_lock); addSource(R.string.version_info, R.drawable.item_version); addSource(R.string.version_more, R.drawable.item_version); if (mData ! = null){ aCache.put("itemsHome",mData,30 * ACache.TIME_DAY); Log.d(TAG, "initData: "+mData); } log.d (TAG, "initData: entered without "); } if (mData.size() %6 ! = 0){ int num = mData.size() % 6 ; for (int i = 0; i < num; i++) { addSource(R.string.item_forhome,R.drawable.item_forhome); } } } @Override protected void onResume(){ if (! isFirst){ initData(); myItemTouchHelperAdapter.notifyDataSetChanged(); } super.onResume(); Log.d(TAG, "onResume: period "); } @Override protected void onStart() { super.onStart(); Log.d(TAG, "onStart: period "); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "onStop: cycle "); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy: cycle "); } @Override protected void onPause() { isFirst = false; // init(); super.onPause(); Log.d(TAG, "onPause: period "); }}Copy the code
Finally, there is a click imitation heavy, here is the use of AOP to solve the problem of repeated click, specific blog reference as follows:
AOP solve button imitation: www.jianshu.com/p/ee2bddca1…
Horizontal paging: blog.csdn.net/mr_lichao/a…
So far is also over, so goodbye, record their own learning, but also to share their own learning with you bigwigs.