[android进阶]仿京东app分类特效

[android进阶]仿京东app分类特效,第1张

概述https://blog.csdn.net/xiaolinxx/article/details/22108985在eoe论坛上看到某人高分求助,想实现京东分类效果效果如图1:图2:1、首先是图1,点击某分类后,右侧滑动出覆盖层(过程有动画),如图二。2、图一的分类列表在覆盖动画过程中,字体缩放,图片推出,直到图二效果。3、图二中,一级列

https://blog.csdn.net/xiaolinxx/article/details/22108985
在eoe论坛上看到某人高分求助,想实现京东分类效果

效果如图1:


图2:


1、首先是图1,点击某分类后,右侧滑动出覆盖层(过程有动画),如图二。
2、图一的分类列表在覆盖动画过程中,字体缩放,图片推出,直到图二效果。
3、图二中,一级列表选中效果的小箭头(见图二),在一级分类切换时箭头有滑动动画(这点可以暂不实现,若有高手那自然更好)。
4、图2分类切换时,右侧覆盖层更新内容。
5、图2可以向右滑动收回覆盖层。其中各种动画为1、2反向。


初步分析下这个界面,有点想slIDingMenu,但明显不是用的slIDingMenu实现的效果,应该是京东自己写得一个界面。

要实现这个界面,就需要对两个ListvIEw进行 *** 作,定义一个AnimationSildingLayout 对象从relativeLayout继承而来

实现界面上的手势拖动事件,事件拦截,滚动监听,等各种需要做的事情。

至于滚动效果,其实分两部分:

一是手指滑动过程中的动画,例如字体Alpha值的变化,左边ListvIEw的移动。

二是手指松开时的动画,右边的ListvIEw移出界面,左边的移进。

package com.example.fangJDSlIDing;
 
import androID.content.Context;
import androID.util.AttributeSet;
import androID.util.Log;
import androID.vIEw.*;
import androID.vIEw.animation.DecelerateInterpolator;
import androID.Widget.*;
import com.example.adapter.leftVIEwAdapter;
import com.nineoldandroIDs.animation.*;
 
import java.util.Dictionary;
import java.util.Hashtable;
 
/**
 * 自定义可以滑动的relativeLayout,处理京东分类的滑动效果
 * 用动画实现滚动效果
 *
 * @author linyanjun
 * @blog http://blog.csdn.net/xiaolinxx
 */
public class AnimationSildingLayout extends relativeLayout {
    /**
     * SildingLayout 布局的父布局
     */
    private VIEwGroup parentVIEw;
    private ListVIEw leftVIEw;
    private ListVIEw rightVIEw;
    /**
     * 滑动的最小距离
     */
    private int mtouchSlop;
    /**
     * 按下点的X坐标
     */
    private int downX;
    /**
     * 按下点的Y坐标
     */
    private int downY;
    /**
     * 临时存储X坐标
     */
    private int tempX;
    /**
     * 临时存储时间
     */
    private long tempTime;
    /**
     * 滑动类
     */
    private Scroller mScroller;
    /**
     * SildingLayout的宽度
     */
    private int vIEwWIDth;
 
    private int parentVIEwScrollX;
 
    private boolean isSilding;
 
    /**
     * 速度追踪对象
     */
    private VeLocityTracker veLocityTracker;
    private static final int SNAP_VELociTY = 300;
 
    private float leftList_move_rate;
    private float leftList_img_wIDth;
    private OnSildingFinishListener onSildingFinishListener;
 
 
    private int leftVIEwTotalMove;
    /**
     * 记录选中的item位置
     */
    private int selectItemposition;
    //箭头图标
    private ImageVIEw arrowVIEw;
 
    public AnimationSildingLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
 
    public AnimationSildingLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
 
        mtouchSlop = VIEwConfiguration.get(context).getScaledtouchSlop();
        mScroller = new Scroller(context);
        leftList_img_wIDth = context.getResources().getDimension(R.dimen.leftList_img_wIDth);
 
