Android 自定义ScrollView - 头部可拉伸

【Android】头部背景图片可伸缩的ScrollView 1、需求 1、头部ImageView可伸缩,且不能影响其他控件摆放位置。 2、期望:可以自动识别ImageView位置,不用指定缩放View。 3、可以指定是否横向拉伸。 4、可以设置纵向平移的View。 2、实现方式 1、使用纯动画方式实现 经实践,使用纯动画方式可以实现头部图片伸缩效果,但是图片下方的布局不会跟着平移。本以为属性动画中的缩放动画是修改了控件的宽高实现,但实际来看并不是,那究竟属... 阅读详情

一、直接上代码

public class HeadZoomScrollView extends ScrollView {

    //头部View
    private View mZoomView;
    // View的宽度
    private int mZoomViewWidth;
    // View的高度
    private int mZoomViewHeight;

    //是否在滑动
    private boolean isScrolling = false;
    //第一次按下的坐标
    private float firstPosition;
    //缩放系数
    private float mScrollRate = 0.3f;
    //回弹系数
    private float mReplyRate = 0.5f;

    public HeadZoomScrollView(Context context) {
        super(context);
    }

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

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

    /**
     * 布局加载完后调用此方法,
     * 根据xml布局getChildAt(0)拿到的是LinearLayout,vg.getChildAt(0)拿到的是RelativeLayout。
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        // 判断指定位置的视图是否为空。
        if(getChildAt(0) != null){
            // 返回组中指定位置的视图。
            ViewGroup vg = (ViewGroup) getChildAt(0);
            if (vg.getChildAt(0) != null){
                // 拿到所需的视图
                mZoomView = vg.getChildAt(0);
            }
        }
    }

    /**
     * 触摸事件
     * @param ev
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // 获取mZoomView的宽高
        if (mZoomViewWidth <= 0 || mZoomViewHeight <= 0){
            mZoomViewWidth = mZoomView.getMeasuredWidth();
            mZoomViewHeight = mZoomView.getMeasuredHeight();
        }
        // 返回正在执行的操作的类型。
        switch (ev.getAction()){
            case MotionEvent.ACTION_MOVE: // 滑动
                if (!isScrolling){
                    // 等于0说明没有滑动,是第一次滑动,记录第一次按下的坐标
                    if (getScrollY() == 0) {
                        firstPosition = ev.getY();
                    }else {
                        break;
                    }
                }
                // 计算缩放值
                // 公式:(当前的位置 - 第一次按下的位置) * 缩放系数
                int distance = (int) ((ev.getY() - firstPosition) * mScrollRate);
                if (distance < 0) {
                    break;
                }
                isScrolling = true;
                setZoomView(distance);
                break;
            case MotionEvent.ACTION_UP: // 抬起
                isScrolling = false;
                replyZoomView();
                break;
        }


        return true;
    }

    /**
     * 回弹动画
     */
    private void replyZoomView() {
        // ViewGroup.LayoutParams lp = mZoomView.getLayoutParams();
        // lp.width = mZoomViewWidth;
        // lp.height = mZoomViewHeight;
        // ((MarginLayoutParams)lp).setMargins(0,0,0,0);
        // mZoomView.setLayoutParams(lp);

        // 计算下拉的缩放值再让属性动画根据这个值复原
        // 现在的宽 - 原本的宽
        int distance = mZoomView.getMeasuredWidth() - mZoomViewWidth;
        // 实现属性动画
        ValueAnimator valueAnimator = ValueAnimator
                .ofFloat(distance, 0)
                .setDuration((long) (distance * mReplyRate));
        // 将监听器添加到在动画生命周期内发送更新事件的监听器集中。需要添加监听器否则调用start(),也没有效果
        valueAnimator.addUpdateListener(animation -> {
            setZoomView((Float) animation.getAnimatedValue());
        });
        valueAnimator.start();
    }

