关于做悬停的一些奇葩想法(利用removeView和addView)

其实关于悬停,自己总结有如下几种方案:

第一种:最早的时候几乎都是利用FrameLayout,在需要悬浮的地方放置一个假的悬停控件,监听滚动事件,从而进行显示和隐藏。

优点:

①几乎没有技术难度

②任意扩展

缺点:

需要维护两套悬停控件(当仅仅是指示剂的还好维护,如果悬停的是类似商城的那种多样式的下拉选择框的,几乎就是准备跑路吧)

第二种:多亏谷歌大佬心疼我们,给我们提供了协调者布局,可以很好的实现单个悬停效果(当然对属性和使用方法很熟悉的前提下,是可以实现更多种悬停样式,但是也有边界)

优点:

①原生控件,体验很好

②多种组合属性,实现各种复杂效果

缺点:

①学习成本高,截止目前还有很多Android开发者不会用协调者布局,甚至都没听过

②复杂场景下,很难达到效果

第三种:是自己想尝试的,就是在原来的滚动布局中移除悬停的控件,直接add到悬停的位置

优点:

①减少维护一套UI成本

②扩展性兼容性好

缺点:

①复杂场景不行

②体验不是很好

但是经过自己用第三种方式的多次试验,其实发现扩展性极强,能够实现自己想要的很多要求,这个需要具体场景具体分析,大家真碰到了,可以用下面源码进行改造实现,看看能否实现自己想要的动效。

下面附上第三种方案的源码和录屏:

录屏:

悬浮效果

源码

测试页面MainActivity2

package com.example.myapplication00;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

public class MainActivity2 extends AppCompatActivity {

    private LinearLayout ll01, ll02, ll022;
    private TextView tv02, tvSet;
    private ScrollViewCustomJava scv;

    private int offset;

    private boolean isFloat;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);


        ll01 = findViewById(R.id.ll01);
        ll02 = findViewById(R.id.ll02);
        ll022 = findViewById(R.id.ll022);
        tv02 = findViewById(R.id.tv02);
        tvSet = findViewById(R.id.tvSet);
        scv = findViewById(R.id.scv);

        offset = dip2px(this, 420);

        scv.setOnScrollListener(new ScrollViewCustomJava.OnScrollListener() {
            @Override
            public void onScroll(int startScrollX, int startScrollY, int endScrollX, int endScrollY) {
                tv02.setText("endScrollY::" + endScrollY);
                Log.d("onScroll---endScrollY::", endScrollY + "---offset::" + offset);
                if(endScrollY >= offset){
                    if(!isFloat){
                        isFloat = true;
                        ll022.removeView(tv02);
                        ll02.addView(tv02);
                    }
                }else{
                    if(isFloat){
                        isFloat = false;
                        ll02.removeView(tv02);
                        ll022.addView(tv02);
                    }
                }
            }
        });


        tvSet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ll022.removeView(tv02);
                ll02.addView(tv02);
            }
        });

    }

    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}

 自定义的能监听Scrollview的滚动的控件(主要是系统没提供,需要自己实现)

package com.example.myapplication00;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;

public class ScrollViewCustomJava extends ScrollView {
    private OnScrollListener onScrollListener;

    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }

    public ScrollViewCustomJava(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (onScrollListener != null) {
            //一定要注意着的int值都是像素值,而我们实际用的时候应该是dp,记得自己进行转换
            onScrollListener.onScroll(oldl, oldt, l, t);
        }
    }

    interface OnScrollListener {
        /**
         * 回调坐标值  一般ScrollView只有Y值变化, HorizontalScrollView是x值变化
         *
         * @param startScrollX 滑动之前的值
         * @param startScrollY 滑动之前的值
         * @param endScrollX   滑动之后的值
         * @param endScrollY   滑动之后的值
         */
        void onScroll(int startScrollX, int startScrollY, int endScrollX, int endScrollY);
    }
}

 这是MainActivity2的xml布局

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

    <com.example.myapplication00.ScrollViewCustomJava
        android:id="@+id/scv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


        <LinearLayout
            android:id="@+id/ll01"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="20dp"
            android:background="#ff0000">

            <TextView
                android:id="@+id/tv01"
                android:layout_width="match_parent"
                android:layout_height="400dp"
                android:textSize="14sp"
                android:text="北京的秋雨,如同一曲悠扬的古筝,在空气中弥漫着淡淡的诗意。在这座繁华都市的某个角落,我静静地感受着秋雨带来的独特魅力。

