Android仿即刻首页垂直滚动图,炫酷到底!_Android

项目地址:https://github.com/JeasonWong/JikeGallery

话不多说,先上效果。

这个效果是在即刻app上看到,觉得很不错,遂仿之。

先说下我的实现思路(以上方的图片滚动为例,下方的文字实现效果类似):

自定义ViewGroup
装载两个ImageView和一个阴影View
通过一定规律交替控制两个ImageView和它们的marginTop,在onLayout()中实现
marginTop的具体值由属性动画控制,不断调用requestLayout()

接下来依次说明

一、自定义ViewGroup

 //滑动状态
 protected static final int STATUS_SMOOTHING = 0;
 //停止状态
 protected static final int STATUS_STOP = 1;

 //ViewGroup宽高
 protected int mWidth, mHeight;
 //变化的marginTop值
 protected int mSmoothMarginTop;
 //默认状态
 protected int mStatus = STATUS_STOP;
 //滚动时间间隔
 protected int mDuration = 500;
 //重复次数
 protected int mRepeatTimes = 0;

 ...

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  mWidth = w;
  mHeight = h;
  mSmoothMarginTop = -h;
  initView();
 }

 protected abstract void initView();

 ...

 /**
  * 是否是奇数圈
  *
  * @return 结果
  */
 protected boolean isOddCircle() {
  return mRepeatTimes % 2 == 1;
 }

先了解下成员变量,其中最重要的一个就是mSmoothMarginTop,相信很多人都知道一个View的marginTop可以设为负数,这个负数可以给我们带来太多的方便。

上图的图0就是我们展现在屏幕上的ImageView,图1则是屏幕外marginTop为-height的ImageView,这个一定要明白,接下来才好继续实现。

二、装载两个ImageView和一个阴影View

 private List<String> mImgList = new ArrayList<>();
 private ImageView[] mImgs = new ImageView[2];
 private View mShadowView;

 ...

 @Override
 protected void initView() {

  //如果没有内容,则不进行初始化操作
  if (mImgList.size() == 0) {
   return;
  }

  removeAllViews();

  MarginLayoutParams params = new MarginLayoutParams(mWidth, mHeight);

  //两个ImageView加载前两张图
  for (int i = 0; i < mImgs.length; i++) {
   mImgs[i] = new ImageView(getContext());
   addViewInLayout(mImgs[i], -1, params, true);
   Glide.with(getContext()).load(getImgPath(i)).centerCrop().into(mImgs[i]);
  }

  //创建阴影View
  mShadowView = new View(getContext());
  mShadowView.setBackgroundColor(Color.parseColor("#60000000"));
  mShadowView.setAlpha(0);
  addViewInLayout(mShadowView, -1, params, true);
 }

 ...

 /**
  * 获取图片地址
  *
  * @param position 位置
  * @return 图片地址
  */
 private String getImgPath(int position) {
  position = position % mImgList.size();
  return mImgList.get(position);
 } 

关键点说明:

MarginLayoutParams 为了之后方便取出margin值
addViewInLayout() 为了对requestLayout的绝对控制
getImgPath() 为了实现循环滚动
这样一来,我们需要的View都已经创建好了。

三、通过一定规律交替控制两个ImageView和它们的marginTop,在onLayout()中实现

 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {

  int cCount = getChildCount();
  MarginLayoutParams cParams;

  for (int i = 0; i < cCount; i++) {
   View childView = getChildAt(i);
   cParams = (MarginLayoutParams) childView.getLayoutParams();

   int cl = 0, ct = 0, cr, cb;

   if (isOddCircle()) {
    if (i == 1) {
     cl = cParams.leftMargin;
     ct = mSmoothMarginTop + mHeight;
    } else if (i == 0) {
     cl = cParams.leftMargin;
     ct = mSmoothMarginTop;
    }
   } else {
    if (i == 0) {
     cl = cParams.leftMargin;
     ct = mSmoothMarginTop + mHeight;
    } else if (i == 1) {
     cl = cParams.leftMargin;
     ct = mSmoothMarginTop;
    }
   }
   //控制shadowView
   if (i == 2) {
    cl = cParams.leftMargin;
    ct = mSmoothMarginTop + mHeight;
   }

   cr = cl + mWidth;
   cb = ct + mHeight;
   childView.layout(cl, ct, cr, cb);
  }

 }

