使用TextView实现带动画的统计图

运行效果图。

一、前言

最近公司要求做一个支付报表,里面就涉及到一个支付方式的统计。很多人第一时间想到的可能就是Echarts,其实也是可以实现。但是一个简单的条形统计图,思想向后没必要搞得那么复杂吧。不就一个textview带个渐变的背景色吗?行吧,就用textview做吧。

二、正文

1、先把每一个统计方式的布局撸出来xml代码如下

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:paddingVertical="5dp">

    <ImageView
        android:id="@+id/imgType"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:src="@mipmap/hb" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="10dp"
        android:layout_weight="1"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:orientation="horizontal">

            <com.example.myapp.PriceTextView
                android:id="@+id/tv_money"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="¥0.00"
                android:textColor="@color/textColor"
                android:textSize="10sp" />

            <TextView
                android:id="@+id/tv_num"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="40dp"
                android:gravity="center"
                android:text="0笔"
                android:textColor="@color/textColor"
                android:textSize="12sp" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/bar_container"
            android:layout_width="match_parent"
            android:layout_height="15dp"
            android:background="@drawable/gray_10_bg"
            android:orientation="vertical">

            <TextView
                android:id="@+id/bar"
                android:layout_width="wrap_content"
                android:layout_height="15dp"
                android:background="@drawable/columnar_yellow_bg" />

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

2、列表数据填充

package com.example.myapp;

import android.animation.ObjectAnimator;
import android.app.Activity;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.List;


/**
 * 横向柱状图
 * Created by Kwon on 2019/12/5 9:54.
 */
public class ColumnarView {

    private final LinearLayout mLinearLayout;
    private final Activity mActivity;

    public ColumnarView(Activity activity, LinearLayout linearLayout) {
        this.mActivity = activity;
        this.mLinearLayout = linearLayout;
    }

    /**
     * 显示支付方式柱状图(横图)
     */
    public void showPayColumnar() {
        mLinearLayout.removeAllViews();
        /*筛选进度条的最大值*/
        double finalMaxScale = 100;

        for (int i = 0; i < 6; i++) {
            View item = LayoutInflater.from(mActivity).inflate(R.layout.columnar_pay_item, mLinearLayout, false);
            PriceTextView tvMoney = item.findViewById(R.id.tv_money);
            TextView tvNum = item.findViewById(R.id.tv_num);
            ImageView imgType = item.findViewById(R.id.imgType);
            View bar = item.findViewById(R.id.bar);
            LinearLayout barContainer = item.findViewById(R.id.bar_container);
            /*添加item到添加隔断到linearlayout*/
            mLinearLayout.addView(item);

            /*金额*/
            double payAmount = i * 6;

            /*支付方式*/
            String payTypeName = "支付方式";
            /*支付进度条背景色*/
            bar.setBackgroundResource(getPayColor(payTypeName));
            /*支付金额*/
            tvMoney.parsePrice(payAmount).showSymbol(payTypeName + "¥");
            /*支付笔数*/
            String payNum = i + "笔";
            tvNum.setText(payNum);

            item.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    item.getViewTreeObserver().removeOnPreDrawListener(this);
                    /*计算出进度条可用宽度(进度条到最后屏幕的宽度-后面显示%的宽度)*/
                    int initWidth = barContainer.getWidth();
                    /*计算出进度条应该显示的宽度*/
                    LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) bar.getLayoutParams();
                    if (finalMaxScale != 0) {
                        lp.width = (int) (initWidth * payAmount / finalMaxScale);
                    }
                    bar.setLayoutParams(lp);
                    /*定时器*/
                    item.postDelayed(() -> {
                        /*获取bar应该显示宽度*/
                        int barWidth = bar.getWidth();
                        /*设置动画,1.5秒内从0.0宽度变成1.0宽度(1.0代表100%)*/
                        ObjectAnimator anim = ObjectAnimator.ofFloat(bar, "alpha", 0.0F, 1.0F).setDuration(2000);
                        /*动画监听*/
                        anim.addUpdateListener(valueAnimator -> {
                            /*事实计算宽度,应该显示的宽度乘以当前进度,再事实设置给bar*/
                            float cVal = (Float) anim.getAnimatedValue();
                            lp.width = (int) (barWidth * cVal);
                            bar.setLayoutParams(lp);
                        });
                        /*动画开始*/
                        anim.start();
                    }, 0);
                    return false;
                }
            });
        }
    }


    /**
     * 根据支付方式返回对于颜色
     *
     * @param payName
     */
    public static int getPayColor(String payName) {
        switch (payName) {
            case "微信支付":
                return R.drawable.columnar_green_bg;
            case "支付宝":
                return R.drawable.columnar_blue_bg;
            case "刷卡":
                return R.drawable.columnar_red500_bg;
            case "花呗":
                return R.drawable.columnar_blue500_bg;
            case "云闪付":
                return R.drawable.columnar_red_bg;
            default:
                return R.drawable.columnar_yellow_bg;
        }
    }
}

3、在需要的地方调用下就可以了,直接上代码
 

package com.example.myapp;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LinearLayout llyPay = findViewById(R.id.llyPay);

        ColumnarView columnarView = new ColumnarView(MainActivity.this, llyPay);
        columnarView.showPayColumnar();
    }
}

怎么样?是不是超级简单。

三、总结

相对于使用Echarts来说,我觉得使用textview+动画来的更加简单。有不足之处,望各位大神赐教!谢谢。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值