国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android開發(fā)在RecyclerView上面實(shí)現(xiàn)"拖放"和"滑動(dòng)刪除"-2

2019-12-12 03:17:55
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

上篇給大家介紹了Android一步步帶你在RecyclerView上面實(shí)現(xiàn)"拖放"和"滑動(dòng)刪除"功能

效果如下:

拖動(dòng)手柄

在設(shè)計(jì)一個(gè)支持"拖放"的列表時(shí), 通常提供一個(gè)在觸摸時(shí)初始化拖拽的"拖動(dòng)手柄". 因其可發(fā)現(xiàn)性和可用性而被Material Guidelines所推薦, 尤其是列表處于"可編輯模式"時(shí).

首先更新item的布局(item_main.xml):

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/item" android:layout_width="match_parent" android:layout_height="?listPreferredItemHeight" android:clickable="true" android:focusable="true" android:foreground="?selectableItemBackground"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="16dp" android:textAppearance="?android:attr/textAppearanceMedium" /> <ImageView android:id="@+id/handle" android:layout_width="?listPreferredItemHeight" android:layout_height="match_parent" android:layout_gravity="center_vertical|right" android:scaleType="center" android:src="@drawable/ic_reorder_grey_500_24dp" /></FrameLayout>

用作"拖放手柄"的圖片可以在Material Design Icon找到, 也可以方便地通過(guò)Android Material Design Icon Generator Plugin添加.

我們?cè)?jīng)提到過(guò), 可以通過(guò)代碼ItemTouchHelper.startDrag(RecyclerView.ViewHolder)來(lái)開啟拖動(dòng). 所以我們要做的就是更新ViewHolder來(lái)包含新的手柄視圖, 并設(shè)置一個(gè)簡(jiǎn)單的觸摸事件接口, 以觸發(fā)startDrag()方法.

我們需要定義一個(gè)接口來(lái)傳遞拖動(dòng)事件.

public interface OnStartDragListener { /** * Called when a view is requesting a start of a drag. * * @param viewHolder The holder of the view to drag. */ void onStartDrag(RecyclerView.ViewHolder viewHolder);}

然后, 在ItemViewHolder中實(shí)現(xiàn)化手柄視圖.

