天天看點

實作美團、餓了麼購物車效果,并本地存儲相關資料

前言

聖誕節快到了,在這裡先祝大家聖誕節快樂!

實作美團、餓了麼購物車效果,并本地存儲相關資料

這篇文章就當我送給大家的節日禮物了(可能寫的部落格技術含量不是很高或者有些許錯誤,希望大家諒解)。

效果圖

實作美團、餓了麼購物車效果,并本地存儲相關資料

分析

有很多時候我們會得到各式各樣的效果和功能,在了解了任務之後我不建議大家馬上去百度或者編寫代碼。應該先分析任務的邏輯,并思考每部分利用什麼控件或者技術實作,哪種實作效果能使我們的邏輯更清晰,即使代碼編寫錯誤當我們修改的時候也不需要改動太大或者重新進行編寫(遵循開閉原則),避免浪費我們的時間。其實就是我們面向接口程式設計的思想,先抽象後實作。
  1. 對于左側菜單和右側内容部分關聯的效果——采用兩個RecyclerView控件
  2. 添加購物車動畫的實作——采用TranslateAnimation動畫
  3. 資料的存儲、擷取以及删除——采用xutils架構

是不是感覺簡單分析之後,思路清晰多了,實作起來也知道該從哪裡入手了。

代碼實作

1. RecyclerView控件實作左側菜單和右側内容關聯效果

activity_main.xml

<LinearLayout
    android:layout_below="@+id/include"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/view"
    android:orientation="horizontal">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/m_list_menu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="5"
        android:scrollbars="none">

    </android.support.v7.widget.RecyclerView>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/m_list_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="2"
        android:scrollbars="none">

    </android.support.v7.widget.RecyclerView>
</LinearLayout>
           

主布局相對來說簡單多了,就不進行詳細的講解了。

item_menu.xml

<LinearLayout
    android:id="@+id/black_lay"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:gravity="center"
    android:orientation="horizontal">
    <View
        android:id="@+id/item_menu_view_red"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"
        android:layout_weight="30"
        android:background="@color/title_color_ff0000"/>
    <TextView
        android:id="@+id/item_menu_text"
        android:layout_width="match_parent"
        android:gravity="center_horizontal"
        android:layout_height="wrap_content"
        android:layout_weight="0.5"
        android:textSize="16sp"
        android:textColor="@android:color/black"
        android:text="好評榜"/>
    <View
        android:id="@+id/item_menu_view_v"
        android:layout_width="0.1dp"
        android:layout_height="50dp"
        android:background="@color/color_menu_lines"/>
</LinearLayout>
           

菜單布局左右兩側分别有一條豎着的黑線和紅線,當我們進行點選item操作的時候,需要進行的隐藏和顯示效果來達到該item處于選中狀态。

item_menu_content.xml

item_menu_content就是一個簡單的布局,由于代碼量太大就不進行展示了,大家可以下載下傳我的Demo進行檢視。
           

RecyclerViewMenuAdapter.java

左側菜單的資料填充器,主要的部分就是在onBindViewHolder方法裡面,先讓所有的item顯示為預設狀态,在根據點選item對應的position來改變該item的狀态即可:

//綁定ViewHolder
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    holder.mTextView.setText(DemoData.ListMenu_STYLE[position]);
    //設定所有的item顯示為預設狀态
    holder.mLinearLayout.setBackgroundResource(R.color.color_menu_back);
    holder.viewRed.setVisibility(View.GONE);
    holder.viewV.setVisibility(View.VISIBLE);
    //根據點選item對應的position來改變該item的狀态
    if (holder.getPosition() == MainActivity.SELECTPOSITION) {
        holder.mLinearLayout.setBackgroundResource(R.color.white);
        holder.viewRed.setVisibility(View.VISIBLE);
        holder.viewV.setVisibility(View.GONE);
    }
    setOnListtener(holder);
}
           

RecyclerViewContentAdapter.java

左側内容填充器則為普通的内容沒有什麼特殊的地方
           

MainActivity.java

/**
 * 菜單清單    資料填充
 */