    /**
     * 缩放View
     * @param zoom
     */
    private void setZoomView(float zoom) {
        if (mZoomViewWidth <= 0 || mZoomViewHeight <= 0){
            return;
        }
        // 获取布局参数对象,设置宽高
        ViewGroup.LayoutParams lp = mZoomView.getLayoutParams();
        lp.width = (int)(mZoomViewWidth + zoom);
        // 公式:现在的宽 / 原本的宽 得到 缩放比例 * 原本的高 得到缩放的高
        lp.height = (int)(mZoomViewHeight * ((mZoomViewWidth + zoom) / mZoomViewWidth));
        // 设置间距
        // 公式:- (lp.width - mZoomViewWidth) / 2
        ((MarginLayoutParams)lp).setMargins(- (lp.width - mZoomViewWidth) / 2,0,0,0);
        mZoomView.setLayoutParams(lp);
    }
}

二、使用

<com.chenfuhai.framework.view.HeadZoomScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <!--头部-->
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="240dp">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/img_me_bg" />
        </RelativeLayout>

        <!--个人信息-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <!--个人信息-->
            <LinearLayout
                android:id="@+id/ll_me_info"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="@android:color/white"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:paddingLeft="15dp"
                android:paddingRight="15dp">
                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/img_user_info_icon" />
                <TextView
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_weight="1"
                    android:text="@string/text_me_item_title_1"
                    android:textColor="@android:color/black" />
                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/img_right_arrow" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</com.chenfuhai.framework.view.HeadZoomScrollView>

三、注意事项

1、ScrollView继承自ViewGroup,所以ScrollView属于自定义ViewGroup。

Android进阶之路 - 拉伸的弹簧效果 因为在一些app中看到了图片的下拉放大,同时自带回弹的效果,所以在网上找了一个,同时尝试实现了一下,勉强满足基本需求,所以在此用于记录,可直接copy使用... 阅读详情

相关推荐

Ubuntu 22.04下GNU Radio 3.10全家桶编译避坑实录:从UHD、VOLK到WiFi收发模块gr-ieee802-11

本文详细介绍了在Ubuntu 22.04系统下编译安装GNU Radio 3.10全家桶的完整流程,包括UHD驱动、VOLK优化库以及WiFi信号处理模块gr-ieee802-11的集成。通过逐步指导解决版本兼容性和依赖问题,帮助研究人员快速搭建高效的软件定义无线电开发环境,特别适合使用USRP设备进行无线通信研究的开发者。

weixin_30825199的博客 447

Android自定义ScrollView实现拉伸效果

ScrollView在项目中使用的特别多但如果想实现那种下拉或者上滑时带有拉伸感的就需要自己继承ScrollView去重写里面的方法了,今天就实现一下自定义ScrollView。 定义一个名为DefinitionScrollView的类代码如下 package com.ranlegeran.leranfinancial.view; import android.content.Context; ...

然了个然 1187

AG16K MCU ARM Cortex M3

其中,Input文件为Keil生成的mcu程序文件,输出为合成后的存储格式Bin文件,Program address 为上方表格中“程序运行 RAM 地址(4bytes)”,即 Keil 中设置的程序运行地址。其中 MCU 程序的地址,根据 mcu.ip 中设置的 FLASH_BIAS 进行设置。AG16K MCU 的 FPGA 工程中,需调用 alta_mcu_m3 的硬核 IP,包含在 alta_sim.v 的库文。Quartus II。//MCU 程序在 FLASH 中存放的首地址。

Embeded_FPGA的博客 1806

android 滑动scrollview 头部标题透明度改变

/AGB由相关工具获得,或者美工提供。//待修改头部 图片视频控件 高度 测试。// 只是layout背景透明(仿知乎滑动效果)

Ivory_wiki的博客 806

金蝶云星空初级实施认证考题

Q4.[单选题] (1.5分) 总账中的多账簿账表主要是基于什么进行查看的Q47.[多选题] (2.5分) 销售订单的收款计划页签勾选预收之后,预收控制环节可以控制哪些节点?

m0_51994557的博客 3121

基于stm32平台上的IC-MU磁绝对值编码器SPI通讯和码盘数据处理

基于stm32平台上的IC-MU磁绝对值编码器SPI通讯和码盘数据处理

watch361的博客 1万+

Android设置ScrollView回到顶部的三种方式