public final ImageView handleView;public ItemViewHolder(View itemView) { super(itemView); // ... handleView = (ImageView) itemView.findViewById(R.id.handle);}

并且更新Adapter.

private final OnStartDragListener mDragStartListener;public RecyclerListAdapter(OnStartDragListener dragStartListener) { mDragStartListener = dragStartListener; // ...}@Overridepublic void onBindViewHolder(final ItemViewHolder holder,  int position) { // ... holder.handleView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (MotionEventCompat.getActionMasked(event) ==   MotionEvent.ACTION_DOWN) { mDragStartListener.onStartDrag(holder); } return false; } });}

完整的Adapter應(yīng)該看起來(lái)像這個(gè).

剩下的是把OnStartDragListener添加到Fragment.

public class RecyclerListFragment extends Fragment implements  OnStartDragListener { // ... @Override public void onViewCreated(View view, Bundle icicle) { super.onViewCreated(view, icicle); RecyclerListAdapter a = new RecyclerListAdapter(this); // ... } @Override public void onStartDrag(RecyclerView.ViewHolder viewHolder) { mItemTouchHelper.startDrag(viewHolder); }}

但你運(yùn)行之后, 可以看到這樣的效果:

標(biāo)示選中視圖

在上一篇的基礎(chǔ)示例中, 被拖拽的item事實(shí)上是被選中的, 但是沒(méi)有可視化的標(biāo)示. 由于顯著的理由, 這是不受歡迎的, 但也很容易修復(fù). 事實(shí)上, 在ItemTouchHelper的幫助下, 只要你的ViewHolder的itemView設(shè)置了background集合(selector), 就會(huì)得到相應(yīng)的效果. 在Lollipop及之后的版本, item view的elevation在拖拽和滑動(dòng)期間會(huì)增加. 而在之前的版本中, 滑動(dòng)時(shí)會(huì)有fade效果. 看起來(lái)就像:

效果看起來(lái)不錯(cuò), 但你可能想要更多的控制. 一種方法是, 無(wú)論任何時(shí)候ViewHolder被選中或者清空, 讓item自己處理這種改變. 由此, ItemTouchHelper.Callback提供了兩種回調(diào).

onSelectedChanged(RecyclerView.ViewHolder, int). 每一次ViewHolder的狀態(tài), 變成drag(ACTION_STATE_DRAG)或者swipe(ACTION_STATE_SWIPE)時(shí), 該方法就會(huì)被調(diào)用. 這時(shí)候是將ViewHolder的狀態(tài)變成active的完美時(shí)刻.

clearView(RecyclerView, RecyclerView.ViewHolder). 在被拖拽的ViewHolder放下時(shí), 或者是滑動(dòng)操作取消或者完成時(shí)(ACTION_STATE_IDLE), 這里會(huì)是將ItemView狀態(tài)設(shè)置為idle的最好的地方.

那么, 我們就把兩者綁定在一起實(shí)現(xiàn).

首先, 創(chuàng)建一個(gè)接口, 讓目標(biāo)ViewHolder實(shí)現(xiàn):

/** * Notifies a View Holder of relevant callbacks from  * {@link ItemTouchHelper.Callback}. */public interface ItemTouchHelperViewHolder { /** * Called when the {@link ItemTouchHelper} first registers an  * item as being moved or swiped. * Implementations should update the item view to indicate  * it's active state. */ void onItemSelected(); /** * Called when the {@link ItemTouchHelper} has completed the  * move or swipe, and the active item state should be cleared. */ void onItemClear();}

接著, 觸發(fā)相應(yīng)的回調(diào)方法:

@Overridepublic void onSelectedChanged(RecyclerView.ViewHolder viewHolder,  int actionState) { // We only want the active item if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { if (viewHolder instanceof ItemTouchHelperViewHolder) { ItemTouchHelperViewHolder itemViewHolder =   (ItemTouchHelperViewHolder) viewHolder; itemViewHolder.onItemSelected(); } } super.onSelectedChanged(viewHolder, actionState);}@Overridepublic void clearView(RecyclerView recyclerView,  RecyclerView.ViewHolder viewHolder) { super.clearView(recyclerView, viewHolder); if (viewHolder instanceof ItemTouchHelperViewHolder) { ItemTouchHelperViewHolder itemViewHolder =  (ItemTouchHelperViewHolder) viewHolder; itemViewHolder.onItemClear(); }}

現(xiàn)在, 剩下的是讓ItemViewHolder實(shí)現(xiàn)ItemTouchHelperViewHolder:

public class ItemViewHolder extends RecyclerView.ViewHolder  implements ItemTouchHelperViewHolder { // ... @Override public void onItemSelected() { itemView.setBackgroundColor(Color.LTGRAY); } @Override public void onItemClear() { itemView.setBackgroundColor(0); }}

考慮到這僅僅是一個(gè)示例, 我們僅僅是在item處于active狀態(tài)時(shí)設(shè)置了灰色背景, 當(dāng)item被清空時(shí), 把灰色背景刪除了. 如果你的Adapter和ItemTouchHelper緊密結(jié)對(duì)的話, 輕易地放棄這個(gè)設(shè)置也行, 轉(zhuǎn)而可以直接在ItemTouchHelper.Callback轉(zhuǎn)變item的狀態(tài).

Grid布局

如果你想在本項(xiàng)目中轉(zhuǎn)而使用GridLayoutManager, 你會(huì)發(fā)現(xiàn)并沒(méi)有正常地起作用. 原因以及修復(fù)原因都很簡(jiǎn)單: 必須告訴ItemTouchHelper我們想要支持左右拖拽. 在SimpleTouchHelperCallback中, 我們已經(jīng)聲明:

@Overridepublic int getMovementFlags(RecyclerView recyclerView,  RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags, swipeFlags);}

支持Grid布局所要求的唯一改變是dragFlags中添加左右方向:

int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |  ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;

但是, 對(duì)于grid而言, "滑動(dòng)刪除"并不是一個(gè)天然的功能模式, 所以你也許會(huì)寫一些如下的代碼:

@Overridepublic int getMovementFlags(RecyclerView recyclerView,  RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |   ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; int swipeFlags = 0; return makeMovementFlags(dragFlags, swipeFlags);}

Grid上面的上下左右"拖放"效果看起來(lái)如下:

自定義滑動(dòng)動(dòng)畫

對(duì)我們而言, 在viewHolder拖拽和滑動(dòng)的時(shí)候, ItemTouchHelper.Callback為我們提供了一個(gè)十分方便的方式來(lái)完全控制ViewHolder的動(dòng)畫. 因?yàn)镮temTouchHelper是一個(gè)ItemDecoration, 我們可以用類似的方式, 詳細(xì)地了解視圖的繪制(hook into the View drawing).

下面是一個(gè)簡(jiǎn)單的例子, 來(lái)覆蓋默認(rèn)的滑動(dòng)動(dòng)畫, 來(lái)展示一個(gè)線性的fade效果.

@Overridepublic void onChildDraw(Canvas c, RecyclerView recyclerView,  ViewHolder viewHolder, float dX, float dY,  int actionState, boolean isCurrentlyActive) { if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { float width = (float) viewHolder.itemView.getWidth(); float alpha = 1.0f - Math.abs(dX) / width; viewHolder.itemView.setAlpha(alpha); viewHolder.itemView.setTranslationX(dX);  } else { super.onChildDraw(c, recyclerView, viewHolder, dX, dY,   actionState, isCurrentlyActive); }}

參數(shù)dX和dY代表選中視圖的當(dāng)前位置,

  • -1.0f表示完完全全的從ItemTouchHelper.END到ItemTouchHelper.START的滑動(dòng).
  • 1.0f表示完完全全的從ItemTouchHelper.START到ItemTouchHelper.END的滑動(dòng).

 對(duì)于任何沒(méi)有處理的actionState你都可以調(diào)用super的方法, 從而使用默認(rèn)的動(dòng)畫.

總結(jié)

我們僅僅了解了自定義ItemTouchHelper所能做的事情中有趣的部分, 我希望能夠在一篇文章中包含更多內(nèi)容, 但是考慮到文章長(zhǎng)度, 還是分開比較好.

以上所述是小編給大家介紹的Android開發(fā)在RecyclerView上面實(shí)現(xiàn)"拖放"和"滑動(dòng)刪除功能(二),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)武林網(wǎng)網(wǎng)站的支持!

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 郑州市| 武义县| 游戏| 鄱阳县| 乌鲁木齐市| 灵台县| 罗江县| 宾阳县| 平顺县| 黄平县| 松滋市| 怀集县| 衡水市| 曲阜市| 图木舒克市| 苏尼特左旗| 鄢陵县| 河源市| 灵宝市| 阳高县| 麟游县| 临颍县| 绥芬河市| 平遥县| 石狮市| 台东市| 兰西县| 石屏县| 临城县| 长海县| 汕头市| 华坪县| 义乌市| 水富县| 颍上县| 东丰县| 康乐县| 宜君县| 巢湖市| 上饶市| 北流市|