雨后的北京,仿佛被洗涤过的画卷。古老的建筑在雨后显得更加庄重典雅,泛着历史的光华。湿润的街道映衬着红黄绿三色交织的树叶,萧索中透露出深沉的美感。西山国家森林公园的枫叶在雨中更加娇艳,让人不禁陶醉在这片秋色之中。

秋雨中的北京人,也别有一番韵味。街头的商贩在雨中忙碌地摆摊,为生活奏响了一曲曲朴实的乐章。行人在雨中疾走,似乎在追赶着什么,又似乎在寻找着什么。还有那些骑车人,披着雨衣在马路上穿梭,犹如一道道流动的风景线。

在这座城市里,秋雨不仅仅是一种自然现象,更是一种文化情感的体现。古老的胡同在雨中显得更加有韵味,让人不禁想起那些传世的历史文化。在雨中漫步于南锣鼓巷,感受着传统与现代的文化冲击。这里不仅有老北京的味道,还有年轻人的活力。手工艺人们在雨中认真地制作着各种小玩意,为这座城市增添了一份匠心之美。

在这场秋雨中,我也有了许多思考。生活在北京这个繁华都市,我们每天都在为了梦想而奔波。然而,在这场秋雨中,我意识到我们需要在忙碌中学会慢下来,去感受大自然的美好,去体会生活的本质。只有这样,我们才能更好地理解这个世界,更好地理解自己。

总之,北京的秋雨是一种独特的魅力,是一种诗意的存在。它让我们感受到自然的美好,体会到生活的韵味。在这场秋雨中,我们不仅可以感受到这座城市的历史与文化,还可以在其中寻找到生活的真谛。让我们一起沉浸在这场秋雨中,感受这份美好,感受这份诗意。"/>


            <LinearLayout
                android:id="@+id/ll022"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:orientation="vertical">


                <TextView
                    android:id="@+id/tv02"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:text="002"
                    android:gravity="center"
                    android:background="#ffffff"/>


            </LinearLayout>




            <TextView
                android:id="@+id/tv03"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:textSize="30dp"
                android:text="北京的秋雨,如同一曲悠扬的古筝,在空气中弥漫着淡淡的诗意。在这座繁华都市的某个角落,我静静地感受着秋雨带来的独特魅力。

雨后的北京,仿佛被洗涤过的画卷。古老的建筑在雨后显得更加庄重典雅,泛着历史的光华。湿润的街道映衬着红黄绿三色交织的树叶,萧索中透露出深沉的美感。西山国家森林公园的枫叶在雨中更加娇艳,让人不禁陶醉在这片秋色之中。

秋雨中的北京人,也别有一番韵味。街头的商贩在雨中忙碌地摆摊,为生活奏响了一曲曲朴实的乐章。行人在雨中疾走,似乎在追赶着什么,又似乎在寻找着什么。还有那些骑车人,披着雨衣在马路上穿梭,犹如一道道流动的风景线。

在这座城市里,秋雨不仅仅是一种自然现象,更是一种文化情感的体现。古老的胡同在雨中显得更加有韵味,让人不禁想起那些传世的历史文化。在雨中漫步于南锣鼓巷,感受着传统与现代的文化冲击。这里不仅有老北京的味道,还有年轻人的活力。手工艺人们在雨中认真地制作着各种小玩意,为这座城市增添了一份匠心之美。

在这场秋雨中,我也有了许多思考。生活在北京这个繁华都市,我们每天都在为了梦想而奔波。然而,在这场秋雨中,我意识到我们需要在忙碌中学会慢下来,去感受大自然的美好,去体会生活的本质。只有这样,我们才能更好地理解这个世界,更好地理解自己。

总之,北京的秋雨是一种独特的魅力,是一种诗意的存在。它让我们感受到自然的美好,体会到生活的韵味。在这场秋雨中,我们不仅可以感受到这座城市的历史与文化,还可以在其中寻找到生活的真谛。让我们一起沉浸在这场秋雨中,感受这份美好,感受这份诗意。"/>



        </LinearLayout>




    </com.example.myapplication00.ScrollViewCustomJava>



    <LinearLayout
        android:id="@+id/ll02"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginStart="20dp"
        android:layout_marginEnd="20dp"
        android:orientation="vertical"
        android:background="#000000ff"/>



    <TextView
        android:id="@+id/tvSet"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:layout_marginTop="50dp"
        android:text="开始变形"
        android:visibility="gone"/>


</FrameLayout>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值