以上实现的就是不断的替换图1和图2谁上谁下,阴影和下方的图保持同步。

四、marginTop的具体值由属性动画控制,不断调用requestLayout()

先看基类ViewGroup

 /**
  * 开启滑动
  *
  */
 public void startSmooth() {

  if (mStatus != STATUS_STOP) {
   return;
  }

  ValueAnimator animator = ValueAnimator.ofFloat(-mHeight, 0);
  animator.setDuration(mDuration);
  animator.setInterpolator(new AccelerateDecelerateInterpolator());
  animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator animation) {

    float marginTop = (float) animation.getAnimatedValue();
    mSmoothMarginTop = (int) marginTop;

    if (marginTop == 0) {

     postDelayed(new Runnable() {
      @Override
      public void run() {

       mRepeatTimes++;

       mSmoothMarginTop = -mHeight;

       doAnimFinish();

       mStatus = STATUS_STOP;

      }
     }, 50);

    } else {
     doAnim();
    }
   }
  });
  animator.start();
  mStatus = STATUS_SMOOTHING;
 }

 //动画结束
 protected abstract void doAnimFinish();

 //动画进行时
 protected abstract void doAnim();

关键点说明:

属性动画控制着mSmoothMarginTop在[-mHeight, 0]中变化
每完成一圈,mRepeatTimes自增1

再来看看Gallery实现类

 @Override
 protected void doAnimFinish() {
  if (isOddCircle()) {
   Glide.with(getContext()).load(getImgPath(mRepeatTimes + 1)).centerCrop().into(mImgs[0]);
  } else {
   Glide.with(getContext()).load(getImgPath(mRepeatTimes + 1)).centerCrop().into(mImgs[1]);
  }
  mShadowView.setAlpha(0);
 }

 @Override
 protected void doAnim() {
  mShadowView.setAlpha(((1 - (-mSmoothMarginTop) / (float) mHeight)));
  requestLayout();
 }

关键点说明:

通过mSmoothMarginTop与mHeight的比值控制阴影View的透明度
每次动画完成时,下方的图(此时下方的图已经超出屏幕了,而上方图显示在屏幕内)需要加载第三张图,使用getImgPath()取出
pic1

以上就是图片的滚动实现,文字的滚动90%是一样的,有点区别的就是需要文字需要控制下垂直居中,我就不赘述了。

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索Android垂直滚动图
Android垂直滚动
即刻搜索首页、炫酷的html5首页、炫酷首页、炫酷网站首页、炫酷的网站首页,以便于您获取更多的相关知识。

时间: 2024-08-25 22:59:53

Android仿即刻首页垂直滚动图,炫酷到底!_Android的相关文章

Android仿即刻首页垂直滚动图,炫酷到底!

项目地址:https://github.com/JeasonWong/JikeGallery 话不多说,先上效果. 这个效果是在即刻app上看到,觉得很不错,遂仿之. 先说下我的实现思路(以上方的图片滚动为例,下方的文字实现效果类似): 自定义ViewGroup 装载两个ImageView和一个阴影View 通过一定规律交替控制两个ImageView和它们的marginTop,在onLayout()中实现 marginTop的具体值由属性动画控制,不断调用requestLayout() 接下来依

Android仿即刻首页垂直滚动图

  Android仿即刻首页垂直滚动图 这个效果是在即刻app上看到,觉得很不错,遂仿之. 先说下我的实现思路(以上方的图片滚动为例,下方的文字实现效果类似): 自定义ViewGroup 装载两个ImageView和一个阴影View 通过一定规律交替控制两个ImageView和它们的marginTop,在onLayout()中实现 marginTop的具体值由属性动画控制,不断调用requestLayout() 接下来依次说明 一.自定义ViewGroup ? 1 2 3 4 5 6 7 8 9

