仿小米视频下滑视频动画效果

昨日无意间看到小米视频,感觉效果不错,不过由于我并没有接触过视频类的项目,所以在这里只对动画效果做了模仿,并不能达到小米视频的真正效果。


首先我们先来看一下小米视频的效果:


在向下滑动一定距离后,videoview(况且称之为viewdeoview吧)会随着下滑滑动到屏幕的下方,并且在滑动过程中位置不在变化,那么首先先缕清思路,首先我们要自定义一个可以监听滑动的scrollview,这个不是很难,直接上代码:

  @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if(scrollChanged!=null){
            scrollChanged.changed(this,l,t,oldl,oldt);
        }

    }

  

    public interface ScrollChanged{
        void changed(MyScrollView who,int l, int t, int oldl, int oldt);
    }
    public ScrollChanged scrollChanged;

    public  void setScrollChanged(ScrollChanged scrollChanged){
        this.scrollChanged=scrollChanged;
    }

}
这样的话我们就定义好了布局,然后我们在想如何让一个布局一直保持在屏幕下方而位置不变呢?这时候我想到了RelativeLayout的属性,于是脑洞大开,开始写布局文件先:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/test_rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.mvptestdemo.MyScrollView
        android:id="@+id/test_sc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:id="@+id/test_ll"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <VideoView
                android:id="@+id/test_vv"
                android:layout_width="match_parent"
                android:layout_height="250dp"
                android:background="@android:color/black" />

            <LinearLayout
                android:id="@+id/test_ll2"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/transparent"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="101dp"
                    android:background="@android:color/holo_red_dark"
                    android:gravity="center"
                    android:text="111111111111111111111" />
<span style="white-space:pre">		</span>....................................................
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="101dp"
                    android:background="@android:color/holo_red_dark"
                    android:gravity="center"
                    android:text="111111111111111111111" />

               
            </LinearLayout>


        </LinearLayout>

    </com.example.mvptestdemo.MyScrollView>
</RelativeLayout>

我们布局最外层是一个Relativetlayout,然后是我们自定义的Scrollview了。布局很简单,最后我们来看activity部分的代码:

首先我们应该获取VideoView布局的宽高,于是我们在oncreate中开始获取:

 videoView.post(new Runnable() {
            @Override
            public void run() {
                height = videoView.getHeight();
                width = videoView.getWidth();
            }
        });

然后我们开始对Scrollview的滚动进行监听,由于监听是动态的,所以我们应该保证在滑动过程中,VideoView的动画只执行一次,所以我们定义一个全局的boolean来确定他只执行一次:

<pre name="code" class="java"> myScrollView.setScrollChanged(new MyScrollView.ScrollChanged() {
            @Override
            public void changed(MyScrollView who, int l, int t, int oldl, int oldt) {
                if (t >= height) {
                    if (!isAnim) {
                        startAnim();
                        isAnim = !isAnim;
                    }

                } else {
                    if (isAnim) {
                        startAnim2();
                        isAnim = !isAnim;
                    }

                }
            }
        });

 这里的t就是我们滑动的距离,当我们滑动的距离大于VideoView的高度时我们执行动画,并且对boolean进行变换。 

接下来我们来看startAnim()的部分代码,首先我们要在将VideoView想办法改到外层的RelativeLayout中,于是我们可以通过动态的代码进行设置:

   new Handler().post(new Runnable() {
            @Override
            public void run() {
                float i = new Float(height) / new Float(width);
                newHeight = (int) (new Float(newWidth) * i);
                LinearLayout layout = (LinearLayout) myScrollView.getChildAt(0);
                layout.removeView(videoView);
                RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(newWidth, newHeight);
                lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
                lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                lp.setMargins(0, 0, 30, 30);
                videoView.setLayoutParams(lp);
                relativeLayout.addView(videoView);
            }
        });
这里先说handler,起初我没有在外层加handler.post,但是在滑动太快的时候会出现nullpointer的异常,在各种度娘谷歌娘一通后才知道是由于布局没有完成而造成的,于是加入post来执行。

首先我们根据VideoView的宽高比来进行对缩小后的视频进行宽高的计算,这里要注意float和int的转换问题。然后我们从scrollview中移除videoview,然后给videoview重新设置LayoutParams,因为RelativeLayout有addRule的方法,所以下面的代码也非常简单,在写完这几行代码后我们再向下滑动的时候,VideoView已经乖乖的站在了屏幕的下方,这时候我们就需要一个简单的位移动画来使这个过程不那么生涩:

  ObjectAnimator animator2 = ObjectAnimator.ofFloat(videoView, View.TRANSLATION_X,-(widthPixels-newWidth),0);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(videoView, View.TRANSLATION_Y, -(heightPixels-newHeight) ,0);
        AnimatorSet animatorSet=new AnimatorSet();
        animatorSet.playTogether( animator2, animator3);
        animatorSet.setDuration(1000);
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                new Handler().post(new Runnable() {
                    @Override
                    public void run() {
                        videoView.start();
                    }
                });
            }
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }
        });
        animatorSet.start();
这是简单的属性动画,并没有什么比较难以理解的部分,在执行完这个动画之后我们让videoview开始播放视频........

这样我们的下滑过程中的动画已经模仿的差不多了,我们来看一下效果吧~





这是全部的动画效果,最后我们只需要在上滑到小于Viderview的高度时,执行另外一个回归原来位置的动画即可,由于小米视频在回来的时候并没有对其执行动画处理,可能也是为了动画执行时的边框问题,于是我在这里也只是写了改变布局的代码:

  new Handler().post(new Runnable() {
            @Override
            public void run() {
                relativeLayout.removeView(videoView);
                LinearLayout layout = (LinearLayout) myScrollView.getChildAt(0);
                LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(width, height);
                videoView.setLayoutParams(lp);
                layout.removeAllViews();
                layout.addView(videoView);
                layout.addView(ll2);
                videoView.start();
大功告成了,这只是一个很简单的例子,通过改变布局和动画相结合我们可以做出很多比较有意思的效果,希望大家多多尝试~如果有更好的效果请分享给我~~~~

最后上一张我老婆的美图:



祝大家上班愉快~


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值