Android 多商品订单评价(类似淘宝)

前几日一商城类项目,有一需求,需要对一份订单的里面几个商品进行分别评价(图片,文字内容,星级);以前都是对一份订单所有商品一起评价,那种简单的多;
后来,承蒙老大细心指导,终于弄出来个看起来还算凑活的,还是先贴一下效果图吧。。。

抖动的有点卡,gif图的问题


图片的相关操作展示.gif
具体评价实现

*上面这张图是订单列表,可以看到有几个商品,要对这几个商品进行分条评价;

*这个gif图是具体的对每一个商品进行上传图片,内容,星级评价操作


好了,下面就来分析一下怎么写出这玩意,先从布局开始

布局很好写,一看就可看出是一个listview,外加一个提交评论的按钮,给listview设置layout_weight属性,固定一下提交按钮的位置。

        android:layout_weight="1"

然后就是listview的item,主要说下上传图片那一块,我添了三个imgview,比较low,做了一些判断,选择图片的控件是单选的,只好一个一个选,这样也好,比较简单清楚。


画了张草图,大家可以看一下,方便理解;


评价示意图.png

着重说一下代码实现:

1,首先,从上个订单页面传过来每个商品的id,图片,图片用于显示,商品id用来判定评价的是哪个商品,id 和图片用两个数组存起来;

//demo中在Mainactivity.java
private List<String> img = new ArrayList<>();
private List<String> ids = new ArrayList<>();

2,要给listview 填充数据,和获得item里面的每条数据,我们就先建一个实体类GoodsAssessBean.java,数据是下面几个,里面有几个方法,列出来(因为这是每条item的数据,所以,拿到相应的东西和方法相对好实现);