private void setMenuCommonadapter() {
     mRecyclerViewMenuCommonadapter = new RecyclerViewMenuAdapter(mContext, stringMenuList);
     mRecyclerMenu.setAdapter(mRecyclerViewMenuCommonadapter);
     mRecyclerViewMenuCommonadapter.setOnItemClickListener(new RecyclerViewMenuAdapter.OnItemClickListener() {
         @Override
         public void onItemClick(View v, int position) {
             SELECTPOSITION = position;
             Log.e("TAG", "SELECTPOSITION:" + SELECTPOSITION);
             mRecyclerViewMenuCommonadapter.notifyDataSetChanged();
             mRecyclerViewContentCommonadapter.notifyDataSetChanged();
         }
         @Override
         public void onItemLongClick(View v, int position) {}
     });
}
           

當點選item的時候,改變SELECTPOSITION 的值,再重新整理兩個recyclerview即可。

效果圖如下:

實作美團、餓了麼購物車效果,并本地存儲相關資料

由于資料全部都是一樣的是以可能看起來,左側内容部分沒有什麼改變,但其實資料已經重新整理了。

模拟器和錄制gif圖工具有些問題,是以分割線顯示不全并且有色差,大家如果有什麼好的工具可以給我推薦推薦,在這裡謝謝大家了!

2.添加購物車動畫的實作

在做添加購物車動畫的時候,首先想到的就是translateanimation平移動畫,公司同僚做過類似的動畫是以拿過來稍加修改并封裝成了工具類,使用起來杠杠滴。

/** 動畫 */
GoodsAnimUtil.setAnim(MainActivity.this, holder.mImgJia, mCarLay);
GoodsAnimUtil.setOnEndAnimListener(new onEndAnim());
           

首先調用工具類裡面的setAnim()方法,就可以設定和開始動畫了;

再監聽動畫,當動畫結束時進行相關操作即可。

public static void setAnim(Activity activity , View imgphoto, View imgcar){
     mActivity = activity;
     mImgcar = imgcar;
     // 一個整型數組,用來存儲按鈕的在螢幕的X、Y坐标
     int[] start_location = new int[];
     // 這是擷取購買按鈕的在螢幕的X、Y坐标(這也是動畫開始的坐标)
     imgphoto.getLocationInWindow(start_location);
     int[] start_location1 = new int[]{start_location[], start_location[]};
     // buyImg是動畫的圖檔,我的是一個小球(R.drawable.sign)
     ImageView buyImg = new ImageView(mActivity);
     // 設定buyImg的圖檔
     buyImg.setImageResource(R.mipmap.aii);
     // 開始執行動畫
     startAnim(buyImg, start_location1);
}
           
  • imgphoto代表我們點選的view,通過imgphoto.getLocationInWindow(start_location)得帶我們點選view的橫坐标和縱坐标,并存在start_location數組裡面;
  • imgcar代表結束位置的view,也是通過mImgcar.getLocationInWindow(end_location)得到結束位置的橫坐标和縱坐标,并存在end_location數組裡面。
/**
 *開始動畫
 */
private static void startAnim(final View v, int[] start_location) {
    anim_mask_layout = null;
    anim_mask_layout = createAnimLayout();
    anim_mask_layout.addView(v);//把動畫小球添加到動畫層
    view = addViewToAnimLayout(anim_mask_layout, v,start_location);
    int[] end_location = new int[];// 這是用來存儲動畫結束位置的X、Y坐标
    mImgcar.getLocationInWindow(end_location);// shopCart是那個購物車
    int width = getWindowsWidth(mActivity);
    // 計算位移
    int endY = end_location[] - start_location[];// 動畫位移的y坐标
    int endX =  - start_location[] + (mImgcar.getWidth() / );// 動畫位移的X坐标
    TranslateAnimation translateAnimationX = new TranslateAnimation(,endX, , );
    translateAnimationX.setInterpolator(new LinearInterpolator());
    translateAnimationX.setRepeatCount();// 動畫重複執行的次數
    translateAnimationX.setFillAfter(true);
    TranslateAnimation translateAnimationY = new TranslateAnimation(, ,, endY);
    translateAnimationY.setInterpolator(new AccelerateInterpolator());
    translateAnimationY.setRepeatCount();// 動畫重複執行的次數
    translateAnimationX.setFillAfter(true);
    ScaleAnimation scaleAnimation = new ScaleAnimation(f, f, f, f);
    scaleAnimation.setInterpolator(new AccelerateInterpolator());
    scaleAnimation.setRepeatCount();// 動畫重複執行的次數
    scaleAnimation.setFillAfter(true);
    scaleAnimation.setDuration();
    final AnimationSet set = new AnimationSet(false);
    set.setFillAfter(false);
    set.addAnimation(translateAnimationY);
    set.addAnimation(translateAnimationX);
    //set.setStartOffset(300);
    set.setDuration();// 動畫的執行時間
    view.startAnimation(set);
    // 動畫監聽事件
    set.setAnimationListener(new Animation.AnimationListener() {
        // 動畫的開始
        @Override
        public void onAnimationStart(Animation animation) {
            v.setVisibility(View.VISIBLE);
        }
        @Override
        public void onAnimationRepeat(Animation animation) {}
        // 動畫的結束
        @Override
        public void onAnimationEnd(Animation animation) {
            v.setVisibility(View.GONE);
            anim_mask_layout.removeAllViews();
            YoYo.with(Techniques.Bounce).withListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {}
                @Override
                public void onAnimationEnd(Animator animation) {
                    mEndAnimListener.onEndAnim();
                }
                @Override
                public void onAnimationCancel(Animator animation) {}
                @Override
                public void onAnimationRepeat(Animator animation) {}
            }).interpolate(new BounceInterpolator()).duration().playOn(mImgcar);
        }
    });
}
           

