高仿墨迹天气下拉拉伸图片

标签: android 墨迹天气 移动 动画 代码分析
5449人阅读 评论(5) 收藏 举报
分类:

简介

最近比较闲,就多学习了下,关键是不看点东西,就犯困啊。墨迹天气这个应用有不少地方需要学习的,这篇文章呢, 说一下他的“我”Tab页下拉拉伸图片展示效果,如果留意的话, 像QQ的好友动态也有差不多的效果。


代码分析

代码比较简单了,就重写了一个ScrollView类,先说说他的原理吧,我是先根据id拿到这个ImageView,然后获得他的TopMargin也就是遮掩后的偏移值,在触摸的时候,对ImageViewTopMargin进行改变产生效果,松手的时候搞个属性动画让他还原到以前的位置就Ok了。好了。 原理就是这样了。

 

先看看布局xml

<com.wjj.imagepull.PullScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="@android:color/white"
    android:id="@+id/scroll_view"
    android:scrollbars="none"
    android:layout_height="match_parent">
 
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
 
            <ImageView
                android:id="@+id/pull_img"
                android:layout_marginTop="-50dp"
                android:src="@drawable/personal_back"
                android:layout_width="match_parent"
                android:scaleType="fitXY"
                android:layout_height="250dp" />
 
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/feed_fengfeng"
                android:scaleType="fitXY"
                android:layout_centerInParent="true" />
        </RelativeLayout>
//此处省略......
    </LinearLayout>
</com.wjj.imagepull.PullScrollView>
大家看到这个设置了吧android:layout_marginTop="-50dp"这个就是要遮掩的多少了,还有这个android:id="@+id/pull_img"  这个id,别乱改了, 我就是根据这个来拿的这个ImageView的。

上代码了

public class PullScrollView extends ScrollView implements ViewTreeObserver.OnGlobalLayoutListener {
 
    View view;
    int srcTopMargion;
    float lastY;
    float offsetY;
 
    public PullScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        ViewTreeObserver observer = getViewTreeObserver();
        if (null != observer)
            observer.addOnGlobalLayoutListener(this);
    }
 
 
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        view = findViewById(R.id.pull_img);
    }
 
 
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        float y = ev.getY();
        Log.d("onTouchEvent", "action=" + action + ",y=" + y);
        MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                lastY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                //计算滑动y方向偏移值
                offsetY = y - lastY;
                //向下移动
                if (offsetY > 0) {
                    //滑动到看到所有图片展示,交给原来的逻辑处理
                    if (params.topMargin == 0) {
                        return super.onTouchEvent(ev);
                    }
                    //在不是下拉图片的时候,向下移动,交给原来的逻辑处理
                    if (getScrollY() != 0) {
                        return super.onTouchEvent(ev);
                    }
                    //可以下拉图片的情况
                    params.topMargin += offsetY / 10;
                    Log.d("onTouchEvent", "topMargin" + params.topMargin + ",lastY=" + lastY + ",y=" + y + ",offsetY" + offsetY);
                    if (params.topMargin >= 0) {
                        params.topMargin = 0;
                    }
                    view.setLayoutParams(params);
                    invalidate();
                }
                lastY = y;
                break;
            case MotionEvent.ACTION_UP:
                //不和原始margion偏移一样的时候
                if (params.topMargin != -srcTopMargion) {
                    Log.d("ACTION_UP", "moveY=" + (srcTopMargion + params.topMargin));
                    //滚动原始偏移值和现在偏移值之间的差值 eg:3~10
                    ObjectAnimator animator = ObjectAnimator.ofInt(this, "moveY", params.topMargin, -srcTopMargion);
                    animator.setDuration(200);
                    animator.setInterpolator(new LinearInterpolator());
                    animator.start();
                }
                break;
        }
        return super.onTouchEvent(ev);
    }
 
    /**
     * 设置移动中的Y值
     *
     * @param value
     */
    public void setMoveY(int value) {
        MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
        params.topMargin = value;
        Log.d("computeScroll", "topMargin=" + params.topMargin);
        view.setLayoutParams(params);
        invalidate();
    }
 
    @Override
    public void onGlobalLayout() {
        MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
        srcTopMargion = -params.topMargin;
        Log.d("srcTopMargion", "" + srcTopMargion);
        getViewTreeObserver()
                .removeGlobalOnLayoutListener(this);
    }
}
PullScrollView构造方法里面注册了OnGlobalLayoutListener来监听Tree树改变后的回调,用来获取ImageViewtopMargin作为以后还原的目标值,在onFinishInflate里面获取这个viewview = findViewById(R.id.pull_img); 

