利用HorizontalScrollView实现滑动页面时的缩放效果
程序员文章站
2022-05-27 10:07:15
在前面的文章中也有关于 horizontalscrollview 的使用:android使用horizontalscrollview实现水平滚动 。
这里主要实现的是向右...
在前面的文章中也有关于 horizontalscrollview 的使用:android使用horizontalscrollview实现水平滚动 。
这里主要实现的是向右滑动时,左侧的视图有逐渐放大,也会越来越清晰;向左滑动时,左侧的视图逐渐减小,逐渐变的模糊,且不移出屏幕左边缘的效果。效果如下(可以在主页面上的右侧向右滑动都可以实现该效果):
这里需要用到自定义的 horizontalscrollview ,让其作为布局文件的根标签。horizontalscrollview 里面只能有一个子组件,所以要把左侧的视图布局文件包含在 horizontalscrollview 的子组件里面。
activity_main.xml :
<com.crazy.reduce.reducesideslip xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/reduce_lay" android:layout_width="wrap_content" android:layout_height="match_parent" android:background="@drawable/bg" android:scrollbars="none" tools:context="com.crazy.reduce.mainactivity" > <linearlayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal" > <include layout="@layout/item" /> <linearlayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_01" > <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onclick="togglemenu" android:text="点击" /> </linearlayout> </linearlayout> </com.crazy.reduce.reducesideslip>
在 item.xml 布局文件的右边有个 button 按钮,这些都在 horizontalscrollview 的子组件当中。而 item.xml 究竟是怎样的布局也都不会影响到整个的滑动。
item.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" > <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerhorizontal="true" android:orientation="vertical" > <button android:id="@+id/bt_b" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margintop="50dp" android:text="一个不同的按钮" /> <imageview android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="match_parent" android:scaletype="centercrop" android:src="@drawable/bg_03" /> </linearlayout> </relativelayout>
mainactivity.java :
package com.crazy.reduce; import android.app.activity; import android.os.bundle; import android.view.view; public class mainactivity extends activity { private reducesideslip rs; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); rs = (reducesideslip)findviewbyid(r.id.reduce_lay); } public void togglemenu(view v) { rs.reduce(); } }
自定义的 reducesideslip.java : 需要 nineoldandroids-2.4.0.jar 包,其下载地址
package com.crazy.reduce; import android.content.context; import android.util.attributeset; import android.view.motionevent; import android.view.viewgroup; import android.widget.framelayout; import android.widget.horizontalscrollview; import android.widget.linearlayout; import com.nineoldandroids.view.viewhelper; public class reducesideslip extends horizontalscrollview { private int mscreenwidth; // 屏幕宽度 private int mmnurightpadding = 300; private int mmenuwidth; // 视图宽度(左边的视图) private int mhalfmenuwidth; private boolean isopen; // 标记菜单是否打开 private boolean once; // 是否已经初始化回收菜单 private viewgroup mmenu; // 左边的视图 private viewgroup mcontent; // 右边的视图 public reducesideslip(context context, attributeset attrs) { super(context, attrs); mscreenwidth = context.getresources().getdisplaymetrics().widthpixels; } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { if (!once) { // 要与布局文件当中的一致 linearlayout temp = (linearlayout)getchildat(0); mmenu = (viewgroup)temp.getchildat(0); mcontent = (viewgroup)temp.getchildat(1); mmenuwidth = mscreenwidth - mmnurightpadding; mhalfmenuwidth = mmenuwidth/2; mmenu.getlayoutparams().width = mmenuwidth; mcontent.getlayoutparams().width = mscreenwidth; } super.onmeasure(widthmeasurespec, heightmeasurespec); } // 在视图计算完自身及子视图的宽高后,重新排版 @override protected void onlayout(boolean changed, int l, int t, int r, int b) { super.onlayout(changed, l, t, r, b); if (changed) { // 隐藏菜单 this.scrollto(mmenuwidth, 0); once = true; } } public void reduce(){ if (isopen) { closemenu(); } else { openmenu(); } } private void openmenu() { if (isopen) { return; } // 和 scrollto() 相似,但是要缓和些, // 不像 scrollto() 直接移动过去 this.smoothscrollto(0, 0); isopen = true; } private void closemenu() { if (isopen) { this.smoothscrollto(mmenuwidth, 0); isopen = false; } } @override public boolean ontouchevent(motionevent ev) { switch (ev.getaction()){ case motionevent.action_up: // 松开手 int scrollx = getscrollx(); // 水平滑动的距离 if (scrollx > mhalfmenuwidth) { this.smoothscrollto(mmenuwidth, 0); isopen = false; } else { this.smoothscrollto(0, 0); isopen = true; } return true; } return super.ontouchevent(ev); } @override protected void onscrollchanged(int l, int t, int oldl, int oldt) { super.onscrollchanged(l, t, oldl, oldt); // 左右视图切换时的渐变范围 (注意是 l 不是1(一)) float scale = l*1.0f/mmenuwidth; // 范围值 (0, 1) float leftscale = 1- 0.3f*scale; // 范围值(0.7, 1) float rightscale = 0.8f + 0.2f*scale; // 范围值 (0.8, 1) viewhelper.setscalex(mmenu, leftscale); viewhelper.setscaley(mmenu, leftscale); // 往右滑动时,左边的视图逐渐变亮 viewhelper.setalpha(mmenu, 0.6f + 0.4f * (1 - scale)); // (0.6, 1) // 往左滑动时,左边的视图不用移除屏幕左边界(可以不要) viewhelper.settranslationx(mmenu, mmenuwidth * scale * 0.7f); viewhelper.setscalex(mcontent, rightscale); viewhelper.setscaley(mcontent, rightscale); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Android属性动画特点详解
推荐阅读
-
利用HorizontalScrollView实现滑动页面时的缩放效果
-
vue刷新页面时去闪烁提升用户体验效果的实现方法
-
利用CSS3的transition属性实现滑动效果
-
微信小程序页面缩放式侧滑效果的实现代码
-
利用js对象将iframe数据缓存, 实现子页面跳转后, 返回时不丢失之前填写的数据
-
h5页面背景图很长要有滚动条滑动效果的实现
-
Android实现ViewPager多页面滑动切换及动画效果的方法
-
利用JavaScript实现在页面中显示距中秋节的天数效果
-
利用HorizontalScrollView实现滑动页面时的缩放效果
-
Android实现ViewPager多页面滑动切换及动画效果的方法