简书链接:androidtab单击到顶双击到顶部并刷新的解决方案 文章字数:685,阅读全文大约需要2分钟 首先要看tab是由什么打造的,我这里演示用我自己开发的增强版本RadioGroupX
做Tabhost也就是 Fragment切换这个增加版高仿源码,所以各位我写的再垃圾也不会垃圾到哪里去。 也就是说高仿源码自然可以兼容老版本的 RadioGroup
其实是增加了可以加badge 小红点功能。
实现思路 为了方便扩展,所以给触摸事件类传递一个接口PageControlX
,而不是一个activiy 给每一个tab设置触摸事件,设置之后原来的点击事件自然是不能触发了, 在自己实现的触摸类 编写具体业务逻辑,后寻找子fragment 或者view,所以我这里不写死为Fragment
而是判断类型是否实现接口ITabActionX
如果实现了ITabActionX
就可以进行操作调用ITabActionX.doubleClickCheck
或ITabActionX.simpleClickCheck
,没有找到就判断是否实现了FragmentHolder
也就是有的可能是一层套一层的。 ITabActionX tabActonX = TopRefreshUtilX.findFinalFragmentByFragmentHolder(((FragmentHolder) fragment));
就得到了最终的ITabActionX
到顶部方法呢基本上只需要调用 scrollView.scrollTo(0, 0);
或者 recyclerview.scrollToPosition(0);
就可以实现到顶部.刷新呢,各位自己操作好了。难点就是考察大家是否会触摸事件的拦截操作了
给每一个tab设置触摸事件,设置之后原来的点击事件自然是不能触发了单击事件也需要借助触发·GestureDetectorCompat
另外避免重复切换需要判断index
1 2 3 4 5 6 public boolean onSingleTapUp(MotionEvent e) { if (pageControl.getCurrentItem() != index) { pageControl.setCurrentItem(index); return true; } }
双击的寻找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Override public boolean onDoubleTap(MotionEvent e) { int current = index; //Prt.d(TAG, "onDoubleTap"); Object fragment = pageControl.getItem(current); if (fragment instanceof ITabActionX) { ((ITabActionX) fragment).doubleClickCheck(); } else if (fragment instanceof FragmentHolder) { ITabActionX tabActonX = TopRefreshUtilX.findFinalFragmentByFragmentHolder(((FragmentHolder) fragment)); if (tabActonX != null) { tabActonX.doubleClickCheck(); } } return super.onDoubleTap(e); }
我不太绘描述,还是直接上源码把。
MyTopTouchListener 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 import android.support.v4.view.GestureDetectorCompat; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; /** * Created by qssq on 2018/3/21 [email protected] */ public class MyTopTouchListener implements View.OnTouchListener { private final int index; private PageControlX pageControl; public MyTopTouchListener(PageControlX pageControl, int index) { this.pageControl = pageControl; this.index = index; } GestureDetectorCompat detector = new GestureDetectorCompat(AppContext.getInstance(), new GestureDetector.SimpleOnGestureListener() { // GestureDetector detector = new GestureDetectorCompat(AppContext.getInstance(), new GestureDetector.SimpleOnGestureListener() { //@返回TRUE如果事件被消耗,否则假 @Override public boolean onSingleTapUp(MotionEvent e) { if (pageControl.getCurrentItem() != index) { pageControl.setCurrentItem(index); return true; } else { Object fragment = pageControl.getItem(index); if (fragment instanceof ITabActionX) { ((ITabActionX) fragment).simpleClickCheck(); } else if (fragment instanceof FragmentHolder) { ITabActionX finalFragmentByFragmentHolder = TopRefreshUtilX.findFinalFragmentByFragmentHolder(((FragmentHolder) fragment)); if (finalFragmentByFragmentHolder != null) { finalFragmentByFragmentHolder.simpleClickCheck(); } } return false; } } @Override public void onLongPress(MotionEvent e) { //Prt.d(TAG, "onLongPress"); super.onLongPress(e); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { //Prt.d(TAG, "onScroll"); return super.onScroll(e1, e2, distanceX, distanceY); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { //Prt.d(TAG, "onFling"); return super.onFling(e1, e2, velocityX, velocityY); } @Override public void onShowPress(MotionEvent e) { //Prt.d(TAG, "onShowPress"); super.onShowPress(e); } @Override public boolean onDown(MotionEvent e) { //Prt.d(TAG, "onDown"); return super.onDown(e); } @Override public boolean onDoubleTap(MotionEvent e) { int current = index; //Prt.d(TAG, "onDoubleTap"); Object fragment = pageControl.getItem(current); if (fragment instanceof ITabActionX) { ((ITabActionX) fragment).doubleClickCheck(); } else if (fragment instanceof FragmentHolder) { ITabActionX tabActonX = TopRefreshUtilX.findFinalFragmentByFragmentHolder(((FragmentHolder) fragment)); if (tabActonX != null) { tabActonX.doubleClickCheck(); } } return super.onDoubleTap(e); } @Override public boolean onDoubleTapEvent(MotionEvent e) { //Prt.d(TAG, "onDoubleTapEvent"); return super.onDoubleTapEvent(e); } /** * 这个方法不同于onSingleTapUp,他是在GestureDetector确信用户在第一次触摸屏幕后,没有紧跟着第二次触摸屏幕,也就是不是“双击”的时候触发 * @param e * @return */ @Override public boolean onSingleTapConfirmed(MotionEvent e) { //Prt.d(TAG, "onSingleTapConfirmed"); //有点慢。虽然确定是单击了 return true; } @Override public boolean onContextClick(MotionEvent e) { //Prt.d(TAG, "onContextClick"); return super.onContextClick(e); } }); @Override public boolean onTouch(View v, MotionEvent event) { detector.onTouchEvent(event); return true; // return super.onTouch(v,event); } }
未完待续。。。。
2018-3-21 17:46:58 继续 上代码
1 2 3 4 5 binding.radioBtn1.setOnTouchListener(new MyTopTouchListener(this, 0)); binding.radioBtn2.setOnTouchListener(new MyTopTouchListener(this, 1)); binding.radioBtn3.setOnTouchListener(new MyTopTouchListener(this, 2)); binding.radioBtn4.setOnTouchListener(new MyTopTouchListener(this, 3)); binding.radiogroup.setOnCheckedChangeListener(this);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 //递归寻找子fragment用 public interface FragmentHolder { Object getCurrentFragment(); } //通常回调给fragment 通知进行recycler的到顶部或者通知整个刷新 public interface ITabActionX { void simpleClickCheck(); void doubleClickCheck(); } //activity控制 public interface PageControlX { int getCurrentItem();//用来判断是否已经选中,没选中就调用setCurrentItem void setCurrentItem(int currentFixIndex); Object getItem(int position);//拿到object 进行判断 }
MyFragment实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Override public void simpleClickCheck() { binding.nestedscrollview.scrollTo(0, 0); } @Override public void doubleClickCheck() { if (binding == null) { return; } simpleClickCheck(); binding.swiperefreshLayout.setRefreshing(true); queryInfo(); }
某嵌套fragment实现
1 2 3 4 5 6 7 @Override public Object getCurrentFragment() { return getFragments().get(binding.viewpager.getCurrentItem()); // return onGetFragment(binding.viewpager.getCurrentItem()); }
FragmentHolder 递归寻找工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class TopRefreshUtilX { /** * 找出真正可以刷新的fragment * * @param fragment * @return */ public static ITabActionX findFinalFragmentByFragmentHolder(FragmentHolder fragment) { Object currentFragment = fragment.getCurrentFragment(); if (currentFragment instanceof ITabActionX) { return (ITabActionX) currentFragment; } else if (currentFragment instanceof FragmentHolder) { return findFinalFragmentByFragmentHolder((FragmentHolder) currentFragment); } else { return null; } } }
scrollview嵌套recyclerview的到顶刷新
1 2 3 4 5 6 7 8 9 10 11 12 13 // ITabActionX @Override public void simpleClickCheck() { Prt.w(TAG, "hashCode:" + this.hashCode()); AppThemeUtils.scrollTop(getDataBind().recyclerview,getDataBind().scrollView); } @Override public void doubleClickCheck() { simpleClickCheck(); AppThemeUtils.refreshRefreshFragment(this); }
滚动到顶部具体业务演示工具类,基本上可以解决大部分到顶部刷新,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public static void scrollTop(RecyclerView recyclerview, NestedScrollView scrollView) { if (recyclerview != null) { recyclerview.scrollToPosition(0); } if (scrollView != null) { scrollView.scrollTo(0, 0); } } public static void scrollTop(RecyclerView recyclerview) { scrollTop(recyclerview,null); }
MainActivity实现PageControlI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Override public int getCurrentItem() { View view = binding.radiogroup.findViewById(binding.radiogroup.getCheckedRadioButtonId()); int index = binding.radiogroup.indexOfChild(view); if (index != -1) { // View childAt = binding.radiogroup.getChildAt(index); } return index; } @Override public void setCurrentItem(int currentFixIndex) { View childAt = binding.radiogroup.getChildAt(currentFixIndex); if (childAt instanceof Checkable) { ((Checkable) childAt).setChecked(true); } else { Prt.e(TAG, "index not is not support check"); } } @Override public Fragment getItem(int position) { return arrayList.get(position); }