RxAndroid+Retrofit+GreenDao+MVP框架---通用基类封装(三)

时间:2020-12-18 21:14:47

打算分为通用的方法,基类封装;网络请求框架封装(RxAndroid+Retrofit);数据库操作封装(GreenDao);

查看完整框架可以到GitHub下载https://github.com/850125665/WeatherApp

RecycleView的长按,单击,drag,swipe封装

-使用现成API可以轻松实现,item的长按,点击,drag,swipe等方法。主要用上GestureDetectorCompat,ItemTouchHelper两个API

TouchListener.java

public class TouchListener implements RecyclerView.OnItemTouchListener {

private String TAG = getClass().getSimpleName();

private GestureDetectorCompat gestureDetectorCompat;

private RecyclerView recyclerView;

private OnClickListener onClickListener;

private ItemTouchHelper itemTouchHelper;

private List list;

private RecyclerView.Adapter adapter;
private SwipeRefreshLayout swipeRefreshLayout;
ViewPager viewPager;

public void setOnClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}

public TouchListener(RecyclerView recyclerView, final List list, final RecyclerView.Adapter adapter) {
this.list = list;
this.adapter = adapter;
this.recyclerView = recyclerView;
gestureDetectorCompat = new GestureDetectorCompat(recyclerView.getContext(), new ItemTouchHelpGestureListener());
List<ViewParent> viewParents = new ArrayList<>();
viewParents = AppMethods.getParentView(recyclerView.getParent(), viewParents);
for (ViewParent parent : viewParents) {
if (parent instanceof ViewPager) {
viewPager = (ViewPager) parent;
} else if (parent instanceof SwipeRefreshLayout) {
swipeRefreshLayout = (SwipeRefreshLayout) parent;
}
}

}

float downX = 0;
float downY = 0;

@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {

switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = e.getX();
downY = e.getY();
if (viewPager != null) {
viewPager.requestDisallowInterceptTouchEvent(true);
}
if (swipeRefreshLayout != null) {
swipeRefreshLayout.requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_MOVE:

if (e.getX() - downX >0) {
if (viewPager != null) {

viewPager.requestDisallowInterceptTouchEvent(false);
}
if (swipeRefreshLayout != null) {

swipeRefreshLayout.requestDisallowInterceptTouchEvent(false);
}
}

//
break;
case MotionEvent.ACTION_UP:
if (viewPager != null) {

                viewPager.requestDisallowInterceptTouchEvent(false);
}
if (swipeRefreshLayout != null) {

swipeRefreshLayout.requestDisallowInterceptTouchEvent(false);
}
break;
}
boolean b = gestureDetectorCompat.onTouchEvent(e);
return b;
}


@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
gestureDetectorCompat.onTouchEvent(e);
}

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

}

public class ItemTouchHelpGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
View childViewUnder = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childViewUnder != null) {
RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(childViewUnder);
int childLayoutPosition = recyclerView.getChildLayoutPosition(childViewUnder);
if (onClickListener != null) {

onClickListener.onItemClickListener(childViewHolder, childLayoutPosition);
}
return false;

}
return false;
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

LogUtils.d(TAG, "onScroll" + "distanceX" + distanceX + " distanceY" + distanceY);

return false;
}

@Override
public void onShowPress(MotionEvent e) {
LogUtils.d(TAG, "onShowPress");
}

@Override
public void onLongPress(MotionEvent e) {
View childViewUnder = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childViewUnder != null) {
RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(childViewUnder);
int childLayoutPosition = recyclerView.getChildLayoutPosition(childViewUnder);
if (onClickListener != null) {

onClickListener.onItemLongClickListener(childViewHolder, childLayoutPosition);
if(swipeRefreshLayout!=null){
swipeRefreshLayout.setEnabled(false);
}
}

}


}
}

public interface OnClickListener {
<T extends RecyclerView.ViewHolder> void onItemClickListener(T t, int position);

<T extends RecyclerView.ViewHolder> void onItemLongClickListener(T t, int position);
}

public void dragItem(final SwipeRefreshLayout swipeRefreshLayout, final DragItemListener dragItemListener) {
this.swipeRefreshLayout = swipeRefreshLayout;
itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if(swipeRefreshLayout!=null){
swipeRefreshLayout.setEnabled(false);
}
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
int dragFlag = 0;
int swipeFlag = 0;
if (layoutManager instanceof LinearLayoutManager) {

dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
swipeFlag = ItemTouchHelper.START;
} else if (layoutManager instanceof GridLayoutManager) {
dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END;
}
return makeMovementFlags(dragFlag, swipeFlag);
}

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
LogUtils.d(TAG, "onMove");
int from = viewHolder.getAdapterPosition();
int to = target.getAdapterPosition();
if(to<=(list.size()-1) && from<=(list.size()-1)){
list.add(to, list.remove(from));
adapter.notifyItemMoved(from, to);
return true;
}else{
return false;
}
}


@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int adapterPosition = viewHolder.getAdapterPosition();
if(adapterPosition<=(list.size()-1)){
dragItemListener.swipe(adapterPosition);
adapter.notifyItemRemoved(adapterPosition);
list.remove(adapterPosition);
}


LogUtils.d(TAG, "onSwiped");
}

@Override
public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y) {
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y);
dragItemListener.drag();
LogUtils.d(TAG, "onMoved");

}

