最近在公司比较闲,中午点外卖的时候突然发现订餐页面还可以,正好没事情做~ 于是准备仿照(饿了么)写一个~
下面上效果图
1、滑动联动的效果
2、订餐效果
恩,大致功能都完成了~
下面开始上代码
一、布局
布局比较简单,左右各一个ListView,这里我用到一个开源项目 PinnedHeaderListView
https://github.com/JimiSmith/PinnedHeaderListView
然后填充数据~ 我这里用的假数据,创建一个实体
package com.lly.order.entity;
import java.util.List;
public class FoodEntity {
private List categoryList;
public List getCategoryList() {
return categoryList;
}
public void setCategoryList(List categoryList) {
this.categoryList = categoryList;
}
public static class category {
private String name;
private List foodbeans;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getFoodbeans() {
return foodbeans;
}
public void setFoodbeans(List foodbeans) {
this.foodbeans = foodbeans;
}
public static class foodbean {
private String dishes;
private int count;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public String getDishes() {
return dishes;
}
public void setDishes(String dishes) {
this.dishes = dishes;
}
}
}
}
添加数据
//获取数据
private void getData() {
List foodbeanList;
int num = 0;
for (int i = 0; i < 8; i++) { //三种类型
num++;
FoodEntity.category category = new FoodEntity.category();
category.setName("类型" + i);
foodbeanList = new ArrayList<>();
int random = new Random().nextInt(6) + 3;//随机
for (int j = 0; j < random; j++) {
num++;
FoodEntity.category.foodbean foodbean = new FoodEntity.category.foodbean();
foodbean.setDishes("鲍鱼" + j);
foodbeanList.add(foodbean);
}
category.setFoodbeans(foodbeanList);
categories.add(category);
location.put(i, num);
}
}
然后就是setAdapter啥的,具体不贴代码了,这里说一下怎么联动的
首先 监听pinnedHeaderListView的滑动事件 setOnScrollListener
pinnedHeaderListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int section = testSectionedAdapter.getSectionForPosition(firstVisibleItem);//获取当前的head
if (mSection != section) {
mCateGoryAdapter.setIndex(section);
mSection = section;
}
}
});
}
首先获取head的位置,然后传入分类的Adapter
/**
* 设置当前的位置
*
* @param mIndex
*/
public void setIndex(int mIndex) {
this.mIndex = mIndex;
notifyDataSetChanged();
}
在getView方法中判断
if (position == mIndex) {
convertView.setBackgroundColor(mContext.getResources().getColor(R.color.white));
} else {
convertView.setBackgroundColor(mContext.getResources().getColor(R.color.gray002));
}
就可以滑动的时候,左边列表更新了
//点击事件
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
if (position == 0) {
pinnedHeaderListView.setSelection(0);
} else {
pinnedHeaderListView.setSelection(location.get(position - 1));
}
mCateGoryAdapter.setIndex(position);
}
});
location 是一个MAP 里面保存着head的位置,在getData里面就是 i 的值
//保存head的位置
private HashMap location = new HashMap<>();
菜品添加效果的实现的实现方式,
点击添加按钮然后滑出的效果,仔细 观察其实是平移加旋转,下面帖代码
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX", viewHolder.imgbtn_add.getX(), 0f);
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("rotation", 0, 720);
ObjectAnimator.ofPropertyValuesHolder(viewHolder.imgbtn_cancle, p1, p2).setDuration(Duration).start();
PropertyValuesHolder pp1 = PropertyValuesHolder.ofFloat("translationX", (viewHolder.imgbtn_add.getX() - viewHolder.tv_number.getX()), 0f);
PropertyValuesHolder pp2 = PropertyValuesHolder.ofFloat("rotation", 0, 360);
ObjectAnimator ObjectAnimator1 = ObjectAnimator.ofPropertyValuesHolder(viewHolder.tv_number, pp1, pp2);
ObjectAnimator1.setStartDelay(50);//延迟
ObjectAnimator1.setDuration(Duration);
ObjectAnimator1.start();
就是把 “-” 和 数量 2个view从添加按钮的位置移动到本身的位置,且进行旋转
当然还有收回去的效果,就在把值换一下就行了,然后监听动画执行完毕,把按钮隐藏就行了
丢到购物车效果的实现,这里我差不多花了一下午时间,才弄好.......
开始我在ListView item里面写了一个View 然后准备移动到指定的位置(购物车),发现移动范围只能在item里面......一想发现自己2B了,View只能在父容器里面移动
恩,所以要在跟布局中写动画了,下面说一下实现过程
1、获取点击item的坐标,这里是获取屏幕的绝对坐标
int[] location = new int[2];
viewHolder.imgbtn_add.getLocationOnScreen(location)
通过写一个接口,通过回调的方式到Activity
public interface onItemClickLocation {
public void onLocation(int x, int y);
}
然后在Activity拿到坐标
public void onLocation(final int x, final int y) {
//生成一个View
final ImageView img_view = new ImageView(this);
img_view.setImageResource(R.mipmap.food_button_add);
relativeLayout.addView(img_view);
//把View的位置移动到和点击的一个位置
img_view.setX(x);
img_view.setY(y - 48);//-48
// 计算位移
float endX = imageViewX - x;
float endY = imageViewY - y;
//执行位移和透明度动画
TranslateAnimation translateAnimationx = new TranslateAnimation(0, endX, 0, 0);
translateAnimationx.setInterpolator(new LinearInterpolator());//匀速
img_view.setAnimation(translateAnimationx);
TranslateAnimation translateAnimationY = new TranslateAnimation(0, 0, 0, endY);
translateAnimationY.setInterpolator(new AccelerateInterpolator());
translateAnimationY.setStartOffset(50);
img_view.setAnimation(translateAnimationY);
AlphaAnimation alphaAnimation = new AlphaAnimation(1f, 0.1f);
img_view.setAnimation(alphaAnimation);
AnimationSet set = new AnimationSet(false);
set.setFillAfter(false);
set.addAnimation(translateAnimationY);
set.addAnimation(translateAnimationx);
set.addAnimation(alphaAnimation);
set.setDuration(500);// 动画的执行时间
img_view.startAnimation(set);
set.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
setTextNum();
relativeLayout.postDelayed(new Runnable() {
@Override
public void run() {
relativeLayout.removeView(img_view);
}
}, 100);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
动画执行完之后,然后remove掉View,我这里延迟是因为view可能没有立马执行完onDrawa方法,这时候remove会报错
代码量不多,理清楚思路就好了~