在這堆複雜的代碼中,我們隻需要關心這兩句代碼即可:

// 計算位移
int endY = end_location[] - start_location[];// 動畫位移的y坐标
int endX = end_location[] - start_location[] + (mImgcar.getWidth() / );// 動畫位移的X坐标
           

在我們的手機界面裡,左上角為(0,0),是以從上向下是正,從左向右是正,是以:

結束位置的縱坐标減去開始位置的縱坐标作為動畫位移的y距離;

結束位置的橫坐标減去開始位置的橫坐标再加上結束位置的view的一半作為動畫移動的x距離。

動畫效果就實作了,當然如果你想實作其他效果隻需要修改GoodsAnimUtil類即可,而主代碼中的代碼不需要改變,這就展現出了低耦合的重要性;

3.采用xutils架構實作本地資料庫

GoodsBean .java

@Table(name = "goods")
public class GoodsBean extends GoodsBase{
    @Column(column = "menupos")
    private int menupos;
    @Column(column = "goodsid")
    private int goodsid;
    @Column(column = "goodsnum")
    private String goodsnum;
    @Column(column = "goodsprice")
    private String goodsprice;

    public int getMenupos() {
        return menupos;
    }

    public void setMenupos(int menupos) {
        this.menupos = menupos;
    }

    public int getGoodsid() {
        return goodsid;
    }

    public void setGoodsid(int goodsid) {
        this.goodsid = goodsid;
    }

    public String getGoodsnum() {
        return goodsnum;
    }

    public void setGoodsnum(String goodsnum) {
        this.goodsnum = goodsnum;
    }

    public String getGoodsprice() {
        return goodsprice;
    }

    public void setGoodsprice(String goodsprice) {
        this.goodsprice = goodsprice;
    }

    @Override
    public String toString() {
        return "GoodsBean{" +
                "menupos='" + menupos + '\'' +
                ", goodsid='" + goodsid + '\'' +
                ", goodsnum='" + goodsnum + '\'' +
                ", goodsprice='" + goodsprice + '\'' +
                '}';
    }
}
           

建立資料庫goods,菜單欄每項對應的menupos、商品的goodsid、存儲數量goodsnum和每個商品對應的價格goodsprice這幾個字段是我們在進行資料庫操作的時候需要使用到的字段;

分析效果圖:

a.點選加号,根據菜單欄的menupos和對應的商品的goodsid進行存儲資料;

b.點選減号,根據菜單欄的menupos和對應的商品的goodsid進行存儲資料;

c.點選菜單欄的item,根據菜單欄的menupos得到二級每個商品已經存儲的數量;

d.點選菜單欄的item,根據菜單欄的menupos得到二級所有商品的存儲數量;

e.點選菜單欄的item,根據菜單欄的menupos得到二級所有商品的存儲價格;

f.删除所有的存儲資料。

根據分析結果,編寫接口以及我們需要實作的方法:

GoodsDataBaseInterface .java

public interface GoodsDataBaseInterface {
    /** 添加和删除購物的數量 */
    int saveGoodsNumber(Context context, int menupos, int goodsid, String goodsnum, String goodsprice);

    /** 根據下标得到 第二級對應購物的數量 */
    int getSecondGoodsNumber(Context context, int menupos, int goodsid);

    /** 根據第一級的下标 得到第二級的所有購物數量 */
    int getSecondGoodsNumberAll(Context context, int menupos);

