天天看點

Android小技巧之最快速簡單的懸浮TAB

先看效果圖吧

Android小技巧之最快速簡單的懸浮TAB

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

最終就能達到效果了。

源碼位址

繼續閱讀