@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);

LogUtils.d(TAG, "onSelectedChanged");
}

@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
LogUtils.d(TAG, "clearView");
if (swipeRefreshLayout != null) {
if (!swipeRefreshLayout.isEnabled()) {
AppInfo.getAppInstant().getUiHandler().postDelayed(new TimerTask() {
@Override
public void run() {
swipeRefreshLayout.setEnabled(true);
}
}, 200);
}


}
}
});
itemTouchHelper.attachToRecyclerView(recyclerView);
}

public interface DragItemListener{
public void drag();
public void swipe(int position);
}

}

-GestureDetector类对外提供了两个接口:OnGestureListener,OnDoubleTapListener,还有一个内部类SimpleOnGestureListener;SimpleOnGestureListener类是GestureDetector提供给我们的一个更方便的响应不同手势的类,它实现了上述两个接口,该类是static class,也就是说它实际上是一个外部类,我们可以在外部继承这个类,重写里面的手势处理方法。因此实现手势识别有两种方法,一种实现OnGestureListener接口,另一种是使用SimpleOnGestureListener类。
OnGestureListener有下面的几个动作:
按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。
抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。
长按(onLongPress): 手指按在持续一段时间,并且没有松开。
滚动(onScroll): 手指在触摸屏上滑动。
按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。
抬起(onSingleTapUp):手指离开触摸屏的那一刹那。
我们用的SimpleOnGestureListener内部类去实现单击,和长按

public class ItemTouchHelpGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
View childViewUnder = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childViewUnder != null) {
RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(childViewUnder);
int childLayoutPosition = recyclerView.getChildLayoutPosition(childViewUnder);
if (onClickListener != null) {

onClickListener.onItemClickListener(childViewHolder, childLayoutPosition);
}
return false;

}
return false;
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

LogUtils.d(TAG, "onScroll" + "distanceX" + distanceX + " distanceY" + distanceY);

return false;
}

@Override
public void onShowPress(MotionEvent e) {
LogUtils.d(TAG, "onShowPress");
}

@Override
public void onLongPress(MotionEvent e) {
View childViewUnder = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childViewUnder != null) {
RecyclerView.ViewHolder childViewHolder = recyclerView.getChildViewHolder(childViewUnder);
int childLayoutPosition = recyclerView.getChildLayoutPosition(childViewUnder);
if (onClickListener != null) {

onClickListener.onItemLongClickListener(childViewHolder, childLayoutPosition);
if(swipeRefreshLayout!=null){
swipeRefreshLayout.setEnabled(false);
}
}

}


}
}

-我们new ItemTouchHelper()来实现drag与swipe
getMovementFlags方法返回的参数是要实现drag还是swipe,我们判断是LinearLayoutManager时只返回drag标识。GridLayoutManager时返回drag与swipe。
onMove方法是drag的实现
onSwiped是swipe的实现
代码简单就不详细讲了

  itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if(swipeRefreshLayout!=null){
swipeRefreshLayout.setEnabled(false);
}
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
int dragFlag = 0;
int swipeFlag = 0;
if (layoutManager instanceof LinearLayoutManager) {

dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
swipeFlag = ItemTouchHelper.START;
} else if (layoutManager instanceof GridLayoutManager) {
dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END;
}
return makeMovementFlags(dragFlag, swipeFlag);
}

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
LogUtils.d(TAG, "onMove");
int from = viewHolder.getAdapterPosition();
int to = target.getAdapterPosition();
if(to<=(list.size()-1) && from<=(list.size()-1)){
list.add(to, list.remove(from));
adapter.notifyItemMoved(from, to);
return true;
}else{
return false;
}
}


@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int adapterPosition = viewHolder.getAdapterPosition();
if(adapterPosition<=(list.size()-1)){
dragItemListener.swipe(adapterPosition);
adapter.notifyItemRemoved(adapterPosition);
list.remove(adapterPosition);
}


LogUtils.d(TAG, "onSwiped");
}

@Override
public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y) {
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y);
dragItemListener.drag();
LogUtils.d(TAG, "onMoved");

}

@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);

LogUtils.d(TAG, "onSelectedChanged");
}

@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
LogUtils.d(TAG, "clearView");
if (swipeRefreshLayout != null) {
if (!swipeRefreshLayout.isEnabled()) {
AppInfo.getAppInstant().getUiHandler().postDelayed(new TimerTask() {
@Override
public void run() {
swipeRefreshLayout.setEnabled(true);
}
}, 200);
}


}
}
});
itemTouchHelper.attachToRecyclerView(recyclerView);

这个类还做了与viewpage和SwipeRefreshLayout一起用的时候drag和swipe与这两个控件有事件冲突,做了事件冲突处理,主要是在onInterceptTouchEvent方法做处理

  @Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {

switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = e.getX();
downY = e.getY();
if (viewPager != null) {
viewPager.requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_MOVE:

if (e.getX() - downX >0) {
if (viewPager != null) {

viewPager.requestDisallowInterceptTouchEvent(false);
}
}

//
break;
case MotionEvent.ACTION_UP:
if (viewPager != null) {

                viewPager.requestDisallowInterceptTouchEvent(false);
}
break;
}
return gestureDetectorCompat.onTouchEvent(e);
}