    /** 根據第一級的下标 得到第二級的所有購物的價格 */
    int getSecondGoodsPriceAll(Context context, int menupos);
    /** 删除所有的購物資料 */
    void deleteAll(Context context);

}
           

編寫實作類OperateGoodsDataBase繼承GoodsDataBaseInterface 接口:

public class OperateGoodsDataBase implements GoodsDataBaseInterface{
   private static OperateGoodsDataBase instance  = new OperateGoodsDataBase();
   public static OperateGoodsDataBase getInstance(){
       return  instance;
   }
   private OperateGoodsDataBase(){}
   /**
    *添加和删除商品數量,并得到商品數量
    */
   @Override
   public int saveGoodsNumber(Context context, int menupos, int goodsid, String goodsnum , String goodsprice) {
       return OperateGoodsDataBaseStatic.saveGoodsNumber(context , menupos , goodsid , goodsnum ,goodsprice);
   }
   /**
    *根據下标得到 第二級對應購物的數量
    */
   @Override
   public int getSecondGoodsNumber(Context context, int menupos, int goodsid) {
       return OperateGoodsDataBaseStatic.getSecondGoodsNumber(context, menupos, goodsid);
   }
   /**
    * 根據第一級的下标 得到第二級的所有購物數量
    */
   @Override
   public int getSecondGoodsNumberAll(Context context, int menupos) {
       return OperateGoodsDataBaseStatic.getSecondGoodsNumberAll(context, menupos);
   }

   /**
    *據第一級的下标 得到第二級的所有購物的價格
    */
   @Override
   public int getSecondGoodsPriceAll(Context context, int menupos) {
       return OperateGoodsDataBaseStatic.getSecondGoodsPriceAll(context, menupos);
   }
   /**
    *删除所有的購物資料
    */
   @Override
   public void deleteAll(Context context) {
       OperateGoodsDataBaseStatic.deleteAll(context);
   }
}
           

在實作類裡面寫了一個單例,這樣在其他類裡面調用該單例隻會有一個實作類,減少了記憶體的消耗;

OperateGoodsDataBaseStatic.java

public class OperateGoodsDataBaseStatic{
    /**
     *添加和删除商品數量
     */
    public static int saveGoodsNumber(Context context, int menupos, int goodsid, String goodsnum , String goodsprice) {
        DbUtils utils = DbUtils.create(context);
        GoodsBean goodsBean = null;
        goodsBean =new GoodsBean();
        goodsBean.setMenupos(menupos);
        goodsBean.setGoodsid(goodsid);
        goodsBean.setGoodsnum(goodsnum);
        goodsBean.setGoodsprice(goodsprice);
        try {
            GoodsBean bean = utils.findFirst(Selector.from(GoodsBean.class).where("menupos" , "=" , menupos).and("goodsid", "=", goodsid));
            //如果有這條資料,數量直接加1;否則就插入表裡面
            if(bean == null){
                Log.e("TAG", "還沒有該商品");
                utils.save(goodsBean);
                Log.e("TAG" , "該商品已經存儲");
                return getSecondGoodsNumber(context , menupos , goodsid);
            }else{
                Log.e("TAG" , "已經有該商品");
                //傳回添加商品之後的商品總數
                return updateNum(context, menupos, goodsid, goodsnum);
            }
        } catch (DbException e) {
            e.printStackTrace();
        }
        Log.e("TAG" , "添加商品失敗");
        utils.close();
        return ;
    }
    /**修改數量,直接傳入數量**/
    public static int updateNum(Context context , int menupos , int goodsid , String goodsnum){
        DbUtils utils = DbUtils.create(context);
        try {
            GoodsBean bean = utils.findFirst(Selector.from(GoodsBean.class).where("menupos", "=", menupos).and("goodsid", "=", goodsid));
            bean.setGoodsnum(goodsnum);
            utils.update(bean);
            Log.e("TAG", "該商品數量改變為:" + getSecondGoodsNumber(context, menupos, goodsid));
            return getSecondGoodsNumber(context , menupos , goodsid);
        } catch (DbException e) {
            e.printStackTrace();
        }
        utils.close();
        return ;
    }
    /**
     *根據下标得到 第二級對應購物的數量
     */
    public static int getSecondGoodsNumber(Context context , int menupos , int goodsid) {
        DbUtils utils = DbUtils.create(context);
        if(utils == null){
            Log.e("TAG" , "還沒有該資料庫");
            return ;
        }
        try {
            GoodsBean bean = utils.findFirst(Selector.from(GoodsBean.class).where("menupos", "=", menupos).and("goodsid", "=", goodsid));
            if(bean == null){
                Log.e("TAG" , "還沒有該存儲商品");
                return ;
            }else{
                Log.e("TAG" , "擷取商品數量成功:" + Integer.parseInt(bean.getGoodsnum()));
                return Integer.parseInt(bean.getGoodsnum());
            }
        } catch (DbException e) {
            e.printStackTrace();
        }
        utils.close();
        Log.e("TAG", "擷取商品數量失敗");
        return ;
    }
    /**
     * 根據第一級的下标 得到第二級的所有購物數量
     */
    public static int getSecondGoodsNumberAll(Context context, int menupos) {
        DbUtils utils = DbUtils.create(context);
        int mSecondGoodsNum = ;
        ArrayList<GoodsBean> mGoodsBeanList = null;
        mGoodsBeanList = getSecondGoodsTypeList(context);
        if(mGoodsBeanList == null){
            Log.e("TAG" , "擷取商品類型總數失敗");
            return ;
        }
        for(int i =  ; i < mGoodsBeanList.size() ; i++){
            if(mGoodsBeanList.get(i).getMenupos() == menupos){
                mSecondGoodsNum += Integer.parseInt(mGoodsBeanList.get(i).getGoodsnum());
            }
        }
        Log.e("TAG", "根據第一級的下标 得到第二級的所有購物數量成功:" + mSecondGoodsNum);
        utils.close();
        return mSecondGoodsNum;
    }
    /**
     *根據第一級的下标 得到第二級商品所有商品類型集合
     */
    public static ArrayList<GoodsBean> getSecondGoodsTypeList(Context context){
        DbUtils utils = DbUtils.create(context);
        ArrayList<GoodsBean> list = null;
        try {
            list = (ArrayList<GoodsBean>) DbUtils.create(context).findAll(GoodsBean.class);
            if(list == null){
                Log.e("TAG" , "該二級商品還沒有存儲資料");
                return null;
            }else{
                Log.e("TAG" , "根據第一級的下标 得到第二級商品類型總數成功:" + list.size());
                return list;
            }
        } catch (DbException e) {
            e.printStackTrace();
        }
        Log.e("TAG" , "根據第一級的下标 得到第二級商品類型總數失敗");
        return null;
    }

