Android视觉动画效果---未完待续

来源:互联网 发布:比价系统源码 编辑:程序博客网 时间:2024/05/29 17:24



最近公司项目要求这个效果,搜来搜去,我都没有找到类似的效果,IOS倒是有类似的Demo,于是乎,自己写了一个体验很差的这种效果,希望大家能够及时指正,并且能开阔新领域。共同进步,如果你的项目有用到类似效果,也请留言,让大家互相学习。

1:原理就是滑动的过程当中不断的计算条目的高度。并且这个高度是根据滑动的距离算出来的

2:透明度不断变化,你会看到第一个透明度是比其他的透明度亮了许多的,其实透明度也是一个根据滑动距离逐渐变化的过程,

在做这个的时候,遇到了几个问题,希望告诉大家,如果大家有什么意见也可以评论。

1  :是自定义ListView的时候,如果你首先设置了滑动监听,那么他会首先执行OnScroll方法,其次执行Onlayout方法,并且一般一次的Onlayot是不能把所有的子布局给初始化好的,因为第一次调用getChildCount方法,得到不是一个正确的子数目的个数。一般第二次或第三次调用Onlayout才是正确的getchildCount数目,如果你想跟IOS一样通过一次遍历得到所有初始化的条目的Y坐标,进而实现这个效果,目前不太可能。因为Android 中ListView遍历的getChildCount方法,只是获得到了显示在屏幕中的那几个条目数,并不是所有的。

2:通过不断的通过


LinearLayout layout = ( LinearLayout) view.getChildAt(i); AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) itemHeight); layout.setLayoutParams(layoutParams);
这种方式不断的去设置条目的大小,是会跟onscroll()方法造成一个死循环的,因为每次设置条目的尺寸,都会先执行OnScroll()然后接着就执行onlayout();事想假如你不断的滚动不断的设置,设置的同时又调用了Onscroll这不就是一个死循环么?
3:计算不准确,因为我们这个条目的尺寸的时候,强制要求的是整形  ,这样经过四舍五入,有时候也会出现精确度的误差。
4:再滑动到最后的时候,还要继续往上能够滑动,直到最后一个条目到了屏幕的最上面,目前我只是加了几个footer让条目继续往上能够滑动了,这到后面肯定是有问题的。     IOS是通过一个ContentSize即设置了listView的高度大于实际条目的高度的多少,让其继续能够往上滚动的,我通过设置listView的高并没有实现类似的效果,即,依然滑到最底部之后,不能往上继续滚动。希望大家能够提出自己的建议。
             
  原理讲清楚,下面附上代码,
