《小曼的账本》开发记录 【3.添加功能,细节优化】

刚跟 “Boss” 展示了当前实现的界面,“Boss”提出了几条小意见,于是立马修改了一下(主要是界面元素摆放问题)。

2018年4月14日 22点01分

开始做显示全部功能。
这个很简单。

  private void initAll() {
        data = DataSupport.findAll(Orders.class);
    }

同时还很贴心的作了一个没有数据时候显示的页面。
通过setEmptyView设置,xml代码就不贴了,就一个textview

adapter.setEmptyView(R.layout.empty_view);

添加功能

添加是一个很重要的功能,同时为了节省小姑娘手动导入的时间,设计了如下方案。

首先小姑娘每天是复制官方发来的Excel表格内容,然后黏贴进自己的表格,那么这个关键的步骤必须留着。
下面是复制内容(举个例子)

2018-04-13  23:26:16    148180575153458589  卓越  1.5 8.94    8.046   6.546   ZhQbirds/中情鸟飞织运动女跑步鞋透气夏季网鞋老北京脚蹬懒人鞋  中国政法        

仔细分析上面的数据依次是 日期/时间/订单号/买家名/红包金额/总佣金/实际佣金/利润/商品名/学校,我们的实体类里面还有是否退款和退款状态两个字段,正好解析这段数据后加上这两个字段就可以构成一个对象(一条数据)。

有了数据解析,我们不如做一个读取剪贴板,可以节省一个黏贴的步骤。
点击添加按钮之后首先监听剪贴板,如果监听到内容解析数据(当然不正确的数据也要解析,展示解析列表后需要 小姑娘点击取消,不过正常时候也不会闲的去搞一些假数据,因为自己用)

2018年4月15日 15点48分

昨天兴高采烈吧我的想法和实现的效果拿给小姑娘看,结果小姑娘来一句可不可以一下子导入所有订单,当然一下导入全部订单的话肯定比导入一个困难,于是改变了一下策略,重新写了一个方法

不过令我担心的事情还是发生了,就是数据解析错误。
一条订单中的各个字段用空格分隔,很自然想到split()方法,但是某些商品名字中间是包含空格的。这就很复杂,并不是每一条数据都能解析出10个字段来,这样就很困难。

一开始是所有订单一起解析,后来与室友讨论了一下,决定一条一条的解析(因为复制后的字符串中间是带有回车的,那么我们索性split("\n")),将一整个字符串分解成一个一个的订单,然后每个订单再处理,这样出错的也只可能是某一个订单。

与室友奋斗到凌晨,00:30.
然后写出了一个简陋的方法。

 @OnClick(R.id.add)
    public void onViewClicked() {
        // 获取系统剪贴板
        ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
        // 获取剪贴板的剪贴数据集
        ClipData clipData = clipboard.getPrimaryClip();

        if (clipData != null && clipData.getItemCount() > 0) {
            // 从数据集中获取(粘贴)第一条文本数据
            CharSequence text = clipData.getItemAt(0).getText();
            showDialog(text);
            //多订单解析
            parseTextMore(text);
        }else{
            Snackbar.make(add,"请复制订单",Snackbar.LENGTH_LONG).show();
        }
    }

    private void showDialog(final CharSequence text) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("文本内容");
        builder.setMessage(text);
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                parseTextMore(text);
            }
        });
        builder.setNegativeButton("取消",null);
        builder.show();
    }

    private void parseTextMore(CharSequence text) {
        String[] orderList = text.toString().split("\n");
        //如果没解析出来的话提示非法数据
        if(orderList.length == 0){
            Snackbar.make(add,"非法数据!",Snackbar.LENGTH_LONG).show();
            return;
        }
        //逐条订单读取
        for(int a = 0; a < orderList.length;a++){
            String order = orderList[a];
            //检查订单是否合法
            if(order.equals("")){
                continue;
            }
            //读取该条订单并按空格分隔
            String[] orderBlock = order.toString().split("\\s+");
            //添加字段
            for(int i = 0 ; i < orderBlock.length; i++){
                Orders orders = new Orders();
                orders.setDate(orderBlock[i++].substring(5));  //日期
                orders.setTime(orderBlock[i++]);  //时间
                orders.setOrderNumber(orderBlock[i++]);  //订单号
                orders.setBuyer(orderBlock[i++]);  //买家
                orders.setAmountOfRedEnvelopes(orderBlock[i++]);  //红包
                orders.setGeneralCommission(orderBlock[i++]);  //总佣金
                orders.setActualCommission(orderBlock[i++]);  //实际佣金
                orders.setProfit(orderBlock[i++]);  //利润
                //判断是否超过10个字段,如果超过,就认为商品名是由多部分组成
                int key = orderBlock.length - 10;
                stringBuilder = new StringBuilder();
                stringBuilder.append(orderBlock[i++]);
                if(key > 0)
                {
                    for (;key > 0;key--)
                    {
                        stringBuilder.append(orderBlock[i++]);
                    }
                }
                orders.setCommodity(stringBuilder.toString());  //商品的特别处理
                
                orders.setCollege(orderBlock[i]);  //学校
                orders.setIsRefund("0");
                orders.setRefundtatus("订单正常");
                orders.save();
                data.add(orders);
                adapter.notifyDataSetChanged();
            }
        }
        Snackbar.make(add,"导入"+orderList.length+"个订单!",Snackbar.LENGTH_LONG).show();
    }