    /**
     *據第一級的下标 得到第二級的所有購物的價格
     */
    public static int getSecondGoodsPriceAll(Context context, int menupos) {
        DbUtils utils = DbUtils.create(context);
        int mSecondGoodsPrice = ;
        ArrayList<GoodsBean> mGoodsBeanList = null;
        mGoodsBeanList = getSecondGoodsTypeList(context);
        if(mGoodsBeanList == null){
            Log.e("TAG" , "擷取商品類型總數失敗");
            return ;
        }
        for(int i =  ; i < mGoodsBeanList.size(); i++){
            if(mGoodsBeanList.get(i).getMenupos() == menupos){
                mSecondGoodsPrice += Integer.parseInt(mGoodsBeanList.get(i).getGoodsnum()) * Integer.parseInt(mGoodsBeanList.get(i).getGoodsprice());
            }
        }
        Log.e("TAG" , "根據第一級的下标 得到第二級的所有購物的價格成功:" + mSecondGoodsPrice);
        utils.close();
        Log.e("TAG" , "根據第一級的下标 得到第二級的所有購物的價格失敗");
        return mSecondGoodsPrice;
    }
    /**
     *删除所有的購物資料
     */
    public static void deleteAll(Context context) {
        DbUtils utils = DbUtils.create(context);
        try {
            List<GoodsBean> records = utils.findAll(GoodsBean.class);
            utils.deleteAll(records);
        } catch (DbException e) {
            e.printStackTrace();
        }
        utils.close();
    }
}
           

對于資料庫的操作,沒有什麼複雜的邏輯,隻需要記住基本的代碼就可以了,是以就不進行講解了,裡面備注寫的也十分詳細;

整合代碼

RecyclerViewContentAdapter.java

a.在onBindViewHolder()方法裡面根據點選的一級菜單的position和商品id,判斷資料庫裡面是否有該商品,有該商品則顯示減号圖示和對應的存儲數量;

