自定义ViewGroup实现Title自动隐藏功能(带源代码)

本文介绍了一种在App中实现标题栏随滚动自动隐藏的效果。通过自定义ScrollView监听滚动事件,结合九旧Android动画库,实现了标题栏的平滑显示与隐藏。此外,文章还提供了封装好的ViewGroup组件及使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<pre name="code" class="html">
 

1、概述

今天看到很多app都有Title自动隐藏功能,自己尝试写了一个最简单版本的。最后还封装了一下,喜欢的朋友可以下载工程看一下效果。
首先我们分析一下,这个title是在默认情况和我们滑动到顶部是自动出现的,Title的消失是在我们滑动了就消失的,但是滑动时如果Title已经消失了就不再播放消失动画了


2、简单的布局

我们分析一下布局文件,主要又Title和下面的滑块组成,这里我用FrameLayout包含TextView(标题)和ScrollView组成。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <customscrollview.ObservableScrollView
        android:id="@+id/scrollview1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

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

            <TextView
                android:layout_width="match_parent"
                android:layout_height="400dp"
                android:background="@color/colorPrimaryDark"
                android:text="1" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="400dp"
                android:background="@android:color/black"
                android:text="2" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="400dp"
                android:background="@color/colorAccent"
                android:text="3" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="400dp"
                android:background="@color/colorPrimary"
                android:text="4" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="400dp"
                android:background="@android:color/holo_blue_bright"
                android:text="5" />
        </LinearLayout>
    </customscrollview.ObservableScrollView>

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@android:color/white"
        android:gravity="center"
        android:text="Title"
        android:textColor="@android:color/holo_green_dark" />
</FrameLayout>


3、Title的动画

 这里的动画主要涉及2个,一个是Title展示的动画,一个是Title隐藏的动画。这里为了兼容低版本,我用到了nineoldandroid库。
Title展示动画:

 public void openTitle(){
        com.nineoldandroids.animation.ObjectAnimator objectAnimator =  ObjectAnimator
                .ofFloat(title, "translationY", -title.getHeight(), 0F);
        objectAnimator.setDuration(500).start();
        titleShow = true;
    }
Title隐藏动画:
 public void closeTitle(){
        ObjectAnimator
                .ofFloat(title, "translationY", 0F, -title.getHeight())
                .setDuration(500)
                .start();
        titleShow = false;
    }

注意:为了让他在已经隐藏不再隐藏,需要引入一个titleShow成员变量,用于标识是否已经隐藏过了。

4、什么时候播放动画

1.到达顶部并且Title已经隐藏,需要展示动画
2.不在顶部并且已经显示,播放隐藏动画
不过我怎么去实时获取ScrollView的滑动呢?抱歉,ScrollView并没有提供什么会回掉,只有View提供了一个setOnScrollChangeListener.不过View倒是提供了onScrollChanged方法,这里我们继承ScrollView,重写View的onScrollChanged方法。

先定义一个接口,用于回掉。
public interface ScrollViewListener {
    void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);
}
继承ScrollView,重写View的onScrollChanged方法。
public class ObservableScrollView extends ScrollView  {
    private ScrollViewListener scrollViewListener = null;
    public ObservableScrollView(Context context) {
        super(context);
    }

    public ObservableScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldx, int oldy) {
        super.onScrollChanged(x, y, oldx, oldy);
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
        }
    }
}
之后我们设置接口,并在onscrollChanged的地方,判断是否需要播放动画即可。
   scrollView1 = (ObservableScrollView) findViewById(R.id.scrollview1);
        scrollView1.setScrollViewListener(this);

@Override
    public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
        //在顶部,并且隐藏状态
        if (y == 0 && !titleShow) {
            openTitle();
            titleShow = true;
        }
        //不在顶部,并且展示状态
        if (y != 0 && titleShow){
            closeTitle();
            titleShow = false;
        }
    }

5、封装ViewGroup

之前的操作已经可以让我们完成要求了,但是我们想封装一下,为什么要封装,因为提高扩展性啊,哈哈哈!
这里我新建一个ViewGroup继承自FrameLayout,
 public AutoTitleScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }
    private void init(Context context){
        layoutInflater = LayoutInflater.from(context);
        //添加布局到Viewgroup
        contentView =  layoutInflater.inflate(R.layout.activity_main2, this);
        //this.addView(contentView);
        title = (TextView) findViewById(R.id.title);
        scrollView1 = (ObservableScrollView) findViewById(R.id.scrollview1);
        scrollView1.setScrollViewListener(this);
    }


6、怎么使用

1.Android Studio:
compile 'com.example.mylibrary:mylibrary:0.0.2'

2.在布局文件里面添加这个ViewGroup就行了。
 <com.example.zybang.meizudemo.customview.customscrollview.AutoTitleScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

7、源码与Github

github项目托管: 点击打开链接

优快云源码下载: 点击打开链接
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值