一、ScrollView.scrollTo(0,0)  直接置顶,瞬间回到顶部,没有滚动过程,其中Y值可以设置为大于0的值,使Scrollview停在指定位置; 二、ScrollView.fullScroll(View.FOCUS_UP)  类似于手动拖回顶部,有滚动过程; 三、ScrollView.smoothScrollTo(0, 0) 类似于手动拖回顶部,有滚动过程,其中Y值可以设置为大

xuanhg221的博客 1万+

Revit二次开发——不启动Revit,做rvt文件数据导出

Revit二次开发——不启动Revit,做rvt文件数据导出Node.js部分调用C#端供外部调用的dllC#部分调用RevitNet.dll,做数据导出exe做外部调用dll总结功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 N

Y.Jerome的专栏 4111

android 自定义ScrollView控件上拉和下拉有拉伸效果

普通的scrollView下拉到顶部时就不动了,而如qq设置界面中的布局,下拉到顶端时还能下拉一段距离。此自定义scrollView就可以实现这样的效果。       这是我在网上找的自定义scrollView代码,会用就行了。 首先,自定义UserDefineScrollView控件。 UserDefineScrollView.java文件: package com.

fxjzzyo的博客 4193

DeepSeek API调用太复杂?OneAPI一站式聚合解决方案

本文介绍了OneAPI如何作为一站式聚合解决方案,简化DeepSeek API的调用流程。通过统一接口、智能路由和模型映射等核心功能,OneAPI大幅降低了多API适配的复杂性,提升开发效率。文章还提供了详细的部署指南和高阶使用技巧,帮助开发者快速实现API聚合管理。

weixin_27215337的博客 381

ArcMap 10.7/10.8启动加载界面后闪退?可能是这个隐藏的Normal.mxt模板文件在搞鬼

本文深入分析了ArcMap 10.7/10.8启动加载界面后闪退的问题,指出Normal.mxt模板文件损坏是常见原因。提供了从定位、删除模板文件到系统级修复的完整解决方案,帮助GIS工程师快速恢复工作流程。

weixin_28523493的博客 331

Android 沉浸式状态栏 头部可拉伸带有一键置顶功能