//綁定ViewHolder
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    holder.mImageView.setImageResource(DemoData.ListMenu_PIMAGES[position]);
    holder.mTitle.setText(DemoData.ListMenu_PTITLE[position]);
    holder.mYueSale.setText("月售" + DemoData.ListMenu_NUMBER[position]);
    holder.mPrice.setText(DemoData.ListMenu_PPRICE[position]);

    holder.mRatingBar.setRating(Float.parseFloat(DemoData.ListMenu_STAR[position]));
    holder.mRatingBar.getRating();

    /** 擷取存儲的商品數量 */
    if (mGoodsDataBaseInterface.getSecondGoodsNumber(mContext, MainActivity.SELECTPOSITION , DemoData.ListMenu_GOODSID[holder.getPosition()]) == ) {
        holder.mNumber.setText("");
        holder.mNumber.setVisibility(View.GONE);
        holder.mImgJian.setVisibility(View.GONE);
    } else {
        holder.mNumber.setText("" + mGoodsDataBaseInterface.getSecondGoodsNumber(mContext, MainActivity.SELECTPOSITION , DemoData.ListMenu_GOODSID[holder.getPosition()]));
        holder.mNumber.setVisibility(View.VISIBLE);
        holder.mImgJian.setVisibility(View.VISIBLE);
    }
    setOnListtener(holder);
}
           

b.自定義item點選、長點選、添加商品和減少商品的監聽事件;

//觸發
protected void setOnListtener(final ViewHolder holder){
   if(mOnItemClickListener != null){
       holder.itemView.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               mOnItemClickListener.onItemClick(holder);
           }
       });
       holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
           @Override
           public boolean onLongClick(View v) {
               mOnItemClickListener.onItemLongClick(holder);
               return true;
           }
       });
       holder.mImgJia.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               mOnItemClickListener.onItemJiaClick(holder);
           }
       });
       holder.mImgJian.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               mOnItemClickListener.onItemJianClick(holder);
           }
       });
   }
}
           

c.點選加号和減号的時候,進行相關的操作;

MainActivity.java

mRecyclerViewContentCommonadapter.setOnItemClickListener(new RecyclerViewContentAdapter.OnItemClickListener() {
@Override
public void onItemClick(RecyclerViewContentAdapter.ViewHolder holder) {}
@Override
public void onItemLongClick(RecyclerViewContentAdapter.ViewHolder holder) {}
/** 添加 */
@Override
public void onItemJiaClick(RecyclerViewContentAdapter.ViewHolder holder) {
    String numText = holder.mNumber.getText().toString().trim();
    /** 點選加号之前還沒有資料的時候 */
    if (numText.isEmpty() || numText.equals("0")) {
        Log.e("TAG", "點選擷取資訊:SELECTPOSITION--" + SELECTPOSITION + "  DemoData.ListMenu_GOODSID[position]--" + DemoData.ListMenu_GOODSID[holder.getPosition()]);
        holder.mImgJian.setVisibility(View.VISIBLE);
        holder.mNumber.setText(mGoodsDataBaseInterface.saveGoodsNumber(mContext, SELECTPOSITION, DemoData.ListMenu_GOODSID[holder.getPosition()], "1", DemoData.ListMenu_PPRICE[holder.getPosition()]) + "");
        holder.mNumber.setVisibility(View.VISIBLE);
    }/** 點選加号之前有資料的時候 */
    else {
        holder.mNumber.setText(mGoodsDataBaseInterface.saveGoodsNumber(mContext, SELECTPOSITION, DemoData.ListMenu_GOODSID[holder.getPosition()], String.valueOf(Integer.parseInt(numText) + ), DemoData.ListMenu_PPRICE[holder.getPosition()]) + "");
    }
    /** 動畫 */
    GoodsAnimUtil.setAnim(MainActivity.this, holder.mImgJia, mCarLay);
    GoodsAnimUtil.setOnEndAnimListener(new onEndAnim());
    /** 統計購物總數和購物總價 */
}
/** 減少 */
@Override
public void onItemJianClick(RecyclerViewContentAdapter.ViewHolder holder) {
    String numText = holder.mNumber.getText().toString().trim();
    holder.mNumber.setText(mGoodsDataBaseInterface.saveGoodsNumber(mContext, SELECTPOSITION, DemoData.ListMenu_GOODSID[holder.getPosition()], String.valueOf(Integer.parseInt(numText) - ), DemoData.ListMenu_PPRICE[holder.getPosition()]) + "");
    numText = holder.mNumber.getText().toString().trim();
    /** 減完之後  資料為0 */
    if (numText.equals("0")) {
        holder.mNumber.setVisibility(View.GONE);
        holder.mImgJian.setVisibility(View.GONE);
    }
    setAll();
}
});
           

