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分类特效所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)