Android 簡單實現控件滑動固定效果

效果圖:

控件滑動固定

實現思路:

??首先我們需要實時的獲取滑動的Y值scrollDistanceY(可以理解為滑動了的距離)薄风,可以通過ScrollView的getScrollY();方法來獲取返顺。我們繼承ScrollView重寫Touch方法等舔,隨觸摸事件反饋scrollDistanceY傀履。需要特殊處理手指離開后屏幕還在滑動導致 scrollDistanceY改變的情況捡多。
??在xml布局中撑帖,綠色的固定布局View我們需要寫兩個绪励,一個與頭部布局重合肿孵,位于APP頂部唠粥,另一個與列表中。在Activity我們獲取內部固定布局距離頂部的高度停做,與我們實時獲取的scrollDistanceY做比較晤愧,控制外部固定布局是否顯示,達到效果圖的效果蛉腌。

代碼實現:

  1. 重寫ScrollView官份,實時反饋scrollDistanceY
package com.wusy.adv;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;


/**
 * Created by XIAO RONG on 2018/8/23.
 * 這是一個能夠實時向主View提供滑動距離Y值的ScrollView(滑動的高度)
 * 能夠運用此ScrollView實現在內部View固定頂部布局的需求
 */

public class FixedHeadScrollView extends ScrollView{
    public FixedHeadScrollViewListener listener;
    private int scrollDistanceY;
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 1:
                    int newY=getScrollY();//在手指離開屏幕的短暫時間間隔后再次獲取Y值
                    if(newY!=scrollDistanceY){//如果不相等,說明手指離開后烙丛,屏幕仍然在滑動,繼續(xù)更新scrollDistanceY的值
                        scrollDistanceY=newY;
                        listener.sendDistanceY(scrollDistanceY);
                        handler.sendEmptyMessageDelayed(1,5);
                    }
                    break;
            }
        }
    };
    public FixedHeadScrollView(Context context) {
        this(context,null);
    }

    public FixedHeadScrollView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public FixedHeadScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if(ev.getAction()==MotionEvent.ACTION_UP){
            handler.sendEmptyMessageDelayed(1,30);
        }
        scrollDistanceY=getScrollY();
        listener.sendDistanceY(scrollDistanceY);
        return super.onTouchEvent(ev);

    }

    public interface  FixedHeadScrollViewListener{
        void sendDistanceY(int distance);
    }

    public void setFixedHeadScrollViewListener(FixedHeadScrollViewListener listener) {
        this.listener = listener;
    }
}
  1. xml代碼贯吓,固定布局要寫兩個,控制一個的顯隱蜀变。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layout_total">

    <com.wusy.adv.FixedHeadScrollView
        android:id="@+id/scrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/layout_head"
                android:layout_width="match_parent"
                android:layout_height="200dp"
                android:background="#e21919"
                android:gravity="center"
                android:text="頭部布局"
                android:textColor="#ffffff"
                android:textSize="17dp" />

            <TextView
                android:id="@+id/layout_fixed_inside"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#10e91b"
                android:gravity="center"
                android:text="固定布局"
                android:textColor="#ffffff"
                android:textSize="17dp" />


            <TextView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:background="#19ace2"
                android:gravity="center"
                android:text="列表布局"
                android:textColor="#ffffff"
                android:textSize="17dp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:background="#d408bc"
                android:gravity="center"
                android:text="列表布局"
                android:textColor="#ffffff"
                android:textSize="17dp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:background="#f7eb00"
                android:gravity="center"
                android:text="列表布局"
                android:textColor="#ffffff"
                android:textSize="17dp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:background="#192de2"
                android:gravity="center"
                android:text="列表布局"
                android:textColor="#ffffff"
                android:textSize="17dp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:background="#19ace2"
                android:gravity="center"
                android:text="列表布局"
                android:textColor="#ffffff"
                android:textSize="17dp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:background="#d408bc"
                android:gravity="center"
                android:text="列表布局"
                android:textColor="#ffffff"
                android:textSize="17dp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:background="#f7eb00"
                android:gravity="center"
                android:text="列表布局"
                android:textColor="#ffffff"
                android:textSize="17dp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:background="#192de2"
                android:gravity="center"
                android:text="列表布局"
                android:textColor="#ffffff"
                android:textSize="17dp" />
        </LinearLayout>

    </com.wusy.adv.FixedHeadScrollView>

    <TextView
        android:id="@+id/layout_fixed_outside"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#10e91b"
        android:gravity="center"
        android:visibility="gone"
        android:text="固定布局"
        android:textColor="#ffffff"
        android:textSize="17dp" />