private String id;//商品id
private  String icon;//商品图片
private String content ="";//商品评价内容
private ArrayList<String> imgList = new ArrayList<>();//七牛返回的图片url
private ArrayList<Bitmap> bitmapList = new ArrayList<>();//本地的bitmap
private String starts="0";//商品星级评定

 /**
     *      添加或更换图片
     * @param bitmap 本地 bitmap
     * @param index 图片的二级位置 0 或 1 或 2;初始值为0 需要加1与 bitmapList.size()比较
     * @param url 七牛返回的图片地址
     */
    public void addOrSetImage(Bitmap bitmap, int index, String url){
        //如果小于等于证明需要更换图片;
        if(index + 1 <= bitmapList.size()){
            imgList.set(index, url);
            bitmapList.set(index, bitmap);
        }else{
            //大于的话新增图片;
            addBitMap(bitmap);
            save(url);
        }
    }

 /**
     * 添加Bitmap
     * @param bitmap
     */
    public void addBitMap(Bitmap bitmap){
        if(bitmapList.size()<3){
            bitmapList.add(bitmap);
        }
    }

 /**
     *
     * @param url  每个item里面的URL
     */
    public void save(String url){
        imgList.add(url);
    }

    /**
     *  这个方法是把七牛返回的图片地址进行拼接,用“;”隔开
     * @return
     */
    public String getItemUrl(){
        String urls="";
        if(imgList.size() > 0){
            for(int i=0;i<imgList.size();i++){
                urls+= imgList.get(i)+";";
            }
            return urls.substring(0,urls.length()-1);
        }else {
            return " ";
        }

    }

    /**
     *  删除第几张图片
     * @param index 第二层位置
     */
    public void deleteImg(int index){
        if(imgList.size()>index){
            imgList.remove(index);
            bitmapList.remove(index);
        }
    }

    /**
     *    把每个 item(每个商品)的评价内容,星级,图片等转成json格式;
     * @return
     */
    public String toSString(){
        String str = "";
        ReturnBean rb = new ReturnBean();
        rb.setContent(getContent());
        rb.setComment_img(getItemUrl());
        rb.setGoods_num(getStarts());
        rb.setOrdergoods_id(getId());
        try {
            str = JsonUtil.toJsonString(rb);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

    public ReturnBean getReturnBean(){
        ReturnBean rb = new ReturnBean();
        rb.setContent(getContent());
        rb.setComment_img(getItemUrl());
        rb.setGoods_num(getStarts());
        rb.setOrdergoods_id(getId());
        return rb;
    }




3,在自己写一个图片帮助类AssessImgHelp。在这个类里,我们把写一个方法,把拿到的商品id,和商品图片存到实体类里,在这里面也有些方法,列出来。

public ArrayList<GoodsAssessBean> mBeanList = new ArrayList<>();
public AssessImgHelp(List<String> ids,List<String> icon){ 
   for(int i=0;i<ids.size();i++){ 
       mBeanList.add(new GoodsAssessBean(ids.get(i), icon.get(i))); 
   }
}

  public ArrayList<GoodsAssessBean> getBeanList(){
        return mBeanList;
    }·

    /**
     *
     * @param outIndex item的位置 相当于position
     * @param bitmap bitmap用于本地显士
     * @param url  七牛返回地址
     * @param inIndex  图片位置
     */
    public void doQiNiuDone(int outIndex, Bitmap bitmap, String url,int inIndex){
      //哪个item调用GoodsAssessBean.java里的方法,也就是添加更换图片
        mBeanList.get(outIndex).addOrSetImage(BitmapUtils.compressImage(bitmap), inIndex, url);
    }

    //长按删除图片
    public void longDelete(int outIndex,int inIndex){
  //调用GoodsAssessBean.java里的删除方法
        mBeanList.get(outIndex).deleteImg(inIndex);
    }

//生成json串
    public String jsonSString(){
        String str="";
        ArrayList<ReturnBean> beanList = new ArrayList<>();
        for(int i=0; i< getBeanList().size(); i++){
            str += getBeanList().get(i).toSString();
            beanList.add(getBeanList().get(i).getReturnBean());
        }
        Log.e("123", "beanList" + JsonUtil.object2JSON(beanList));
        return JsonUtil.object2JSON(beanList);

    }

4,最后一个帮助类AssessBeanUtils.java;存入list的position和每个item里面图片的位置,贴一下;


    private int outIndex;
    private int inIndex;


    public void setBean(int outIndex,int inIndex){
        this.outIndex = outIndex;
        this.inIndex = inIndex;
    }


    public int getOutIndex() {
        return outIndex;
    }


    public int getInIndex() {
        return inIndex;
    }

5,好的,现在到目前为止,我们所有的数据都能拿的到,还有一些图片的删除,更换,添加等等方法全部准备完毕,剩下的只是在MainActivity中调用即可(demo中的MainActivity),着重看几个地方;

//list之外的星级判定,物流,描述等获取可以用setOnRatingBarChangeListener()方法;
  mRatingBarMiaoshu.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
            @Override
            public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
                miaoshu = rating + "";
            }
        });
  /*
    * 填充数据
    * */
    private void showData() {
        //长按图片抖动效果
        final Animation anim = AnimationUtils.loadAnimation(MainActivity.this, R.anim.myanim);

        mAdapter = new CommonAdapter<GoodsAssessBean>(MainActivity.this, assessImgHelp.getBeanList(), R.layout.item_assess) {
            @Override
            public void convert(ViewHolder helper, final GoodsAssessBean item, final int position) {
                //加载商品图片
                ImageLoad.loadImgDefault(MainActivity.this, (ImageView) helper.getView(R.id.m_assess), item.getIcon());

                //获取商品星级评价
                ((RatingBar) helper.getView(R.id.m_ratingBar_shop)).setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
                    @Override
                    public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
                        item.setStarts(rating + "");
                    }
                });

                //获取评价内容
                ((EditText) helper.getView(R.id.m_assess_edt)).addTextChangedListener(new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                    }

                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {

                    }

                    @Override
                    public void afterTextChanged(Editable s) {
                        item.setContent(s + "");
                    }
                });
                //三个imageView和三个删除按钮
                final ImageView img1 = helper.getView(R.id.m_menmian1_icon);
                final ImageView img2 = helper.getView(R.id.m_menmian2_icon);
                final ImageView img3 = helper.getView(R.id.m_menmian3_icon);
                final ImageView imgclose1 = helper.getView(R.id.m_image_one);
                final ImageView imgclose2 = helper.getView(R.id.m_image_two);
                final ImageView imgclose3 = helper.getView(R.id.m_image_three);
                img1.setScaleType(ImageView.ScaleType.CENTER_CROP);//CENTER_CROP  FIT_XY
                img2.setScaleType(ImageView.ScaleType.CENTER_CROP);//CENTER_CROP  FIT_XY
                img3.setScaleType(ImageView.ScaleType.CENTER_CROP);//CENTER_CROP  FIT_XY
                //获取本地图片数量。分别对应相应的显示
                int size = item.getBitMapListSize();
                if (size == 0) {
                    setImageViewVisibility(img1, true, img2, false, img3, false);
                    img1.setImageResource(R.mipmap.pj_tj);//默认图片
                } else if (size == 1) {
                    setImageViewVisibility(img1, true, img2, true, img3, false);
                    img1.setImageBitmap(item.getBitmapList().get(0));
                    img2.setImageResource(R.mipmap.pj_tj);
                } else if (size == 2) {
                    setImageViewVisibility(img1, true, img2, true, img3, true);
                    img1.setImageBitmap(item.getBitmapList().get(0));
                    img2.setImageBitmap(item.getBitmapList().get(1));
                    img3.setImageResource(R.mipmap.pj_tj);
                } else if (size == 3) {
                    setImageViewVisibility(img1, true, img2, true, img3, true);
                    img1.setImageBitmap(item.getBitmapList().get(0));
                    img2.setImageBitmap(item.getBitmapList().get(1));
                    img3.setImageBitmap(item.getBitmapList().get(2));
                }
              //点击事件
                img1.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Log.e("123", "img: " + img1.getId());
                        mAssessBean.setBean(position, 0);//存储一级二级位置
                        new PopupWindows(MainActivity.this);//弹出选择头像,相册
                    }
                });
                img2.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mAssessBean.setBean(position, 1);
                        new PopupWindows(MainActivity.this);
                    }
                });
                img3.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mAssessBean.setBean(position, 2);
                        new PopupWindows(MainActivity.this);
                    }
                });
                img1.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                      //一些小细节判断,如果第一张没有图片,长按提示请选择图片
                        if (assessImgHelp.getBeanList().get(position).getImgListSize() > 0) {
                            img1.startAnimation(anim);//抖动效果
                            imgclose1.setVisibility(View.VISIBLE);//显示删除按钮
                        } else {
                            toast("请添加图片");
                        }
                        return true;
                    }
                });
                //删除按钮点击事件
                imgclose1.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        assessImgHelp.longDelete(position, 0);//调用删除方法
                        mAdapter.notifyDataSetChanged();
                        imgclose1.setVisibility(View.GONE);
                        toast("删除成功");

                    }
                });
                img2.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        if (assessImgHelp.getBeanList().get(position).getImgListSize() > 1) {
                            img2.startAnimation(anim);
                            imgclose2.setVisibility(View.VISIBLE);
                        } else {
                            toast("请添加图片");
                        }


                        return true;
                    }
                });
                imgclose2.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        assessImgHelp.longDelete(position, 1);
                        mAdapter.notifyDataSetChanged();
                        imgclose2.setVisibility(View.GONE);
                        toast("删除成功");

                    }
                });
                img3.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        if (assessImgHelp.getBeanList().get(position).getImgListSize() > 2) {
                            img3.startAnimation(anim);
                            imgclose3.setVisibility(View.VISIBLE);
                        } else {
                            toast("请添加图片");
                        }


                        return true;
                    }
                });
                imgclose3.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        assessImgHelp.longDelete(position, 2);
                        mAdapter.notifyDataSetChanged();
                        imgclose3.setVisibility(View.GONE);
                        toast("删除成功");

                    }
                });
            }

        };
        mAssessList.setAdapter(mAdapter);
    }
