android tab单击到顶双击到顶部并刷新的解决方案

首先要看tab是由什么打造的,我这里演示用我自己开发的增强版本RadioGroupX做Tabhost也就是 Fragment切换这个增加版高仿源码,所以各位我写的再垃圾也不会垃圾到哪里去。
也就是说高仿源码自然可以兼容老版本的 RadioGroup其实是增加了可以加badge 小红点功能。

实现思路
为了方便扩展,所以给触摸事件类传递一个接口PageControlX,而不是一个activiy
给每一个tab设置触摸事件,设置之后原来的点击事件自然是不能触发了, 在自己实现的触摸类 编写具体业务逻辑,后寻找子fragment 或者view,所以我这里不写死为Fragment而是判断类型是否实现接口ITabActionX如果实现了ITabActionX就可以进行操作调用ITabActionX.doubleClickCheckITabActionX.simpleClickCheck,没有找到就判断是否实现了FragmentHolder 也就是有的可能是一层套一层的。ITabActionX tabActonX = TopRefreshUtilX.findFinalFragmentByFragmentHolder(((FragmentHolder) fragment));就得到了最终的ITabActionX
到顶部方法呢基本上只需要调用scrollView.scrollTo(0, 0); 或者recyclerview.scrollToPosition(0);就可以实现到顶部.刷新呢,各位自己操作好了。难点就是考察大家是否会触摸事件的拦截操作了

给每一个tab设置触摸事件,设置之后原来的点击事件自然是不能触发了单击事件也需要借助触发·GestureDetectorCompat
另外避免重复切换需要判断index

 public boolean onSingleTapUp(MotionEvent e) {
            if (pageControl.getCurrentItem() != index) {
                pageControl.setCurrentItem(index);
                return true;
            }
}

双击的寻找

    @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

package com.mm999.meiye.totoprefresh;

import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import com.mm999.meiye.AppContext;

/**
 * Created by qssq on 2018/3/21 qssq666@foxmail.com
 */
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
继续 上代码

 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);
//递归寻找子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实现


    @Override
    public void simpleClickCheck() {

        binding.nestedscrollview.scrollTo(0, 0);
    }

    @Override
    public void doubleClickCheck() {
        if (binding == null) {
            return;
        }
        simpleClickCheck();
        binding.swiperefreshLayout.setRefreshing(true);
        queryInfo();

    }

某嵌套fragment实现

    @Override
    public Object getCurrentFragment() {
        return getFragments().get(binding.viewpager.getCurrentItem());

        //        return onGetFragment(binding.viewpager.getCurrentItem());

    }

FragmentHolder 递归寻找工具类

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的到顶刷新

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

滚动到顶部具体业务演示工具类,基本上可以解决大部分到顶部刷新,

    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

    @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);
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,846评论 25 707
  • 原文链接:https://github.com/opendigg/awesome-github-android-u...
    IM魂影阅读 32,921评论 6 472
  • 冬日的阳光总是喜人的 尤其是将爱情照耀的如此透明 忠诚的冰倒映着浪漫 一季消融 一季凝固 这就是故事的开始 我独自...
    公子随笔阅读 227评论 0 2
  • 今天上了开学以来正式的第一节课,感觉两个班上下来完全不一样,一个安安静静,非常的配合我,而另一个班实在是吵得我难以...
    星空下的自己阅读 185评论 0 1
  • 第九本书,和第八本一起看,类型不同。这本书确实难啃,要仔细研读。参考了作者的前言,从第六章开始看起。 第六章:交流...
    陈加新阅读 549评论 0 4