高仿饿了么订餐界面

来源:互联网 发布:java实战1200例怎么样 编辑:程序博客网 时间:2024/05/16 01:21

最近在公司比较闲,中午点外卖的时候突然发现订餐页面还可以,正好没事情做~ 于是准备仿照(饿了么)写一个~ 

下面上效果图


1、滑动联动的效果




2、订餐效果





恩,大致功能都完成了~


下面开始上代码

 

一、布局

布局比较简单,左右各一个ListView,这里我用到一个开源项目 PinnedHeaderListView

https://github.com/JimiSmith/PinnedHeaderListView 

 

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/rel_layout"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <android.support.v7.widget.Toolbar xmlns:app="http://schemas.android.com/apk/res-auto"        android:id="@+id/toolbar"        android:layout_width="match_parent"        android:layout_height="48dp"        android:layout_alignParentTop="true"        android:background="?attr/colorPrimary"        app:popupTheme="@style/AppTheme.PopupOverlay" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_below="@+id/toolbar"        android:orientation="horizontal"        android:paddingBottom="48dp">        <ListView            android:id="@+id/my_listview"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1"            android:background="@color/gray002"            android:scrollbars="none" />        <com.lly.order.view.PinnedHeaderListView            android:id="@+id/pinnedListView"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="3"            android:background="@android:color/white" />    </LinearLayout>    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="48dp"        android:layout_alignParentBottom="true"        android:background="#4E4E4E">        <ImageView            android:id="@+id/imageView2"            android:layout_width="32dp"            android:layout_height="32dp"            android:layout_centerVertical="true"            android:layout_marginLeft="8dp"            android:src="@mipmap/icon_cart" />        <TextView            android:id="@+id/tv_nm"            android:layout_width="16dp"            android:layout_height="16dp"            android:layout_alignTop="@+id/imageView2"            android:layout_toLeftOf="@+id/textView4"            android:layout_toStartOf="@+id/textView4"            android:background="@mipmap/cemara_bg_timer_red"            android:gravity="center"            android:text=""            android:textColor="@color/white"            android:textSize="12sp"            android:visibility="gone" />        <TextView            android:id="@+id/textView4"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerVertical="true"            android:layout_marginLeft="16dp"            android:layout_toRightOf="@+id/imageView2"            android:text="¥0"            android:textColor="@color/white"            android:textSize="21sp" />        <TextView            android:id="@+id/textView3"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:layout_marginLeft="16dp"            android:layout_marginRight="8dp"            android:text="¥30起送"            android:textColor="@color/gray006"            android:textSize="18sp" />    </RelativeLayout></RelativeLayout>


 

然后填充数据~ 我这里用的假数据,创建一个实体

package com.lly.order.entity;import java.util.List;public class FoodEntity {    private List<category> categoryList;    public List<category> getCategoryList() {        return categoryList;    }    public void setCategoryList(List<category> categoryList) {        this.categoryList = categoryList;    }    public static class category {        private String name;        private List<foodbean> foodbeans;        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public List<foodbean> getFoodbeans() {            return foodbeans;        }        public void setFoodbeans(List<foodbean> 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<FoodEntity.category.foodbean> 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<Integer, Integer> 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会报错

代码量不多,理清楚思路就好了~

 

 

 


3 1
原创粉丝点击