从点击按钮开始,从剪贴板拿到数据,然后弹窗提示检查数据,确认后就进行解析,其中parseTextMore()方法只是简陋的写了一下,后期肯定会优化的。

图片发自App

每一个订单如果退款了需要追回红包,而追回的进度不一样,所以我们item下面有订单状态和退款按钮,现在我们做一个点击退款按钮,订单状态转变的功能。

定义一些常量


public class Contacts {
  public static final String ORDER_NORMAL = "订单正常";
  public static final String ORDER_ING = "红包未追回";
  public static final String ORDER_ED = "红包已追回";
  public static final String ISREFUND = "已退款";
  public static final String UNREFUND = "未退款";
}

然后我们修改适配器代码,包括颜色修改,添加监听器都在适配器里完成,这也是BRVAH这款框架的特色。

 @Override
    protected void convert(BaseViewHolder helper, Orders item) {
       helper.addOnClickListener(R.id.isRefund);
       helper.addOnClickListener(R.id.RefundStatus);
    
     ...//省略的代码..
    
     //设置退款和追回红包的一些状态,包括颜色,点击状态等。
       helper.setText(R.id.RefundStatus,item.getRefundtatus());
        TextView refundStatus = helper.getView(R.id.RefundStatus);
       if(item.getRefundtatus().equals(Contacts.ORDER_ED)){
           refundStatus.setTextColor(mContext.getResources().getColor(R.color.green));
       }
        if(item.getRefundtatus().equals(Contacts.ORDER_ING)){
            refundStatus.setTextColor(mContext.getResources().getColor(R.color.red));
        }
        if(item.getRefundtatus().equals(Contacts.ORDER_NORMAL)){
            refundStatus.setTextColor(mContext.getResources().getColor(R.color.colorAccent));
        }

        helper.setText(R.id.isRefund,item.getIsRefund());
        TextView isRefund = helper.getView(R.id.isRefund);
        if(item.getIsRefund().equals(Contacts.UNREFUND)){
            isRefund.setClickable(true);
            refundStatus.setClickable(false);
        }else{
            isRefund.setClickable(false);
            refundStatus.setClickable(true);
        }
    }

然后我们来看看在界面中如何调用。

   adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
            @Override
            public void onItemChildClick(final BaseQuickAdapter adapter, View view, final int position) {
                if(view == adapter.getViewByPosition(recycleview,position,R.id.isRefund)){
                    button = (Button) view;
                    positionInList = position;
                    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                    builder.setTitle("警告");
                    builder.setMessage("该订单是否退货?本操作不可逆,请谨慎操作");
                    builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //退款(修改数据库的订单状态)
                            Orders orders = DataSupport.find(Orders.class,data.get(positionInList).getId());
                            orders.setRefundtatus(Contacts.ORDER_ING);
                            orders.setIsRefund(Contacts.ISREFUND);
                            orders.save();

                            //刷新列表
                            data.get(positionInList).setRefundtatus(Contacts.ORDER_ING);
                            data.get(positionInList).setIsRefund(Contacts.ISREFUND);
                            adapter.notifyDataSetChanged();
                        }
                    });
                    builder.setNegativeButton("取消",null);
                    builder.show();
                }
                if(view == adapter.getViewByPosition(recycleview,position,R.id.RefundStatus)){
                    button = (Button) view;
                    positionInList = position;
                    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                    builder.setTitle("警告");
                    builder.setMessage("红包是否追回?本操作不可逆,请谨慎操作");
                    builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //退款
                            Orders orders = DataSupport.find(Orders.class,data.get(positionInList).getId());
                            orders.setRefundtatus(Contacts.ORDER_ED);
                            orders.save();

                            //刷新列表
                            data.get(positionInList).setRefundtatus(Contacts.ORDER_ED);
                            adapter.notifyDataSetChanged();
                        }
                    });
                    builder.setNegativeButton("取消",null);
                    builder.show();
                }
            }
        });

可以看到,点击退款或者追红包按钮后都会触发数据库操作然后刷新列表完成更新。

这里做的是不可逆的,小可爱说最好还是可逆的吧,所以我打算做一个长按恢复订单状态,这个后期再说。

做完这个之后我发现fragment_second没有存在的必要了,所以我直接修改了一下fragment_first,增加了这么一个构造方法

 @SuppressLint("ValidFragment")
    public FirstFragment(int flag) {
       this.flag = flag;
    }

通过拿到flag来确定是哪个页面加载的,

 if(flag == 1){
//显示添加按钮
            add.setVisibility(View.VISIBLE);
  //加载全部         
 initAll();
        }else if(flag == 2){
//隐藏添加按钮            
add.setVisibility(View.GONE);
 //退款单 
 initRefund();
        }
  private void initRefund() {
        data = DataSupport.where("isRefund = ?", Contacts.ISREFUND).order("time desc").find(Orders.class);
        getActivity().setTitle("已退款"+"("+data.size()+")");
    }

    private void initAll() {
        data = DataSupport.findAll(Orders.class);
        getActivity().setTitle("全部订单("+DataSupport.count(Orders.class)+")");
    }
图片发自App

退款页面效果。

下面是算账功能。

买糖糖。

你可能感兴趣的:(《小曼的账本》开发记录 【3.添加功能,细节优化】)