一:实现沉浸式状态栏,头部可以拉伸,头部图片可下拉放大,带有一键置顶功能  先看看三个步骤: 1:在AndroidManifest.xml中设置Activity的属性为android:theme="@android:style/Theme.NoTitleBar" 2:在Layout的第一个布局中设置与头部的间隔(android:layout_marginTop="25dp",当然具体间隔多少...

shenggaofei的博客 1849

Unity Shader之路(一)什么是Unity Shader?

Unity Shader前言什么是UnityShaderUnity Shader和材质的关系 前言 众所周知,要想当游戏开发工程师,Unity中的Shader编写不得不摸,这一系列文章我将描写我的Shader学习之路,致敬冯乐乐的书Unity Shader入门精要,此篇什么是Unity Shader?希望能给后人一点方向 我们刚开始接触Unity的时候,总是会遇到材质,但是不了解材质都是什么,为什么可以在很多材质中选择,为什么有时候选择了其他材质后就不能达到我们想要的结果,为什么资源商店有那么多的材质,山.

TurboQ珞珈 2239

沉浸式状态栏+头部拉伸+一键置顶

一些普通的界面加上这些效果应该还是不错的,所以就抽空写了这个小小的demo. Demo传送门 : http://download.youkuaiyun.com/detail/as_jon/9651533思路: 1.沉浸式状态栏 : 修改系统状态栏属性,使他始终与顶部导航栏色值一样. 2.头部拉伸跟一键置顶 : 自定义 Scroll View ,获取界面滑动高度,然后做出相应的操作.代码如下:Main A

总之岁月漫长,然而值得等待。 4695

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

可拉伸头部控件

可拉伸头部控件 原理:滑动时设置包含背景控件的大小。 自定义属性: values>attrs.xml xml version="1.0" encoding="utf-8"?> name="TractionScrollView"> name="bg" format="reference" /> name="head" format="ref

melody534056585的博客 840

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Android自定义view仿写QQ空间可拉伸头部控件

先来看下仿照QQ空间顶部图片过度下拉时,顶部图片放大回弹的效果,完整项目:https://github.com/buder-cp/CustomView/tree/master/buder_DN_view/buderdn20 业务逻辑包括:顶部图片可以下拉,当过度下拉时会有顶部图片放大的效果,在松手时会有顶部图片回弹效果。 我们看下大致看下需要重写哪些方法才能完成上面的需求。 首先肯定要有...

王温暖的博客 619

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

仿QQ空间之打造个性化可拉伸头部控件

最近有研究了QQ空间可拉伸头部控件的listView。如何去做呢?这里使用了自定义listView的方法。先看效果图吧:究竟如何去做呢? 可以用的方法有: * 1.继承 extends ViewGrop * 2.RecycleView +Behavior+CoordinateLayout * 3.ViewGroup 组合控件 * 4.ListView + headView这次我们主要

这个时代,作为程序员可能要学习小程序 2089

ScrollView的拉伸效果

  /* * @Comment :下拉回弹效果 * @Created :2018/7/6 11:20 * @Name : YJ */public class BounceScrollView extends ScrollView { private static final String TAG = "BounceScrollView"; private View ...

lanrenxiaowen的博客 425

Android沉浸式状态栏 + scrollView顶部伸缩 + actionBar渐变

因为文件太多,全部展示会影响篇幅,暂时就先列举这些部分截图。

2301_79655511的博客 835

android 底部上拉界面,Android 上拉下拉界面的弹性ScrollView效果实现

1.需求:像Ios那样上拉下拉实现动画回弹效果效果图:2.具体实现:继承ScrollView,重写dispatchTouchEvent()方法,判断上下滑动,计算距离,手指松开后实现动画效果,回到正常布局位置。实现代码:package com.mingyansu.splash;import android.annotation.SuppressLint;import android.content...

weixin_35986497的博客 683

自定义ScrollView 实现图片放大,上滑修改标题栏状态

一.功能介绍自定义ScrollView实现图片拉伸效果,下拉放大头部图片,监听滑动,改变标题头部是个图片,下面是个WebView,滑动改变标题状态;二.代码介绍1.自定义ScrollView ,重写onTouchEvent()方法,监听触摸下拉 上滑位置,实现图片放大以及回弹;@Override public boolean onTouchEvent(MotionEvent ev) { ...

shanshan_1117的博客 472

下拉顶部拉伸效果

如图下拉时顶部拉伸效果 代码如下: 创建:DampView public class DampView extends ScrollView { private static final int LEN = 0xc8; private static final int DURATION = 500; private static final int MAX_DY = 200; priva...

weixin_33739541的博客 182

[Android] 带阻尼效果的可拉伸的HorizontalScrollView

昨天美工说需要带苹果的带阻尼效果的可拉伸的HorizontalScrollView。然后花了几个小时实现了效果。 代码如下: package view; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.view.Moti

darling_shadow的专栏 3155

下拉头布局,弹簧效果,头布局滑动和ScrollVIew滑动冲突的解决

package com.zft.tygj.view; import android.animation.ValueAnimator; import android.content.Context; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.util.Lo...

Fan的博客 413

Android中ScrollView实现拖拽反弹效果动画

public class BounceScrollView extends ScrollView { private View inner;// 孩子View private float y;// 点击时y坐标 private Rect normal = new Rect();// 矩形(这里只是个形式,只是用于判断是否需要动画.) privat

道哥的技术博客 4815

上下拉伸图片-第三方开源-PullToZoomListViewEx 实现阻尼效果

本文要说的PullToZoomScrollViewEx 实现阻尼效果 什么是阻尼效果。简单解释就是一张图片,当你按住向下拖动,图片跟着拉升方大,当你松开时,回弹到原来的效果,在Android 上我们这种效果叫做阻尼效果。 这里我们用一个第三的 PullToZoomScrollViewEx 来实现,他的原理是自己定义的view 继承的我们ScrollView,设置我们初始的高度,然后实现下拉的

qq_35816104的博客 1459
上一篇: Android 时间戳工具类
下一篇: Android RecyclerView适配器封装
Android Hai
博客等级 码龄7年 30粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Android Hai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值