onTouchEvent就是我们的主战场了, 逻辑都在这了,先判断在ACTION_MOVE中,是不是向下滑动,如果是的话,有2种情况是需要排除的, 就是不进行topMargin改变的,是哪些呢?

第一个是topMargin都滑到0了, 就不要滑了吧。

第二个是在其他地方滑动的时候,举个例子吧,就是正常的往下滑的时候,不做处理。

除了这2种情况,下面就是topMargin的改变了,这里我加了一个offsetY / 10的除以10的阻值,就是防止滑的太快了, 这个你可以进行自定义的。

当我抬手的时候,假如说我的topMargin和以前的初始值不一样的时候,还记得吧,咱们在onGlobalLayout取得的那个值,需要做的就是启动一个动画平移滑动到上面了。

当自动滑动的时候,这里用了ObjectAnimator属性动画,其实当时用的是Scroll,为什么又不用他了呢,因为重写的computeScroll方法,如果在里面处理的话,会和自己的滚动有冲突,感兴趣的可以试试。

还有一个setMoveY方法,这个就是属性动画调用的那个方法了,根据线性插值计算后返回的值,然后在用于改变topMargin,直到恢复到刚开始的状态。

 

结束语

好了,这个项目就算完了,不过我只在我的小米手机上测试了一下,其他分辨率不知道会不会有问题,大家可以测测看。

 

Github地址

https://github.com/wu928320442/ImagePull

查看评论

Android ImageView 图片拉伸,填满控件

最近要做个软件的启动界面,要展示客户公司的企业形象,用一张图片放在ImageView中实现,但是发现图片并没有填满,而是在上下边上留出了一点空白: 这样不行,那怎样才能让图片铺满控件呢,网上找的的...
  • zhouyingge1104
  • zhouyingge1104
  • 2016-01-18 10:31:59
  • 13937

自定义scrollView实现顶部图片下拉放大

自定义scrollView实现顶部图片下拉放大
  • l448288137
  • l448288137
  • 2016-03-28 10:59:51
  • 8131

android 中scrollView顶部图片下拉放大

项目中需要在scrollView下拉的时候顶部的图片放大,网络上没有找到合适的,自己写了也 不多说了,直接上代码 这是布局 ...
  • l448288137
  • l448288137
  • 2015-08-20 13:01:16
  • 4180

经验之谈—实现图片下拉放大的效果

这里我们主要是用一下,如何能保持原来的图片的宽高比来轻松的实现放大的效果,主要的是UIViewContentModeScaleAspectFill这个起的效果: 我们用tableView来展示这个效果...
  • yi_zz32
  • yi_zz32
  • 2015-12-22 19:15:12
  • 10638

Android 高仿墨迹天气“我”页面

1,实现效果 实现的效果分三个部分来说明,首先是下拉到最大高度,个人信息界面会产生一个回弹的效果,然后是滚动到顶部,个人信息界面收缩,并且产生登录按钮会重新出现,黄色的消息按钮会平移到最右边。最后是...
  • jdsjlzx
  • jdsjlzx
  • 2016-01-31 22:25:15
  • 2109

Android开发之QQ空间效果(QQ空间下拉图片放大,松手后回弹)

Android开发之QQ空间效果(QQ空间下拉图片放大,松手后回弹) 腾讯QQ空间的下拉图片放大,松手后回弹的效果带来的视觉差异效果让许多移动开发者心动不已,经本人一段时间的研究,终于实现了该视差...
  • FlyingSnow2211
  • FlyingSnow2211
  • 2015-09-16 12:50:22
  • 2118

<em>android下拉</em>背景图伸缩

仿qq空间的<em>下拉图片</em>伸缩,图片从xy轴方向<em>拉伸</em>... 2015-06-15 上传大小:2.51MB <em>android</em> 仿qq空间的<em>下拉图片</em>伸缩,图片从xy轴方向<em>拉伸</em> 综合评分:4(16位用户评分) ...
  • 2018年03月22日 00:00

高仿墨迹天气下拉拉伸图片

简介 最近比较闲,就多学习了下,关键是不看点东西,就犯困啊。墨迹天气这个应用有不少地方需要学习的,这篇文章呢, 说一下他的“我”Tab页下拉拉伸图片展示效果,如果留意的话, 像QQ的好友动态也有差不...
  • wu928320442
  • wu928320442
  • 2015-03-11 14:18:04
  • 5449

高仿android-QQ空间下拉背景图拉伸回弹效果

  • 2014年11月06日 14:46
  • 2.52MB
  • 下载

高仿android-QQ空间下拉背景图拉伸回弹效果,修复已知BUG

  • 2015年10月28日 12:57
  • 2.7MB
  • 下载
    个人资料
    专栏达人
    等级:
    访问量: 21万+
    积分: 2362
    排名: 1万+
    博客专栏