package sample.discrollview.flavienlaurent.com.mylistview;import android.animation.ValueAnimator;import android.content.Context;import android.content.res.TypedArray;import android.database.sqlite.SQLiteCantOpenDatabaseException;import android.graphics.Canvas;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.util.Log;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView;import android.widget.LinearLayout;import android.widget.ListAdapter;import android.widget.ListView;import android.widget.RelativeLayout;import android.widget.Toast;import com.nineoldandroids.view.ViewHelper;public class LvListView extends ListView implements AbsListView.OnScrollListener{    /**     * 显示在屏幕上多少个item     */    private int showItemCount;    /**     * 每个item的高度     */    private int itemHeight;    /**     * 记录第一个显示的item     */    /**     * 从第几行执行动画     */    private int scaleFlagIndex = 1;    /**     * 是否到了最后一行     */    private boolean lastFlag = false;    /**     * 步骤     */    private int step = 0;    /**     * 步骤个数     */    private int stepCount;    private Context context;    private boolean isScroll=false;    private float lastY;    private  float maxAlpha=0.45f;    //设置顶部条目的标准    private int TopItem=400;    //设置下面的item布局    private int BottomItem=200;    //记录是否是第一次进去onlayout的遍历for    private Boolean  isFirs=true;    private int a;    private Boolean isRealyScroll=false;    //初始Padding    private float FirstPadding=85f;    private float TwoPadding=285f;    private  float RecordItemOHeight;    private int   mFirstVisibleItem;    private Boolean addFooter=true;    private View viewFooter;    public LvListView(Context context) {        this(context, null);        this.context=context;    }    public LvListView(Context context, AttributeSet attrs) {        this(context, attrs, 0);        this.context=context;    }    /**     * 构造方法中拿到自定义属性showViewCount,并设置滚动监听     *     * @param context     * @param attrs     * @param defStyleAttr     */    public LvListView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.context=context;        //获取showViewCount        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LvListView);        showItemCount = typedArray.getInt(R.styleable.LvListView_showViewCount, 0);        typedArray.recycle();        //设置一个滚动监听        setOnScrollListener(this);    } /*   @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,                MeasureSpec.AT_MOST);        super.onMeasure(widthMeasureSpec, expandSpec);    }*/  /*  @Override    public boolean onTouchEvent(MotionEvent ev)    {        int action = ev.getAction();        if (action == MotionEvent.ACTION_UP)        {            checkForReset();            return true;        }        return super.onTouchEvent(ev);    }*/    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        isScroll=true;        if(isFirs) {            //写个方法解决,布局黑的问题            for (int i = 0; i < getChildCount(); i++) {                if (i == 0) {                    getChildAt(i).findViewById(R.id.textview).setAlpha(0);                    getChildAt(i).findViewById(R.id.textview_xiantop).setAlpha(1);                    getChildAt(i).findViewById(R.id.ivtwo).setAlpha(getAlphaNumber(TopItem, BottomItem, TopItem));                } else {                    getChildAt(i).findViewById(R.id.textview).setAlpha(1);                    getChildAt(i).findViewById(R.id.textview_xiantop).setAlpha(0);                    getChildAt(i).findViewById(R.id.ivtwo).setAlpha(getAlphaNumber(TopItem, BottomItem, BottomItem));                }            }        }       if(!isRealyScroll) {            initLayot();        }        stepCount = getAdapter().getCount() - 2;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);    }    /**     * 检查当前getScrollY,显示完成Item,或者收缩此Item     */    private void checkForReset()    {        int top = getChildAt(0).getTop();        if (top == 0)            return;        Log.d("==",top+"");         if (Math.abs(top) > 130)        {            this.smoothScrollBy((int)RecordItemOHeight-Math.abs(top), 100);        } else if(Math.abs(top)>95&&Math.abs(top)<130)        {                return;        }else        {            this.smoothScrollBy(-Math.abs(top),100);        }    }    @Override    public void onScrollStateChanged(AbsListView view, int scrollState) {        if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {            checkForReset();        }    }    @Override    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {        if(totalItemCount == 0) return;        mFirstVisibleItem = firstVisibleItem;        if(isScroll&&getChildAt(0).getY()!=lastY)        {            Log.d("onScroll","执行了onSrcoll");            isFirs=false;            isRealyScroll=true;            for (int i = 0; i < getChildCount(); i++) {                float item0Height = getChildAt(0).getY();                if (i == 0) {                    float itemHeight = 400.0f + item0Height / getChildAt(0).getHeight() * 200.0f;                    this.RecordItemOHeight=itemHeight;                    LinearLayout layout = (LinearLayout) getChildAt(i);                    AbsListView.LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int)itemHeight);                    layout.setLayoutParams(layoutParams);                    getChildAt(i).findViewById(R.id.ivtwo).setAlpha(getAlphaNumber(TopItem, BottomItem, itemHeight));                    getChildAt(i).findViewById(R.id.textview).setAlpha(1 - gettextAlphaNumber(TopItem, BottomItem, itemHeight));                    getChildAt(i).findViewById(R.id.textview_xiantop).setAlpha(gettextAlphaNumber(TopItem, BottomItem, itemHeight));        //          getChildAt(i).findViewById(R.id.money).setPadding(0, 0, 0, (int) getPadding(TopItem, BottomItem, itemHeight));                   if (getChildAt(0).getY()>lastY) {//                 getChildAt(i).findViewById(R.id.money).setPadding(0, 0, 0, (int) getPadding(TopItem, BottomItem, itemHeight));                    getChildAt(i).findViewById(R.id.money).setPadding(0, 0, 0, (int) FirstPadding);                    getChildAt(i).findViewById(R.id.textview).setPadding(0, 0, 0, (int) FirstPadding);                    getChildAt(i).findViewById(R.id.textview_xiantop).setPadding(0, 0, 0, (int) FirstPadding);                    Log.d("lastY","getChildAt(0).getY()"+getChildAt(0).getY()+" >lastY"+lastY);                }                    lastY=item0Height;                }                else  if(i == 1)              {                  float itemHeight = 200.0f - item0Height / getChildAt(0).getHeight() * 200.0f;                  getChildAt(i).findViewById(R.id.ivtwo).setAlpha(getAlphaNumber(TopItem, BottomItem, itemHeight));                   LinearLayout layout = ( LinearLayout) view.getChildAt(i);                    AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) itemHeight);                    layout.setLayoutParams(layoutParams);                   getChildAt(i).findViewById(R.id.textview).setAlpha(1 - gettextAlphaNumber(TopItem, BottomItem, itemHeight));                   getChildAt(i).findViewById(R.id.textview_xiantop).setAlpha(gettextAlphaNumber(TopItem, BottomItem, itemHeight));                 getChildAt(i).findViewById(R.id.money).setPadding(0, 0, 0, (int) getPadding(TopItem, BottomItem, itemHeight));                  getChildAt(i).findViewById(R.id.textview).setPadding(0, 0, 0, (int) getPadding(TopItem, BottomItem, itemHeight));                  getChildAt(i).findViewById(R.id.textview_xiantop).setPadding(0, 0, 0, (int) getPadding(TopItem, BottomItem, itemHeight));                }               else  {                       itemHeight = 200;                       getChildAt(i).findViewById(R.id.ivtwo).setAlpha(getAlphaNumber(TopItem, BottomItem, itemHeight));                       LinearLayout layout = (LinearLayout) getChildAt(i);                       AbsListView.LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight);                       layout.setLayoutParams(layoutParams);                       getChildAt(i).findViewById(R.id.textview).setAlpha(1);                       getChildAt(i).findViewById(R.id.textview_xiantop).setAlpha(0);                       getChildAt(i).findViewById(R.id.money).setPadding(0, 0, 0, (int) TwoPadding);                       getChildAt(i).findViewById(R.id.textview).setPadding(0, 0, 0, (int) TwoPadding);                       getChildAt(i).findViewById(R.id.textview_xiantop).setPadding(0, 0, 0, (int) TwoPadding);                }            }        }else        {            return;        }}    public void initLayot() {        for (int i = 0; i < getChildCount(); i++) {            float item0Height = getChildAt(0).getY();            Log.d("item0Height", item0Height + "");            lastY = item0Height;            if (i == 0) {                //itemHeight = 450;                float itemHeight = 400.0f + item0Height / getChildAt(0).getHeight() * 200.0f;                getChildAt(i).findViewById(R.id.ivtwo).setAlpha(getAlphaNumber(TopItem, BottomItem, 400));                LinearLayout layout = (LinearLayout) getChildAt(i);                AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) 400);                layout.setLayoutParams(layoutParams);                getChildAt(i).findViewById(R.id.money).setPadding(0, 0, 0, (int)FirstPadding);                getChildAt(i).findViewById(R.id.textview).setPadding(0, 0, 0, (int)FirstPadding);                getChildAt(i).findViewById(R.id.textview_xiantop).setPadding(0, 0, 0,(int)FirstPadding);            } else {                float itemHeight = 200.0f - item0Height / getChildAt(0).getHeight() * 200.0f;                getChildAt(i).findViewById(R.id.ivtwo).setAlpha(getAlphaNumber(TopItem, BottomItem, 200));                LinearLayout layout = (LinearLayout) getChildAt(i);                AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) 200);                layout.setLayoutParams(layoutParams);                getChildAt(i).findViewById(R.id.money).setPadding(0, 0, 0,(int)TwoPadding);                getChildAt(i).findViewById(R.id.textview).setPadding(0, 0, 0, (int)TwoPadding);                getChildAt(i).findViewById(R.id.textview_xiantop).setPadding(0, 0, 0,(int)TwoPadding);            }        }    }//Topstandard目前设置为450, BottomStand目前定为300,currentItemHeight算出来的当前的tem高public  float getAlphaNumber(float Topstandard, float BottomStand ,float currentItemHeight){    float delta=1-(Topstandard-currentItemHeight)/(Topstandard-BottomStand);    float alpha=0.45f-(delta*(maxAlpha - 0.1f));    return  alpha;}    //Topstandard目前设置为450, BottomStand目前定为300,currentItemHeight算出来的当前的tem高    public  float gettextAlphaNumber(float Topstandard, float BottomStand ,float currentItemHeight)    {        float delta=1-(Topstandard-currentItemHeight)/(Topstandard-BottomStand);        return  delta;    }    //Topstandard目前设置为450, BottomStand目前定为300,currentItemHeight算出来的当前的tem高    public  float getPadding(float Topstandard, float BottomStand ,float currentItemHeight)    {//        float delta=(Topstandard-currentItemHeight)/(Topstandard-BottomStand);//        float padding=100f-(delta*(100f - 10f));//        return  padding;        float delta=(Topstandard-currentItemHeight)/(Topstandard-BottomStand);        float padding=FirstPadding-(delta*(FirstPadding - TwoPadding));        return  padding;    }}




0 0
原创粉丝点击