Android中TextView实现垂直滚动和上下滚动效果

布局里面就是两个自定义的TextView,上面的左右滑动的是AutoHorizontalScrollTextView; 下面上下滚动的是AutoVerticalScrollTextView; 上面左右滑动的非常好实现,直接把AutoHorizontalScrollTextView复制到项目中,复制全类名到布局文件中,和系统TextView一样,只需设置文本其他什么都不用设置: 下面垂直滚动的AutoVerticalScrollTextView相比AutoHorizontalScrollTextV

Android 开发之BottomBar+ViewPager+Fragment实现炫酷的底部导航效果_Android

BottomBar BottomBar是Github上的一个开源框架,因为从1.3.3开始不支持fragments了,要自己配置,弄了很久,不管是app的fragment还是V4 的程序总是总是闪退.于是就用这种方式实现了,效果还不错.github有详细说明,多余的就不说了. 这个roughike是这个项目的所有者(大神致敬). 我用的是Android studio开发,fragment全部导的V4的包(以为最开始就支持的是v4的,后面也支持了app.fragment). 首先是dependen

Android 开发之BottomBar+ViewPager+Fragment实现炫酷的底部导航效果

BottomBar BottomBar是Github上的一个开源框架,因为从1.3.3开始不支持fragments了,要自己配置,弄了很久,不管是app的fragment还是V4 的程序总是总是闪退.于是就用这种方式实现了,效果还不错.github有详细说明,多余的就不说了. 这个roughike是这个项目的所有者(大神致敬). 我用的是Android studio开发,fragment全部导的V4的包(以为最开始就支持的是v4的,后面也支持了app.fragment). 首先是dependen

Android仿QQ好友列表实现列表收缩与展开_Android

ExpandableListView是一个垂直滚动显示两级列表项的视图,与ListView不同的是,它可以有两层:每一层都能够被独立的展开并显示其子项. 好友QQ列表,可以展开,可以收起,在android中,以往用的比较多的是listview,虽然可以实现列表的展示,但在某些情况下,我们还是希望用到可以分组并实现收缩的列表,那就要用到android的ExpandableListView,今天研究了一下这个的用法,也参考了很多资料动手写了一个小demo,实现了基本的功能,下面直接上效果图以及源代码

Android仿美团下拉菜单(商品选购)实例代码_Android

美团电商应用平台大家使用非常频繁,下面小编通过本文给大家介绍电商应用平台中常用的选择类别下拉列表的实现.先给大家展示下效果图: 一.下拉列表的实现 其实实现方法有很多,这时实现的也没有什么技术含量,只是总结下自己在项目中的做法,也提供一个思路. 首先是列表的数据,一般数据都是从后台读过来,这里因为没有后台,所以写死在客户端: private void initMenuData() { menuData = new ArrayList<map<string, string=""

Android中通过AsyncTask类来制作炫酷进度条的实例教程_Android

AsyncTask (API level 3,所以几乎所有目前在市面上流通的 Android 版本皆可使用) 是除 Thread 外的另一种选择,Android 团队鼓励主执行绪(UI thread) 专注于操作 & 画面的流畅呈现, 其余工作 (如网络资料传输.档案/磁碟/资料存取) 最好都在背景执行: Thread 通常要搭配 Handler 使用,而 AsyncTask 用意在简化背景执行 thread 程序码的撰写. 如果您预期要执行的工作能在几秒内完成,就可以选择使用 AsyncTas

Android 仿今日头条简单的刷新效果实例代码_Android

点击按钮,先自动进行下拉刷新,也可以手动刷新,刷新完后,最后就多一行数据.有四个选项卡. 前两天导师要求做一个给本科学生预定机房座位的app,出发点来自这里.做着做着遇到很多问题,都解决了.这个效果感觉还不错,整理一下. MainActivity package com.example.fragmentmytest; import android.content.DialogInterface; import android.graphics.Color; import android.os.B