        Log.d("logonActivity", "SildingLayout() mtouchSlop:" + mtouchSlop);
 
    }
 
    public voID initLayout(final ListVIEw leftVIEw,ListVIEw rightVIEw){
        this.leftVIEw=leftVIEw;
        this.rightVIEw=rightVIEw;
        this.parentVIEw= (VIEwGroup) rightVIEw.getParent();
        parentVIEw.setVisibility(INVISIBLE);
        arrowVIEw= (ImageVIEw) findVIEwByID(R.ID.img_arrow);
        leftVIEw.setonScrollListener(new AbsListVIEw.OnScrollListener() {
            @OverrIDe
            public voID onScrollStateChanged(AbsListVIEw vIEw, int scrollState) {
                //To change body of implemented methods use file | Settings | file Templates.
            }
 
            @OverrIDe
            public voID onScroll(AbsListVIEw vIEw, int firstVisibleItem, int visibleItemCount, int totalitemCount) {
 
                if (leftVIEw.getChildAt(0)!=null) {
                    int deltaY=tempScrollY-getScroll();
                     tempScrollY=getScroll();
                    arrowVIEw.setY(arrowVIEw.getY()+deltaY);
                }
            }
 
 
        });
 
    }
 
    private Dictionary<Integer, Integer> ListVIEwItemHeights = new Hashtable<Integer, Integer>();
    private int tempScrollY;
    private int getScroll() {
        VIEw c = leftVIEw.getChildAt(0); //this is the first visible row
        int scrollY = -c.gettop();
        ListVIEwItemHeights.put(leftVIEw.getFirstVisibleposition(), c.getHeight());
        for (int i = 0; i < leftVIEw.getFirstVisibleposition(); ++i) {
            if (ListVIEwItemHeights.get(i) != null) // (this is a sanity check)
                scrollY += ListVIEwItemHeights.get(i); //add all heights of the vIEws that are gone
        }
        return scrollY;
    }
 
 
    /**
     * 事件拦截 *** 作
     */
    @OverrIDe
    public boolean onIntercepttouchEvent(MotionEvent ev) {
 
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // addVeLocityTracker(ev);
                downX = tempX = (int) ev.getRawX();
                downY = (int) ev.getRawY();
                tempTime = System.currentTimeMillis();
                break;
            case MotionEvent.ACTION_MOVE:
 
                int moveX = (int) ev.getRawX();
                //满足此条件屏蔽SildingLayout里面子类的touch事件
                if ((Math.abs(moveX - downX) > mtouchSlop
                        && Math.abs((int) ev.getRawY() - downY) < mtouchSlop)) {
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                //recycleVeLocityTracker();
                break;
        }
 
        return super.onIntercepttouchEvent(ev);
    }
 
 
    @OverrIDe
    public boolean ontouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
 
 
                break;
            case MotionEvent.ACTION_MOVE:
                if(parentVIEw.getVisibility()==VIEw.INVISIBLE){
                    break;
                }
                //在移动时候leftvIEw始终可见
                setleftVIEwVisiable();
                int moveX = (int) event.getRawX();
                int deltaX = tempX - moveX;
                leftVIEwTotalMove += deltaX;
                long NowTime = System.currentTimeMillis();
                long deltaTime = NowTime - tempTime;
                tempTime = NowTime;
                tempX = moveX;
                if (Math.abs(moveX - downX) > mtouchSlop
                        && Math.abs((int) event.getRawY() - downY) < mtouchSlop) {
                    isSilding = true;
                }
 
                if (moveX - downX >= 0 && isSilding) {
                    parentVIEw.setX(parentVIEw.getX() - deltaX);
 
                    //更新ListvIEw的文本
                    changelistVIEw();
                    if (Math.abs(leftVIEwTotalMove * leftList_move_rate) > 1) {
                        float targetX = leftVIEw.getX() - leftVIEwTotalMove * leftList_move_rate;
                        if (targetX >= -leftList_img_wIDth && leftVIEw.getX() <= 0) {
                            changelistVIEw();
                            leftVIEw.setX(targetX);
                        }
                        leftVIEwTotalMove = 0;
                    }
 
                }
                break;
            case MotionEvent.ACTION_UP:
                if(parentVIEw.getVisibility()==VIEw.INVISIBLE){
                    break;
                }
                leftVIEwTotalMove = 0;
                isSilding = false;
                if (parentVIEw.getX() >= vIEwWIDth / 3) {//移动继续超过1/3就向右滑动
                    scrollRight();
                    extendleftVIEw();
                } else {
                    scrollOrigin();
                    leftVIEwSlIDing((int) leftVIEw.getX(), -(int) leftList_img_wIDth, leftVIEw, 500l);
                }
 
                break;
            case MotionEvent.ACTION_CANCEL:
 
                break;
        }
 
        return true;
    }
 
    private voID onleftVIEwShorted() {
        leftVIEwAdapter ba = (leftVIEwAdapter) leftVIEw.getAdapter();
        ba.setHIDeFlag(true);
        ba.notifyDataSetChanged();
    }
 
    private voID onleftVIEwExtended() {
        leftVIEwAdapter ba = setleftVIEwVisiable();
        ba.notifyDataSetChanged();
    }
 
    private leftVIEwAdapter setleftVIEwVisiable() {
        leftVIEwAdapter ba = (leftVIEwAdapter) leftVIEw.getAdapter();
        if (ba.isHIDeFlag()) {
            ba.setHIDeFlag(false);
            ba.notifyDataSetChanged();
        }
        return ba;
    }
 
 
    @OverrIDe
    protected voID onLayout(boolean changed, int l, int t, int r, int b) {
 
        super.onLayout(changed, l, t, r, b);
        if (changed) {
            // 获取rightVIEw所在布局的父布局
            parentVIEw = (VIEwGroup) rightVIEw.getParent();
            vIEwWIDth = this.getWIDth();
            leftList_move_rate = leftList_img_wIDth / (vIEwWIDth - leftList_img_wIDth);
            Log.d("logonActivity", "SildingLayout:onLayout: leftList_move_rate" + leftList_move_rate);
 
 
        }
    }
 
    /**
     * 设置OnSildingFinishListener, 在onSildingFinish()方法中finish Activity
     *
     * @param onSildingFinishListener
     */
    public voID setonSildingFinishListener(
            OnSildingFinishListener onSildingFinishListener) {
        this.onSildingFinishListener = onSildingFinishListener;
    }
 
 
    /**
     * 滚动出界面
     */
    private voID scrollRight() {
        parentVIEwSlIDing((int) parentVIEw.getX(), vIEwWIDth, parentVIEw, 500l, new AnimatorListenerAdapter() {
            @OverrIDe
            public voID onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                onleftVIEwExtended();
                if (onSildingFinishListener != null) {
                    onSildingFinishListener.onSildingFinish();
                }
            }
        });
    }
 
    /**
     * 滚动到起始位置
     */
    public voID scrollOrigin() {
        parentVIEwSlIDing((int) parentVIEw.getX(), 0, parentVIEw, 500l, new AnimatorListenerAdapter() {
            @OverrIDe
            public voID onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                parentVIEwScrollX = 0;
            }
        });
    }
 
 
    private voID changelistVIEw() {
        int visibleposition = leftVIEw.getFirstVisibleposition();
        int lastVisibleposition = leftVIEw.getLastVisibleposition();
        int selectedItemNum=selectItemposition-visibleposition;
        // Log.d("logonActivity", String.format("SildingLayout:visibleposition:%d ,lastVisibleposition %d",visibleposition,lastVisibleposition));
        for (int i = 0; i <= lastVisibleposition - visibleposition; i++)//获取ListVIEw的所有Item数目
        {
            //    linearLayout linearlayout = (linearLayout)mListVIEw.getChildAt(i);
            VIEw vIEw = leftVIEw.getChildAt(i);
 
            if (vIEw != null && vIEw.getTag() != null) {
                leftVIEwAdapter.VIEwHolder holder = (leftVIEwAdapter.VIEwHolder) vIEw.getTag();
                // holder.textVIEw.setText(String.valueOf(parentVIEwScrollX));
                holder.description.setAlpha(Math.abs(parentVIEw.getX()) / vIEwWIDth);
                if(i==selectedItemNum){
                    holder.textVIEw.setText("我被选中了!");
                }
            }
        }
    }
 
    public voID startSildingInAnimation(int position) {
        this.selectItemposition = position;
        arrowVIEw.setY(leftVIEw.getChildAt(position-leftVIEw.getFirstVisibleposition()).gettop());
        tempScrollY=(int)getScroll();
        if (Math.abs(leftVIEw.getX()) < leftList_img_wIDth * 0.2) { //如果leftvIEw大部分都显示出来,就执行动画
 
            parentVIEwSlIDing(vIEwWIDth, 0, parentVIEw, 500l, new AnimatorListenerAdapter() {
                @OverrIDe
                public voID onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
 
                }
 
                @OverrIDe
                public voID onAnimationStart(Animator animation) {
                    super.onAnimationStart(animation);
                    parentVIEw.setVisibility(VISIBLE);
                }
            });
 
            leftVIEwSlIDing(0, -(int) leftList_img_wIDth, leftVIEw, 500l);
        }
    }
 
    private voID parentVIEwSlIDing(int fromx, int tox, VIEw vIEw, long duration, AnimatorListenerAdapter Listener) {
        PropertyValuesHolder pvTY = PropertyValuesHolder.offloat("x", fromx,
                tox);
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(vIEw, pvTY).setDuration(duration);
        objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @OverrIDe
            public voID onAnimationUpdate(ValueAnimator valueAnimator) {
//                parentVIEwScrollX = ((float) valueAnimator.getAnimatedValue()).intValue();
                changelistVIEw();
            }
        });
        objectAnimator.addListener(Listener);
        objectAnimator.setInterpolator(new DecelerateInterpolator());
        objectAnimator.start();
    }
 
 
    private voID leftVIEwSlIDing(int formx, int tox, VIEw vIEw, long duration) {
 
        PropertyValuesHolder leftXPv = PropertyValuesHolder.offloat("x", formx,
                tox);
        ObjectAnimator leftOA = ObjectAnimator.ofPropertyValuesHolder(vIEw, leftXPv).setDuration(duration);
        leftOA.setInterpolator(new DecelerateInterpolator());
        leftOA.start();
        leftOA.addListener(new AnimatorListenerAdapter() {
            @OverrIDe
            public voID onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                onleftVIEwShorted();
            }
        });
 
    }
 
 
    private voID extendleftVIEw() {
        PropertyValuesHolder leftXPv;
        if (leftVIEw.getX() < 0) {
            leftXPv = PropertyValuesHolder.offloat("x", leftVIEw.getX(),
                    0);
        } else {
            return;
        }
 
        ObjectAnimator leftOA = ObjectAnimator.ofPropertyValuesHolder(leftVIEw, leftXPv).setDuration(500);
        leftOA.addListener(new AnimatorListenerAdapter() {
            @OverrIDe
            public voID onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                onleftVIEwExtended();
            }
        });
        leftOA.setInterpolator(new DecelerateInterpolator());
        leftOA.start();
 
    }
 
 
    public interface OnSildingFinishListener {
        public voID onSildingFinish();
    }
 
    /**
     * 添加用户的速度跟踪器
     *
     * @param event
     */
    private voID addVeLocityTracker(MotionEvent event) {
        if (veLocityTracker == null) {
            veLocityTracker = VeLocityTracker.obtain();
        }
 
        veLocityTracker.addMovement(event);
    }
 
    /**
     * 移除用户速度跟踪器
     */
    private voID recycleVeLocityTracker() {
        if (veLocityTracker != null) {
            veLocityTracker.recycle();
            veLocityTracker = null;
        }
    }
 
    /**
     * 获取X方向的滑动速度,大于0向右滑动,反之向左
     *
     * @return
     */
    private int getScrollVeLocity() {
        veLocityTracker.computeCurrentVeLocity(1000);
        int veLocity = (int) veLocityTracker.getXVeLocity();
        return veLocity;
    }
 
 
 
 
}

源代码下载
————————————————
版权声明:本文为CSDN博主「xiaolinxx」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiaolinxx/article/details/22108985

总结

以上是内存溢出为你收集整理的[android进阶]仿京东app分类特效全部内容,希望文章能够帮你解决[android进阶]仿京东app分类特效所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1028167.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存