1.使用RecyclerView

使用RecyclerView可以轻松实现图片切换时的动画过程,这点要好于GridView。

2. 拖拽的实现

  • Dragmanager

继承View.OnDragListener,对拖拽过程中进行操作,

Action_drag_started 获取到操作的Item

Action_Drag_location 根据每个停留的位置判断是否交换item的位置。

Action_Drag_ended 跟新位置

  • DragSortAdapter

抽象类,为recyclerView 增加onItemTouchListener和onScrollListener, 记录onTouch的item,并在拖拽过程中判断recyclerview是否可以滚动,从而在拖拽的item快到边界时滚动recyclerView,使可以与本来在屏幕上不可见的item进行交换位置。

  • ViewHolder

ViewHolder 实现startDrag方法


2.itemDecoration


为recyclerview item增加divider,可以有两种方式,覆盖onDraw方法绘制itemDivider,或者覆盖getItemOffsets方法,使item之间可以分隔开。

3.GridlayoutManager

当recyclerview嵌入到scrollview中时,需要复写LayoutManager,在这里复写其中的onMeasure方法,需要计算每个item的高度或者宽度进行叠加,当recyclerview中item很多时,不要采用这种方式,回导致view不能复用,其中在计算item高度时,需要加上每个item的itemOffsets,查看recyclerview的源码发现,无法直接获取到item的offsets,最终采用反射的方式获取到其值:

try {
    Method method = recyclerView.getClass().getDeclaredMethod("getItemDecorInsetsForChild",View.class);
    method.setAccessible(true);
    final Rect insets = (Rect)method.invoke(recyclerView, child);
    itemDecorationHeight = heightUsed + insets.height();
    itemDecorationWidth = widthUsed + insets.width();
} catch (NoSuchMethodException e){
    Log.d("FullGridLayoutManager","no method found");
}catch(IllegalAccessException e){
    Log.d("FullGridLayoutManager","IllegalAccessException");
}catch (InvocationTargetException e){
    Log.d("FullGridLayoutManager","InvocationTargetException");
}