首页 > 系统 > Android > 正文

利用HorizontalScrollView实现滑动页面时的缩放效果

2019-10-21 21:35:27
字体:
来源:转载
供稿:网友

在前面的文章中也有关于 HorizontalScrollView 的使用:Android使用HorizontalScrollView实现水平滚动 。

这里主要实现的是向右滑动时,左侧的视图有逐渐放大,也会越来越清晰;向左滑动时,左侧的视图逐渐减小,逐渐变的模糊,且不移出屏幕左边缘的效果。效果如下(可以在主页面上的右侧向右滑动都可以实现该效果):

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); }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表