d.在點選item的點選事件、點選加号監聽動畫結束和點選減号的時候都要調用setAll()方法進行商品總數和商品價格的資料更新;

/**
 * 點選加号和減号的時候設定總數和總價格
 */
private void setAll() {
 //設定所有購物數量
 if (mGoodsDataBaseInterface.getSecondGoodsNumberAll(mContext, SELECTPOSITION) == ) {
     mListAllNum.setVisibility(View.GONE);
     mListAllPrice.setText("¥0");
     mListAllNum.setText("0");
 } else {
     mListAllPrice.setText("¥" + mGoodsDataBaseInterface.getSecondGoodsPriceAll(mContext, SELECTPOSITION) + "");
     mListAllNum.setText(mGoodsDataBaseInterface.getSecondGoodsNumberAll(mContext, SELECTPOSITION) + "");
     mListAllNum.setVisibility(View.VISIBLE);
 }
}
           

全部主代碼 MainActivity.java

public class MainActivity extends BaseActivity {
    /**
     * 标題
     */
    @InjectView(R.id.m_fml_title_tv)
    TextView mTitle;
    /**
     * 側邊欄菜單RecyclerView
     */
    @InjectView(R.id.m_list_menu)
    RecyclerView mRecyclerMenu;
    /**
     * 内容RecyclerView
     */
    @InjectView(R.id.m_list_content)
    RecyclerView mRecyclerContent;
    /**
     * 商品總價
     */
    @InjectView(R.id.m_list_all_price)
    TextView mListAllPrice;
    /**
     * 物品總數量
     */
    @InjectView(R.id.m_list_num)
    TextView mListAllNum;
    /**
     * 側邊欄菜單資料填充器
     */
    private RecyclerViewMenuAdapter mRecyclerViewMenuCommonadapter = null;
    /**
     * 内容資料填充器
     */
    private RecyclerViewContentAdapter mRecyclerViewContentCommonadapter = null;
    private Context mContext;
    /**
     * 存儲資料list
     */
    private List<String> stringMenuList = new ArrayList<String>();
    private List<String> stringContentList = new ArrayList<String>();
    public static int SELECTPOSITION = ;
    /**
     * 資料操作接口
     */
    GoodsDataBaseInterface mGoodsDataBaseInterface = null;
    /**
     * 購物車布局
     */
    @InjectView(R.id.m_list_car_lay)
    RelativeLayout mCarLay;

