Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android开发在RecyclerView上面实现"拖放"和"滑动删除"-2大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

上篇给大家介绍了Android一步步带你在RecyclerView上面实现"拖放"和"滑动删除"功能

效果如下:

Android开发在RecyclerView上面实现"拖放"和"滑动删除"-2

拖动手柄

在设计一个支持"拖放"的列表时,通常提供一个在触摸时初始化拖拽的"拖动手柄". 因其可发现性和可用性而被Material Guidelines所推荐,尤其是列表处于"可编辑模式"时.

Android开发在RecyclerView上面实现"拖放"和"滑动删除"-2

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

<FrameLayout xmlns:android="http://scheR_710_11845@as.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找到,也可以方便地通过Android Material Design Icon Generator Plugin添加.

我们曾经提到过,可以通过代码itemtouchhelper.startDrag(RecyclerView.ViewHolder)来开启拖动. 所以我们要做的就是更新ViewHolder来包含新的手柄视图,并设置一个简单的触摸事件接口,以触发startDrag()方法.

我们需要定义一个接口来传递拖动事件.

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中实现化手柄视图.

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;
 // ...
}
@Override
public 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应该看起来像这个.

剩下的是把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);
 }
}

但你运行之后,可以看到这样的效果:

Android开发在RecyclerView上面实现"拖放"和"滑动删除"-2

标示选中视图

上一篇的基础示例中,被拖拽的item事实上是被选中的,但是没有可视化的标示. 由于显著的理由,这是不受欢迎的,但也很容易修复. 事实上,在itemtouchhelper的帮助下,只要你的ViewHolder的itemView设置了BACkground集合(SELEctor),就会得到相应的效果. 在Lollipop及之后的版本,item view的elevation在拖拽和滑动期间会增加. 而在之前的版本中,滑动时会有fade效果. 看起来就像:

Android开发在RecyclerView上面实现"拖放"和"滑动删除"-2

效果看起来不错,但你可能想要更多的控制. 一种方法是,无论任何时候ViewHolder被选中或者清空,让item自己处理这种改变. 由此,itemtouchhelper.CallBACk提供了两种回调.

onSELEctedChanged(RecyclerView.ViewHolder,int). 每一次ViewHolder的状态,变成drag(ACTION_STATE_DRAG)或者swipe(ACTION_STATE_SWIPE)时,该方法就会被调用. 这时候是将ViewHolder的状态变成active的完美时刻.

clearView(RecyclerView,RecyclerView.ViewHolder). 在被拖拽的ViewHolder放下时,或者是滑动操作取消或者完成时(ACTION_STATE_IDLE),这里会是将ItemView状态设置为idle的最好的地方.

那么,我们就把两者绑定在一起实现.

首先,创建一个接口,让目标ViewHolder实现:

/**
 * 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();
}

接着,触发相应的回调方法:

@Override
public 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);
}
@Override
public void clearView(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder) {
 super.clearView(recyclerView,viewHolder);

 if (viewHolder instanceof itemtouchhelperViewHolder) {
 itemtouchhelperViewHolder itemViewHolder = 
 (itemtouchhelperViewHolder) viewHolder;
 itemViewHolder.onItemClear();
 }
}

现在,剩下的是让ItemViewHolder实现itemtouchhelperViewHolder:

public class ItemViewHolder extends RecyclerView.ViewHolder 
 implements itemtouchhelperViewHolder {
 // ...
 @Override
 public void onItemSELEcted() {
 itemView.setBACkgroundColor(Color.LTGRAY);
 }
 @Override
 public void onItemClear() {
 itemView.setBACkgroundColor(0);
 }
}

虑到这仅仅是一个示例,我们仅仅是在item处于active状态时设置了灰色背景,当item被清空时,把灰色背景删除了. 如果你的Adapter和itemtouchhelper紧密结对的话,轻易地放弃这个设置也行,转而可以直接在itemtouchhelper.CallBACk转变item的状态.

Grid布局

如果你想在本项目中转而使用GridLayoutManager,你会发现并没有正常地起作用. 原因以及修复原因都很简单: 必须告诉itemtouchhelper我们想要支持左右拖拽. 在SimpleTouchHelperCallBACk中,我们已经声明:

@Override
public 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;

但是,对于grid而言,"滑动删除"并不是一个天然的功能模式,所以你也许会写一些如下的代码:

@Override
public 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上面的上下左右"拖放"效果看起来如下:

Android开发在RecyclerView上面实现"拖放"和"滑动删除"-2

自定义滑动动画

对我们而言,在viewHolder拖拽和滑动的时候,itemtouchhelper.CallBACk为我们提供了一个十分方便的方式来完全控制ViewHolder的动画. 因为itemtouchhelper一个ItemDecoration,我们可以用类似的方式,详细地了解视图的绘制(hook into the View drawing).

下面是一个简单的例子,来覆盖认的滑动动画,来展示一个线性的fade效果.

@Override
public 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);
 }
}

参数dX和dY代表选中视图的当前位置,

 对于任何没有处理的actionState你都可以调用super的方法,从而使用认的动画.

总结

我们仅仅了解了自定义itemtouchhelper所能做的事情中有趣的部分,我希望能够在一篇文章中包含更多@L_489_92@,但是虑到文章长度,还是分开比较好.

以上所述是小编给大家介绍的Android开发在RecyclerView上面实现"拖放"和"滑动删除功能(二),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持

大佬总结

以上是大佬教程为你收集整理的Android开发在RecyclerView上面实现"拖放"和"滑动删除"-2全部内容,希望文章能够帮你解决Android开发在RecyclerView上面实现"拖放"和"滑动删除"-2所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。