高仿知乎Android客户端欢迎引导动画

这段时间断断续续的抽时间模仿了下知乎Andorid的引导页面,觉得知乎做的更活泼一些吧。对动画,对NineOld实践也就到此告一段落了,再往深挖无非就是一些插值估值等基础的数学知识了。(在这里我要吐槽下知乎的UI设计师,我搞了好久发现2,3,4页面每个页面中的3张图片一直高度被拉伸,最后发现是图片本身就不一样高!)
我发现知乎好像是用了多个布局文件来加载每页的布局,但是我算比较懒,全塞到一个里面了。demo的Git地址(可能注释的不够明了)
https://github.com/qtstsq55/SimilarKonwLedgeWizard.git
先看下效果图:
这里写图片描述
源码:

package com.example.zhwizard;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.example.animator.AnimationFactory;
import com.example.animator.AnimatorValue;
import com.example.animator.AnimatorValueImplements;
import com.example.view.FirstView;
import com.nineoldandroids.animation.Animator;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {

    private ViewPager viewager;
    private LinearLayout layout,layout_look,layout_qq,layout_sina;
    private ArrayList<View> list_views;
    public static final  int LENGTH=6;
    private static final float SHOWFROM =0.4f ;
    private   int  temp,index,status=-1;
    private FirstView firImage;
    private View layout_bg;
    private int red=9,green=42,blue=91;
    private int redEnd=0,greenEnd=150,blueEnd=255;
    private float pageDistance;
    private ImageView im_page_press;
    private TextView tv_guide_01;
    private String guideString[]=new String[]{
            "观而思-知乎漫游指南",
            "思而动-知乎漫游指南",
            "动而问-知乎漫游指南",
            "问而答-知乎漫游指南",
            "答而得-知乎漫游指南"
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViews();
        initValue();
    }

    private void findViews() {
        viewager=(ViewPager)findViewById(R.id.viewpager);//ViewPager
        layout_bg=  findViewById(R.id.layout_bg);//最外层背景颜色View
        im_page_press= (ImageView) findViewById(R.id.im_pagepress_01);//移动的滑块
        tv_guide_01= (TextView) findViewById(R.id.tv_guide_01);//底部的引导文字
        pageDistance=im_page_press.getWidth()+dip2px(3);//滑块移动距离
        layout_look= (LinearLayout) findViewById(R.id.layout_look);
        layout_qq= (LinearLayout) findViewById(R.id.layout_qq);
        layout_sina= (LinearLayout) findViewById(R.id.layout_sina);
    }

    private void initValue() {
        LayoutInflater  inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
        list_views=new ArrayList<View>();
        //反射加载6个引导页面布局
        for(int i=0;i<LENGTH;i++){
            View view = inflater.inflate(R.layout.wizard_image_item,null);
            list_views.add(view);
        }
        viewager.setAdapter(new MyPagerAdapter(list_views));
        viewager.setOnPageChangeListener(new MyPageChangeListener());
    }


    private void animateNormal(int position,float showFrom,int showPix,int tempPosition){
        ArrayList<View> curList=new ArrayList<View>();//当前页面的View控件
        ArrayList<View> nextList=new ArrayList<View>();//下一个页面的View控件
        ArrayList<AnimatorValue> list_ani=new ArrayList<AnimatorValue>();
        View nextView=null,curView=null;
        if(tempPosition>0){
            curView = list_views.get(index);
        }else{
            curView = list_views.get(position);
        }
        if(index+1<list_views.size()) {
            nextView = list_views.get(index +1);
        }
        //加入每个页面需要动画的控件
        if(nextView!=null) {
            nextList.add(nextView.findViewById(R.id.im_0));
            nextList.add(nextView.findViewById(R.id.im_1_1));
            nextList.add(nextView.findViewById(R.id.im_1_2));
            nextList.add(nextView.findViewById(R.id.im_1_3));
            nextList.add(nextView.findViewById(R.id.im_2_1));
            nextList.add(nextView.findViewById(R.id.im_3_1));
            nextList.add(nextView.findViewById(R.id.im_3_2));
            nextList.add(nextView.findViewById(R.id.im_3_3));
        }
        if(curView!=null) {
            curList.add(curView.findViewById(R.id.im_0));
            curList.add(curView.findViewById(R.id.im_1_1));
            curList.add(curView.findViewById(R.id.im_1_2));
            curList.add(curView.findViewById(R.id.im_1_3));
            curList.add(curView.findViewById(R.id.im_2_1));
            curList.add(curView.findViewById(R.id.im_3_1));
            curList.add(curView.findViewById(R.id.im_3_2));
            curList.add(curView.findViewById(R.id.im_3_3));
        }
        //当前页面加载动画的实现
        if(tempPosition>0){
                    if(status==2){
                        for(int i=0;i<curList.size();i++){
                            AnimatorValue a=new  AnimatorValueImplements(curList.get(i),"TranslationX",(float)((i+1)*(temp*(1-showFrom))));
                            list_ani.add(a);
                        }
                    }else {
                        for (int i = 0; i < curList.size(); i++) {
                            AnimatorValue a = new AnimatorValueImplements(curList.get(i), "TranslationX", (float) ((showPix * (i + 1) * (1 - showFrom))));
                            list_ani.add(a);
                        }
                    }
        }else{
                for (int i = 0; i < curList.size(); i++) {
                    AnimatorValue a = new AnimatorValueImplements(curList.get(i), "TranslationX", (float) (-(showPix * (curList.size() - i))));
                    list_ani.add(a);
                }
        }
        //下一个页面加载动画的实现,SHOWFROM代表当前页面划过30%,加载下一个动画,具体可以自己设置
        if(showFrom<SHOWFROM){
            if(status==2){
                for (int i = 0; i < nextList.size(); i++) {
                    AnimatorValue a = new AnimatorValueImplements(nextList.get(i), "TranslationX", (float) ((showPix * (i + 1) * (1 - showFrom))));
                    list_ani.add(a);
                }
            }else{
                for(int i=0;i<nextList.size();i++){
                    AnimatorValue a=new  AnimatorValueImplements(nextList.get(i),"TranslationX",(float)(showPix*(i+1)));
                    list_ani.add(a);
                }
                temp=showPix;
            }
        }else{
            for(int i=0;i<nextList.size();i++){
                AnimatorValue a=new  AnimatorValueImplements(nextList.get(i),"TranslationX",(float)((i+1)*(temp*(1-showFrom))));
                list_ani.add(a);
            }
        }
        //背景动画,蓝色逐渐变淡
        AnimatorValue b1=new  AnimatorValueImplements(layout_bg,"backgroundColor", Color.rgb(red,green,blue),Color.rgb( (int) (red-(redEnd-red)/list_views.size()*(position+showFrom)), (int) (green+(greenEnd-green)/list_views.size()*(position+showFrom)), (int) (blue+(blueEnd-blue)/list_views.size()*(position+showFrom))));
        list_ani.add(b1);
        //滑块动画
        AnimatorValue b2=new  AnimatorValueImplements(im_page_press,"TranslationX",(pageDistance+im_page_press.getWidth())*(position+showFrom));
        list_ani.add(b2);
        //设置执行时间为0,也就是随着滑动实时动画
        AnimationFactory.getInstance().createEngine().startTogether(0,null,list_ani);
    }


   private  class MyPageChangeListener implements ViewPager.OnPageChangeListener {

        @Override
        public void onPageScrollStateChanged(int arg0) {
            status=arg0;
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            //判断左右滑方向,这里凭借这个是不准的,需要与status配合(这里加上TouchListener会更好理解,有机会再加吧)
            int tempPosition=index-position;
            //加载动画
            animateNormal(position, positionOffset, positionOffsetPixels, tempPosition);
        }

        @Override
        public void onPageSelected(int arg0) {
            index=arg0;
            if(index>0){
                tv_guide_01.setText(guideString[index-1]);
            }
            if(index==list_views.size()-1){
                layout_look.setVisibility(View.VISIBLE);
                layout_qq.setVisibility(View.VISIBLE);
                layout_sina.setVisibility(View.VISIBLE);
            }else{
                layout_look.setVisibility(View.GONE);
                layout_qq.setVisibility(View.GONE);
                layout_sina.setVisibility(View.GONE);
            }
            int height=tv_guide_01.getHeight();
            int width=tv_guide_01.getWidth();
            //底部引导文字动画,从下到上,从上到下
            AnimatorValue c1=new  AnimatorValueImplements(tv_guide_01,"TranslationY",-height/4f,-height/2f,-height*3/4f,(float)-height);
            c1.getAnimator().setDuration(100);
            c1.getAnimator().addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {

                }

                @Override
                public void onAnimationEnd(Animator animator) {
                    if (index< guideString.length) {
                        tv_guide_01.setText(guideString[index]);
                    } else {
                        tv_guide_01.setText("");
                    }
                }

                @Override
                public void onAnimationCancel(Animator animator) {

                }

                @Override
                public void onAnimationRepeat(Animator animator) {

                }
            });
            ArrayList<AnimatorValue> list=new ArrayList<AnimatorValue>();
            AnimatorValue c2=new  AnimatorValueImplements(tv_guide_01,"TranslationY",(float)height,height*3/4f,height/2f,height/4f,0);
            c2.before(c1);
            c2.getAnimator().setDuration(100);
            list.add(c1);
            list.add(c2);
            //最后一个页面的动画
            if(index==5){
                AnimatorValue d1=new  AnimatorValueImplements(layout_qq,"TranslationX",(float)width/2);
                AnimatorValue d2=new  AnimatorValueImplements(layout_sina,"TranslationX",(float)-width/2);
                d1.before(c2);
                d1.getAnimator().setDuration(1000);
                d2.getAnimator().setDuration(1000);
                list.add(d1);
                list.add(d2);

                ImageView im_0= (ImageView) list_views.get(index).findViewById(R.id.im_0);
                AnimatorValue e1=new  AnimatorValueImplements(im_0,"TranslationY",-55f);
                e1.before(d1);
                e1.getAnimator().setInterpolator(new AccelerateDecelerateInterpolator());
                e1.getAnimator().setDuration(1000);
                list.add(e1);

            }

            AnimationFactory.getInstance().createEngine().startTogetherByLink(null,list.toArray(new AnimatorValue[list.size()]));
        }
    }

    class MyPagerAdapter extends PagerAdapter {
        public List<View> mListViews;

        public MyPagerAdapter(List<View> mListViews) {
            this.mListViews=mListViews;
        }

        @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }

        @Override
        public void destroyItem(View arg0, int arg1, Object arg2) {
            if(getCount()>1){
                //第一个页面的逐步显示图标的View,具体就是如前两篇博文写的一样,利用了自己重写的插值器来计算显示位置,缩放率等
                if(arg1==0){
                    FirstView image = (FirstView)(mListViews.get(arg1).findViewById(R.id.item_image));
                    image.clearimages();
                }
                ((ViewPager) arg0).removeView(mListViews.get(arg1));
            }
        }

        @Override
        public void finishUpdate(View arg0) {
        }

        @Override
        public int getCount() {
            return mListViews.size();
        }

        @Override
        public Object instantiateItem(View arg0, int arg1) {
            layout= (LinearLayout) mListViews.get(arg1).findViewById(R.id.layout);
            firImage = (FirstView) (mListViews.get(arg1).findViewById(R.id.item_image));
            ImageView im_0= (ImageView) mListViews.get(arg1).findViewById(R.id.im_0);
            ImageView im_1_1= (ImageView) mListViews.get(arg1).findViewById(R.id.im_1_1);
            ImageView im_1_2= (ImageView) mListViews.get(arg1).findViewById(R.id.im_1_2);
            ImageView im_1_3= (ImageView) mListViews.get(arg1).findViewById(R.id.im_1_3);
            ImageView im_2_1= (ImageView) mListViews.get(arg1).findViewById(R.id.im_2_1);
            ImageView im_3_1= (ImageView) mListViews.get(arg1).findViewById(R.id.im_3_1);
            ImageView im_3_2= (ImageView) mListViews.get(arg1).findViewById(R.id.im_3_2);
            ImageView im_3_3= (ImageView) mListViews.get(arg1).findViewById(R.id.im_3_3);
            //这里推荐使用异步加载ImageLoader等,不然OOM谁也受不了
             switch (arg1){
                case 0:
                    layout.setVisibility(View.GONE);
                    firImage.startAnimation();
                    break;
                case 1:
                    layout.setVisibility(View.VISIBLE);
                    im_0.setBackgroundResource(0);
                    im_1_1.setBackgroundResource(R.drawable.ic_guide_second_01);
                    im_2_1.setBackgroundResource(R.drawable.ic_guide_second_02);
                    im_3_1.setBackgroundResource(R.drawable.ic_guide_second_03);
                    break;
                case 2:
                    layout.setVisibility(View.VISIBLE);
                    im_0.setBackgroundResource(R.drawable.ic_guide_third_01);
                    im_1_1.setBackgroundResource(R.drawable.ic_guide_third_02);
                    im_2_1.setBackgroundResource(R.drawable.ic_guide_third_03);
                    im_3_1.setBackgroundResource(R.drawable.ic_guide_third_04);
                    break;
                case 3:
                    layout.setVisibility(View.VISIBLE);
                    im_0.setBackgroundResource(R.drawable.ic_guide_fourth_01);
                    im_1_1.setBackgroundResource(R.drawable.ic_guide_fourth_02);
                    im_2_1.setBackgroundResource(R.drawable.ic_guide_fourth_03);
                    im_3_1.setBackgroundResource(R.drawable.ic_guide_fourth_04);
                    break;
                case 4:
                    layout.setVisibility(View.VISIBLE);
                    im_0.setBackgroundResource(R.drawable.ic_guide_fifth_01);
                    im_1_1.setBackgroundResource(R.drawable.ic_guide_fifth_02);
                    im_1_2.setBackgroundResource(R.drawable.ic_guide_fifth_03);
                    im_1_3.setBackgroundResource(R.drawable.ic_guide_fifth_04);
                    im_2_1.setBackgroundResource(R.drawable.ic_guide_fifth_05);
                    im_2_1.setScaleX(0.5f);
                    im_3_1.setBackgroundResource(R.drawable.ic_guide_fifth_06);
                    im_3_2.setBackgroundResource(R.drawable.ic_guide_fifth_07);
                    im_3_3.setBackgroundResource(R.drawable.ic_guide_fifth_08);
                    break;
                case 5:
                    im_0.setBackgroundResource(R.drawable.guide_logo);
                    break;
            }
            ((ViewPager)arg0).addView(mListViews.get(arg1));
            return mListViews.get(arg1);
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == (arg1);
        }

        @Override
        public void restoreState(Parcelable arg0, ClassLoader arg1) {
        }

        @Override
        public Parcelable saveState() {
            return null;
        }

        @Override
        public void startUpdate(View arg0) {
        }
    }

   private int dip2px(float dpValue){
       float scale=getResources().getDisplayMetrics().density;
       return (int) (dpValue*scale+.5f);
   }

}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值