//图片的显示与隐藏
public void setImageViewVisibility(ImageView img1, boolean boo1, ImageView img2, boolean boo2, ImageView img3, boolean boo3) {
        img1.setVisibility(boo1 ? View.VISIBLE : View.GONE);
        img2.setVisibility(boo2 ? View.VISIBLE : View.GONE);
        img3.setVisibility(boo3 ? View.VISIBLE : View.GONE);
    }


后面的就是一些调用相册,相机,选取图片,上传七牛,还有就是6.0权限问题也有判断。
七牛上传成功之后,调这个方法:

//第一个是position,第三个是七牛返回的图片地址,第四个是图片位置;
assessImgHelp.doQiNiuDone(mAssessBean.getOutIndex(), bitmap, key, mAssessBean.getInIndex());

具体看Demo吧,足够详细,绝对能看懂,以上;

https://github.com/WKaKa/Assess

PS:图片提示失败是应为七牛Token接口失效了,需要换成自己项目里的。

2017,5,19.png

拍完照或者选择完图片后,之前填写的星级和内容会刷新掉。解决方法就是弄两个hashMap暂时存一下,只是用来显示。。。。。。

   HashMap<Integer, String> saveMap = new HashMap<Integer, String>();;//这个集合用来存储对应位置上Editext中的文本内容
    HashMap<Integer, Float> saveMapStart = new HashMap<Integer, Float>();;//这个集合用来存储对应位置上评价星级


  ((RatingBar) helper.getView(R.id.m_ratingBar_shop)).setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
                    @Override
                    public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
                        item.setStarts(rating + "");
                        Integer tag= (Integer)  helper.getView(R.id.m_assess_edt).getTag();
                        saveMapStart.put(tag, rating);//在这里根据position去保存文本内容
                    }
                });

                ((EditText) helper.getView(R.id.m_assess_edt)).addTextChangedListener(new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                    }

                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {

                    }

                    @Override
                    public void afterTextChanged(Editable s) {
                        item.setContent(s + "");
                        Integer tag= (Integer)  helper.getView(R.id.m_assess_edt).getTag();
                        saveMap.put(tag, s.toString());//在这里根据position去保存文本内容
                    }
                });

                helper.getView(R.id.m_assess_edt).setTag(position);//设置editext一个标记
                helper.getView(R.id.m_assess_edt).clearFocus();//清除焦点  不清除的话因为item复用的原因   多个Editext同时改变
                ((EditText) helper.getView(R.id.m_assess_edt)).setText(saveMap.get(position));//将对应保存在集合中的文本内容取出来  并显示上去

                helper.getView(R.id.m_ratingBar_shop).setTag(position);//设置editext一个标记
                helper.getView(R.id.m_ratingBar_shop).clearFocus();//清除焦点  不清除的话因为item复用的原因   多个Editext同时改变
                if(saveMapStart.get(position) == null){
                    ((RatingBar) helper.getView(R.id.m_ratingBar_shop)).setRating(0);//将对应保存在集合中的文本内容取出来  并显示上去

                }else {
                    ((RatingBar) helper.getView(R.id.m_ratingBar_shop)).setRating(saveMapStart.get(position));//将对应保存在集合中的文本内容取出来  并显示上去

                }

                                            2017,12,22
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容