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

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

(0)

相关推荐

  • Android 自定义 HorizontalScrollView 打造多图片OOM 的横向滑动效果(实例代码)

    自从Gallery被谷歌废弃以后,Google推荐使用ViewPager和HorizontalScrollView来实现Gallery的效果.的确HorizontalScrollView可以实现Gallery的效果,但是HorizontalScrollView存在一个很大的问题,如果你仅是用来展示少量的图片,应该是没问题的,但是如果我希望HorizontalScrollView可以想ViewPager一样,既可以绑定数据集(动态改变图片),还能做到,不管多少图片都不会OOM(ViewPager内

  • Android HorizontalScrollView左右滑动效果

    本文实例为大家分享了Android HorizontalScrollView左右滑动的具体代码,供大家参考,具体内容如下 效果图 一.什么是HorizontalScrollView HorizontalScrollView实际上是一个FrameLayout ,这意味着你只能在它下面放置一个子控件 ,这个子控件可以包含很多数据内容.有可能这个子控件本身就是一个布局控件,可以包含非常多的其他用来展示数据的控件.这个布局控件一般使用的是一个水平布局的LinearLayout.TextView也是一个可

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

    在前面的文章中也有关于 HorizontalScrollView 的使用:Android使用HorizontalScrollView实现水平滚动 . 这里主要实现的是向右滑动时,左侧的视图有逐渐放大,也会越来越清晰:向左滑动时,左侧的视图逐渐减小,逐渐变的模糊,且不移出屏幕左边缘的效果.效果如下(可以在主页面上的右侧向右滑动都可以实现该效果): 这里需要用到自定义的 HorizontalScrollView ,让其作为布局文件的根标签.HorizontalScrollView 里面只能有一个子组

  • Android仿今日头条滑动页面导航效果

    最近项目中用到了滑动页面,也就是和目前市场上很火的"今日头条"页面滑动类似,在网上找了一下,大部分都是用ViewPager来实现的,刚开始我用的是ViewPager+ViewGroup,上面的标题按钮用的是HorizontalScrollView,写完之后感觉效果比较生硬,果断换掉,发现了一个效果比较好的第三方,也就是今天的主题:PagerSlidingTabStrip.好了,下面来具体介绍一下PagerSlidingTabStrip,进行一下源码解析. 一.看一下demo的样子吧 二

  • Android利用ViewPager实现滑动广告板实例源码

    •android-support-v4.jar,这是谷歌官方给我们提供的一个兼容低版本Android设备的软件包,里面包囊了只有在Android3.0以上可以使用的api.而ViewPager就是其中之一,利用它我们可以做很多事情,从最简单的导航,到页面切换菜单等等. •ViewPager的功能就是可以使视图滑动,就像Lanucher左右滑动那样. •本Demo向大家演示ViewPager的使用,并在用户未滑动View时,每隔5s钟自动切换到下一个View(循环切换),而当用户有Touch到Vi

  • Android利用HorizontalScrollView仿ViewPager设计简单相册

    最近学习了一个视频公开课,讲到了利用HorizontalScrollView仿ViewPager设计的一个简单相册,其实主要用了ViewPager缓存的思想.此篇文章参考:Android自定义HorizontalScrollView打造超强Gallery效果(这篇文章与公开课的讲的大致一样) 这里简单说一下ViewPager的缓存机制 1.进入ViewPager时,加载当前页和后一页: 2.当滑动ViewPager至下一页时,加载后一页,此时第一页是不会销毁的,同时加载当前页的下一页. 其实就是

  • Flutter 利用CustomScrollView实现滑动效果

    我们在之前的文章中//www.jb51.net/article/213709.htm 使用了 ListView 将几个 GridView 组合在一起实现滑动效果,今天利用CustomScrollView改造一下代码 CustomScrollView 简介 CustomScrollView的常用属性如下: slivers:最重要的属性,由多个SliverXX组件组成的数组,包括如 SliverList(对应 ListView),SliverGrid(对应 GridView)等,如果普通组件无法直接

  • Android开发中如何解决Fragment +Viewpager滑动页面重复加载的问题

    前言 之前在做一个Viewpager上面加载多个Fragment时总会实例化已经创建好的Fragmnet对象类似 viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) { switch(position){ case 0: fragments=new Fragmnet01(); break; case

  • vue中使用vue-router切换页面时滚动条自动滚动到顶部的方法

    有时候我们需要页面滚动条滚动到某一固定的位置,一般使用Window scrollTo() 方法. 语法就是:scrollTo(xpos,ypos) xpos:必需.要在窗口文档显示区左上角显示的文档的 x 坐标. ypos:必需.要在窗口文档显示区左上角显示的文档的 y 坐标. 例如滚动内容的坐标位置100,500: window.scrollTo(100,500); 好了,这个scrollTop这儿只是简单介绍一下,下面我们介绍下veu-router中的滚动行为. 使用前端路由,当切换到新路由

  • vue返回上一页面时回到原先滚动的位置的方法

    项目结束,测试时发现在首页商品列表中,向上滑动几页后点击进入详情,从详情页面返回商品列表时,页面回到了最顶部,测试不通过说是用户体验不好,要求从哪里点击进去返回该页面时回到原先的滚动页面. 思路:因为vue是单页面应用,进入其他页面时会销毁该页面,用keep-alive不让其刷新,具体实现为: (1).在App.vue中加入: <template> <div id="app"> <!--<router-view/>--> <!--页

  • 微信小程序中的滑动页面隐藏和显示组件功能的实现代码

    用csdnAPP的用户都知道,在发布blink动态时,那个红色按钮会随着你滚动页面消失或者出现.往上滑动时,按钮消失.往下滑动时,按钮出现. 今天我们就模仿一下这个功能,只不过我们换中样式,让它逐渐滑出页面,或逐渐从页面之外滑到固定位置. 效果图: 滑动前: 滑动后: 此功能是往上滑动消失,往下滑动出现. 实现步骤: 编写页面代码与样式 编写逻辑代码 wxml: <view class="mask-con {{!hidden ? 'mask-con-show' : '' } } sendD

  • vue基于better-scroll实现左右联动滑动页面

    本文实例为大家分享了vue基于better-scroll实现左右联动滑动页面,供大家参考,具体内容如下 界面如下: vue模板 <template> <div class="goods"> <div class="menu-wrapper"> <ul> <li class="menu-item" v-for="(good, index) in goods" :key=&qu

随机推荐