Android小技巧之最快速简单的悬浮TAB

简介: 先看效果图吧image原理其实实现这样的效果是十分的简单的,继承ScrollView,监听onScrollChanged,根据滑动的距离,不断的layout需要悬浮的tab的位置。

先看效果图吧

img_8692023b2604dfc4e04ef24bc563f772.gif
image

原理

其实实现这样的效果是十分的简单的,继承ScrollView,监听onScrollChanged,根据滑动的距离,不断的layout需要悬浮的tab的位置。这只是一个简单的demo,主要提供的是一种思路,利用到实际中还是有点距离。

编码

  1. 继承ScrollView,暴露一个外接口,重写onScrollChanged方法,向接口提供scrollY位置。
  2. getViewTreeObserver().addOnGlobalLayoutListener,通过添加视图观察者监听来初始化tab的位置。
    
      
    public class ScrollLevitateTabView extends ScrollView {
        private OnScrollLintener onScrollLintener;
        public void setOnScrollLintener(OnScrollLintener onScrollLintener) {
            this.onScrollLintener = onScrollLintener;
        }
        public ScrollLevitateTabView(Context context) {
            this(context,null);
        }
    
        public ScrollLevitateTabView(Context context, AttributeSet attrs) {
            this(context, attrs,0);
        }
    
        public ScrollLevitateTabView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
        private void init() {
            //增加视图监听 在整个视图树绘制完成后会回调
            getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    onScrollLintener.onScroll(getScrollY());
                }
            });
        }
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            super.onScrollChanged(l, t, oldl, oldt);
            if (onScrollLintener != null) {
                onScrollLintener.onScroll(t);
            }
        }
    
        public interface OnScrollLintener{
            void onScroll(int scrollY);
        }
    }

布局中使用

直接将ScrollLevitateTabView作为根布局,嵌套一个FrameLayout方便更改tab的位置。FrameLayout中放真正的tab,嵌套的其它ViewGroup中正常布局,必须留有一个TAB的占位View


    <?xml version="1.0" encoding="utf-8"?>
    <aohanyao.com.scolltabview.ScrollLevitateTabView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/sltv"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                ................放自己的View
    
                <!--占位的Tab-->
                <TextView
                    android:id="@+id/flow_tab2"
                    android:layout_width="match_parent"
                    android:layout_height="48dp"
                    android:textColor="#fff"
                    android:textSize="20sp" />
                <!--占位的Tab-->
                ................放自己的View
            </LinearLayout>
            <!--真正的Tab-->
            <TextView
                android:id="@+id/flow_tab"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:background="#03a9f4"
                android:gravity="center"
                android:text="这里是悬浮的TAB"
                android:textColor="#fff"
                android:textSize="20sp" />
            <!--真正的Tab-->
        </FrameLayout>
    </aohanyao.com.scolltabview.ScrollLevitateTabView>

MainActivity

没什么代码量,FVB和设置滑动监听,然后在回调方法中不断的layout真正tab的位置


    public class MainActivity extends AppCompatActivity implements ScrollLevitateTabView.OnScrollLintener {
        //外层的ScrollView
        private ScrollLevitateTabView sltv;
        //真正的Tab
        private TextView flow_tab;
        //占位的Tab
        private TextView flow_tab2;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            flow_tab = (TextView) findViewById(R.id.flow_tab);
            flow_tab2 = (TextView) findViewById(R.id.flow_tab2);
            sltv = (ScrollLevitateTabView) findViewById(R.id.sltv);
            //设置监听
            sltv.setOnScrollLintener(this);
        }
    
        @Override
        public void onScroll(int scrollY) {
            //layout Tab的位置
            int top = Math.max(scrollY, flow_tab2.getTop());
            flow_tab.layout(0, top, flow_tab.getWidth(), top + flow_tab.getHeight());
        }
    }
    

最终就能达到效果了。

源码地址

目录
相关文章
|
4月前
|
安全 Android开发 开发者
【Android开发小技巧】扔掉这坑人的 Handler
【Android开发小技巧】扔掉这坑人的 Handler
42 0
|
2月前
|
Android开发
Android开发小技巧:怎样在 textview 前面加上一个小图标。
Android开发小技巧:怎样在 textview 前面加上一个小图标。
13 0
|
12月前
|
Android开发
【Android小技巧】分享Android Studio常用快捷键(持续更新)
ctrl+F4:关闭窗口 ctrl+H:打开此类的继承关系 ctrl+tab:切换窗口(应用内) ctrl+s:保存(好习惯需养成) shift+F10:编译运行 ctrl+l:在当前类查找关键词 Alt+7:查看此类的结构(方法、变量等) ctrl+p:查看此方法所有重载(光标需在括号内)
110 0
|
Java Android开发 Kotlin
一些实用的Android进阶小技巧
主要是利用application获取唯一的全局实例context,使得我们在任何场景都可以获取context
79 0
一些实用的Android进阶小技巧
|
Android开发
Android中TextView字体加粗小技巧
开发中经常会遇到字体加粗的需求,在使用系统字体的情况下,我们一般是通过在布局文件中给TextView设置`android:textStyle="bold"`属性。 如果你们的设计师小姐姐不想使用Android的这种加粗效果,只是想要接近于`PingFang SC Medium`的效果,那么TextView的`bold`就有点没脸看了。
|
安全 Android开发
android在ida动态调试的一些小技巧
android在ida动态调试的一些小技巧
265 0
android在ida动态调试的一些小技巧
|
存储 缓存 安全
【整理篇】Android 开发小技巧
【整理篇】Android 开发小技巧
93 0
|
XML 编解码 Android开发
Android中的资源复用小技巧
做了很多项目,发现每个项目里都有大量的相似图标,比如每个颜色一种、每个角度一种(左箭头、右箭头)等等,虽然这些图标很小占用不了太多资源。但是当我们需要change的时候就得一个个去替换,其实在android里有很多小技巧可以让这些资源进行复用,减少体积的同时也可以使项目结构更加清晰。 这里总结的一些比较常用的复用,包扩:自适应、变色、旋转、阴影、组合、透明度、剪裁、留白等
235 0
|
缓存 Android开发 容器
android小技巧之不缓存的ViewPager
前言 在开发中我们会经常用到ViewPager这个类,比如引导页的啦,主页啦,等等之类的。 一般情况下,我在ViewPger中都是放的Framgnt,这样简单有方便,但是ViewPager却会默认的缓存当前页面的最近两个页面,于是问题就产生了,我们的需...
2072 0
|
Android开发
Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager
Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager
Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager