美文网首页自定义viewAndroid知识Android技术知识
Android 多商品订单评价(类似淘宝)

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

作者: 咔咔和拉拉 | 来源:发表于2016-10-18 12:31 被阅读3864次
    前几日一商城类项目,有一需求,需要对一份订单的里面几个商品进行分别评价(图片,文字内容,星级);以前都是对一份订单所有商品一起评价,那种简单的多;
    后来,承蒙老大细心指导,终于弄出来个看起来还算凑活的,还是先贴一下效果图吧。。。

    抖动的有点卡,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
    

    相关文章

      网友评论

      • b74cd58c8696:大神 选择图片之后这个页面刷新才能显示图片,但是这个页面刷新就会把之前写的内容还有评分清空,应该怎么处理呢 麻烦解答下 谢谢
        b74cd58c8696:@咔咔和拉拉 不需要回复我了 我已经解决了 谢谢
        b74cd58c8696:@咔咔和拉拉 你好 我看了下你发给我的链接 ,我说的不是调用相机把之前的activity销毁了,我想说的是能不能调用相机之后 不使用 mAdapter.notifyDataSetChanged(); 方法就可以显示图片呢,因为这个方法使用后 之前选择的评分 和评价内容就不见了
        咔咔和拉拉:@武杰123 我也遇到过,有的手机可以有的手机不可以。你看看这篇文章,应该对你有所帮助http://blog.sina.com.cn/s/blog_783ede0301014og5.html
      • ee8b6c70848f:高手,你是怎么把不同商品的图片分类上传到服务器的.像是这种情况,统一提交的话,服务器需要个键来接收文件.然后还需要一个键来判断这评价图片是属于哪个商品的.这就要在外部多嵌套一层map 看了网络框架的源码,实在没找到添加图片的时候可以嵌套的功能.
        咔咔和拉拉:@筱内涵丶 选择图片不是能拿到bitmap 吗, /**
        502 * 图片上传七牛服务器
        503 */
        504 private void qiNiuUpload(final Bitmap bitmap) { };
        是用的七牛的服务器,七牛会给我们返回个地址key,把这个地址传给后台就可以了。多张图片的就是拼的json串,你看下GoodsAssessBean 这个实体类里的toSString();方法就明白了。github上有注释
        a50cf46914d2:@咔咔和拉拉 你传图片,传的是什么?不是表单提交吗,底层就是二进制文件,多层图片嵌套具体要怎么上传?Post提交的哈希集不是应该是这样的吗: Map<String ,Map<String,File>>
        咔咔和拉拉: @逆我心中贼 是这样的,我是给后台传了个拼的json串,里面包括商品id,这个商品的评论内容,和评论的多张图片(每张图片用逗号隔开),就可以了。剩下的就是后台根据每个商品的ID 获取评论的内容了,当然,多张图片的后台根据逗号做判断,分开截取就好了,我们只要传数据就行了
      • lcyop:大神,选择图片提示上传失败
        lcyop:@咔咔和拉拉 这个token是要注册七牛开发者账号,集成SDK获得吗?
        咔咔和拉拉:@cycker 相机崩溃可能是权限问题http://blog.csdn.net/javaandroid730/article/details/53544365,提示图片上传失败是七牛token失效了,你需要换成项目里的获取token接口
        lcyop:华为mate7(Android 6.0)和华为mate8(Android 7.0)都提示图片上传失败,Android 6.0 调用相机崩溃
      • Lee0528:好牛叉的样子。get
      • 巴图鲁:拜读

      本文标题:Android 多商品订单评价(类似淘宝)

      本文链接:https://www.haomeiwen.com/subject/tzbkyttx.html