</RelativeLayout>
  1. Activity中,實現FixedHeadScrollView提供的接口介评。獲取內層固定布局距離固定位置的高度库北,與scrollDistanceY比較,當內層固定布局達到固定位置们陆,則顯示外層固定布局寒瓦,反之隱藏。
package com.wusy.adv;

import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.wusy.wusylibrary.base.BaseActivity;

/**
 * Created by XIAO RONG on 2018/8/23.
 */

public class HomeActivity extends BaseActivity implements FixedHeadScrollView.FixedHeadScrollViewListener{
    private TextView layout_inside,layout_outside;
    private int topDistance;
    private FixedHeadScrollView scrollView;

    @Override
    public int getContentViewId() {
        return R.layout.activity_home;
    }

    @Override
    public void findView() {
        layout_inside=findViewById(R.id.layout_fixed_inside);
        layout_outside=findViewById(R.id.layout_fixed_outside);
        scrollView=findViewById(R.id.scrollview);
    }

    @Override
    public void init() {
        scrollView.setFixedHeadScrollViewListener(this);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if(hasFocus){
            topDistance=layout_inside.getTop();
            Log.i("msg","topDistance="+topDistance);
        }
    }

    @Override
    public void sendDistanceY(int distance) {
        Log.i("msg","看這里——"+distance);
        if(distance>=topDistance){
            layout_outside.setVisibility(View.VISIBLE);
        }else{
            layout_outside.setVisibility(View.GONE);
        }
    }
}

注意:

  1. 在獲取內部固定布局距離頂部的距離的時候坪仇,不要在onCreate()中去執(zhí)行杂腰,由于界面還沒有完全繪制完成,獲取到的距離值永遠為0椅文。建議在onWindowFocusChanged()中去獲取喂很。
  2. xml中,外部固定布局一定要放在scrollView外面皆刺。
  3. 記得處理手指離開屏幕后少辣,界面仍然在滑動,導致外層固定布局的顯示隱藏控制有誤羡蛾。

我的博客即將搬運同步至騰訊云+社區(qū)漓帅,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=32rm642dvbr7

End

筆者的Github Blog,希望各位大大提意見痴怨,點個star忙干,謝謝
傳送門:WusyBlog

求互粉互贊,互贊所有文章可以私聊我浪藻。哈哈捐迫,希望我們的原創(chuàng)文章能讓更多朋友看到,一起變強爱葵。

筆者新開通了微信公眾號——飲水思源|wusy 計劃持續(xù)運營弓乙,每日為您分享Android干貨末融、原創(chuàng)文章。微信掃描下方的二維碼關注我暇韧,開發(fā)學習路上不迷路勾习。謝謝各位


飲水思源|wusy.jpg
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市懈玻,隨后出現的幾起案子巧婶,更是在濱河造成了極大的恐慌,老刑警劉巖涂乌,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艺栈,死亡現場離奇詭異,居然都是意外死亡湾盒,警方通過查閱死者的電腦和手機湿右,發(fā)現死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來罚勾,“玉大人毅人,你說我怎么就攤上這事〖庋辏” “怎么了丈莺?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長送丰。 經常有香客問我缔俄,道長,這世上最難降的妖魔是什么器躏? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任俐载,我火速辦了婚禮,結果婚禮上登失,老公的妹妹穿的比我還像新娘瞎疼。我一直安慰自己,他們只是感情好壁畸,可當我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布贼急。 她就那樣靜靜地躺著,像睡著了一般捏萍。 火紅的嫁衣襯著肌膚如雪太抓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天令杈,我揣著相機與錄音走敌,去河邊找鬼。 笑死逗噩,一個胖子當著我的面吹牛掉丽,可吹牛的內容都是我干的跌榔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼捶障,長吁一口氣:“原來是場噩夢啊……” “哼僧须!你這毒婦竟也來了?” 一聲冷哼從身側響起项炼,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤担平,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后锭部,有當地人在樹林里發(fā)現了一具尸體暂论,經...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年拌禾,在試婚紗的時候發(fā)現自己被綠了取胎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡湃窍,死狀恐怖闻蛀,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情坝咐,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布析恢,位于F島的核電站墨坚,受9級特大地震影響,放射性物質發(fā)生泄漏映挂。R本人自食惡果不足惜泽篮,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柑船。 院中可真熱鬧帽撑,春花似錦、人聲如沸鞍时。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽逆巍。三九已至及塘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間锐极,已是汗流浹背笙僚。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留灵再,地道東北人肋层。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓亿笤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親栋猖。 傳聞我的和親對象是個殘疾皇子净薛,可洞房花燭夜當晚...
    茶點故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內容