    @Override
    protected void onCreate(Bundle arg0) {
        super.onCreate(arg0);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(MainActivity.this);
        mContext = this;
        initView();
        setRecyclerView();
        initHttp();
    }
    private void initView() {
        mGoodsDataBaseInterface = OperateGoodsDataBase.getInstance();
        //清空資料庫緩存
        mGoodsDataBaseInterface.deleteAll(mContext);
        mTitle.setText("清單菜單");
    }
    /**
     * 模拟網絡請求資料
     */
    private void initHttp() {
        for (int i = ; i < ; i++) {
            stringMenuList.add("1111");
        }
        for (int i = ; i < ; i++) {
            stringContentList.add("2222");
        }
        setMenuCommonadapter();
        setContentCommonadapter();
    }
    @OnClick({R.id.m_fml_title_back, R.id.m_list_submit})
    void onClick(View v) {
        switch (v.getId()) {
            case R.id.m_fml_title_back:
                finish();
                break;
            case R.id.m_list_submit:
                Toast.makeText(mContext, "送出", Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
    }
    /**
     * 設定RecyclerView的布局方式
     */
    private void setRecyclerView() {
        //垂直listview顯示方式
        mRecyclerMenu.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false));
        mRecyclerMenu.addItemDecoration(new DividerItemDecoration(mContext, LinearLayoutManager.VERTICAL));
        mRecyclerContent.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false));
    }
    /**
     * 菜單清單    資料填充
     */
    private void setMenuCommonadapter() {
        mRecyclerViewMenuCommonadapter = new RecyclerViewMenuAdapter(mContext, stringMenuList);
        mRecyclerMenu.setAdapter(mRecyclerViewMenuCommonadapter);
        mRecyclerViewMenuCommonadapter.setOnItemClickListener(new RecyclerViewMenuAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View v, int position) {
                SELECTPOSITION = position;
                Log.e("TAG", "SELECTPOSITION:" + SELECTPOSITION);
                mRecyclerViewMenuCommonadapter.notifyDataSetChanged();
                mRecyclerViewContentCommonadapter.notifyDataSetChanged();
                setAll();
            }
            @Override
            public void onItemLongClick(View v, int position) {}
        });
    }
    /**
     * 商品種類清單    資料填充
     */
    private void setContentCommonadapter() {
        mRecyclerViewContentCommonadapter = new RecyclerViewContentAdapter(mContext, stringContentList);
        mRecyclerContent.setAdapter(mRecyclerViewContentCommonadapter);
        mRecyclerViewContentCommonadapter.setOnItemClickListener(new RecyclerViewContentAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(RecyclerViewContentAdapter.ViewHolder holder) {}
            @Override
            public void onItemLongClick(RecyclerViewContentAdapter.ViewHolder holder) {}
            /** 添加 */
            @Override
            public void onItemJiaClick(RecyclerViewContentAdapter.ViewHolder holder) {
                String numText = holder.mNumber.getText().toString().trim();
                /** 點選加号之前還沒有資料的時候 */
                if (numText.isEmpty() || numText.equals("0")) {
                    Log.e("TAG", "點選擷取資訊:SELECTPOSITION--" + SELECTPOSITION + "  DemoData.ListMenu_GOODSID[position]--" + DemoData.ListMenu_GOODSID[holder.getPosition()]);
                    holder.mImgJian.setVisibility(View.VISIBLE);
                    holder.mNumber.setText(mGoodsDataBaseInterface.saveGoodsNumber(mContext, SELECTPOSITION, DemoData.ListMenu_GOODSID[holder.getPosition()], "1", DemoData.ListMenu_PPRICE[holder.getPosition()]) + "");
                    holder.mNumber.setVisibility(View.VISIBLE);
                }/** 點選加号之前有資料的時候 */
                else {
                    holder.mNumber.setText(mGoodsDataBaseInterface.saveGoodsNumber(mContext, SELECTPOSITION, DemoData.ListMenu_GOODSID[holder.getPosition()], String.valueOf(Integer.parseInt(numText) + ), DemoData.ListMenu_PPRICE[holder.getPosition()]) + "");
                }
                /** 動畫 */
                GoodsAnimUtil.setAnim(MainActivity.this, holder.mImgJia, mCarLay);
                GoodsAnimUtil.setOnEndAnimListener(new onEndAnim());
                /** 統計購物總數和購物總價 */
            }
            /** 減少 */
            @Override
            public void onItemJianClick(RecyclerViewContentAdapter.ViewHolder holder) {
                String numText = holder.mNumber.getText().toString().trim();
                holder.mNumber.setText(mGoodsDataBaseInterface.saveGoodsNumber(mContext, SELECTPOSITION, DemoData.ListMenu_GOODSID[holder.getPosition()], String.valueOf(Integer.parseInt(numText) - ), DemoData.ListMenu_PPRICE[holder.getPosition()]) + "");
                numText = holder.mNumber.getText().toString().trim();
                /** 減完之後  資料為0 */
                if (numText.equals("0")) {
                    holder.mNumber.setVisibility(View.GONE);
                    holder.mImgJian.setVisibility(View.GONE);
                }
                setAll();
            }
        });
    }
    /**
     * 動畫結束後,更新所有數量和所有價格
     */
    class onEndAnim implements GoodsAnimUtil.OnEndAnimListener {
        @Override
        public void onEndAnim() {
            setAll();
        }
    }
    /**
     * 點選加号和減号的時候設定總數和總價格
     */
    private void setAll() {
        //設定所有購物數量
        if (mGoodsDataBaseInterface.getSecondGoodsNumberAll(mContext, SELECTPOSITION) == ) {
            mListAllNum.setVisibility(View.GONE);
            mListAllPrice.setText("¥0");
            mListAllNum.setText("0");
        } else {
            mListAllPrice.setText("¥" + mGoodsDataBaseInterface.getSecondGoodsPriceAll(mContext, SELECTPOSITION) + "");
            mListAllNum.setText(mGoodsDataBaseInterface.getSecondGoodsNumberAll(mContext, SELECTPOSITION) + "");
            mListAllNum.setVisibility(View.VISIBLE);
        }
    }
}
           
由于牽扯到3個知識點,是以邏輯可能有些亂,是以大家可以檢視我編寫的代碼,裡面注釋十分詳細,有意見或者疑問的可以共同商讨。

源碼下載下傳位址

繼續閱讀