[android进阶]仿京东app分类特效
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了[android进阶]仿京东app分类特效,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含15702字,纯文字阅读大概需要23分钟。
内容图文
![[android进阶]仿京东app分类特效](/upload/InfoBanner/zyjiaocheng/1022/b497413ef3324c5ca43f4875d06bf69a.jpg)
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分类特效所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。