安卓横向柱状图,逻辑与实现,第一版——AS源码!

16 篇文章 3 订阅

安卓横向柱状图,逻辑与实现

网上有很多图标的开源工程。实现图表类型也是丰富多样,如:线图、柱形图、饼图、散点图、仪表图、雷达图、热力图、混合图等。
点击跳转到第二版
https://blog.csdn.net/yu1441/article/details/81129430


然而一般的柱状图却并不适合在手机上面展示数据。毕竟手机屏幕就那么大,而且大部分功能性APP都是竖着用。列一旦多了,后面就显示不下,如果把行距缩小,那么底部文字又显示不下。为了适应手机屏幕,横向柱状图才是最实用,解决了很多不能完全显示问题。但是好几个主流的chart并没有横向柱状图。为什么没有?估计是因为太简单了,别人都不想做成控件。


点击下载源码
点击跳转到第二版

首先来看看demo效果
图片1图片1
图片1图片2

GIF动画:
GIF

首先在activity的xml放入:

   <LinearLayout
            android:id="@+id/linearlayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:orientation="vertical">
     </LinearLayout>

然后是柱状图部分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:gravity="center_vertical"
    android:orientation="horizontal"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"
    >

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


        <TextView
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:singleLine="true"
            android:ellipsize="end"
            android:text="name" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/bar_container"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="3.2"
        android:gravity="left|center_vertical"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/bar"
            android:layout_width="wrap_content"
            android:layout_height="20dp"
            android:background="#0CD3F4" />

        <TextView
            android:id="@+id/percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="10dp"
            android:text="0%"
            android:textColor="#0CD3F4" />
    </LinearLayout>

</LinearLayout>

activity中关键代码:

  private void showColumnar() {
        linearlayout.removeAllViews();
        //赋值
        for (int i = 0; i < 30; i++) {
            //随机产生一个进度
            final double ranNum = Math.random() * 100;
            //设置最大值
            final double finalMaxScale = 100;

            final View item = LayoutInflater.from(this).inflate(R.layout.columnar_item, linearlayout, false);
            final TextView name = item.findViewById(R.id.name);
            final TextView percent = item.findViewById(R.id.percent);
            final View bar = item.findViewById(R.id.bar);
            final LinearLayout container = item.findViewById(R.id.bar_container);

            name.setText("测试数据" + i);
            bar.setBackgroundColor(Color.parseColor("#3FA0FF"));
            percent.setText(format.format(ranNum) + "%");
            percent.setTextColor(Color.parseColor("#3FA0FF"));

            item.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    item.getViewTreeObserver().removeOnPreDrawListener(this);
                    //计算出进度条可用宽度(进度条到最后屏幕的宽度-后面显示%的宽度)
                    final int initWidth = container.getWidth() - percent.getWidth();
                    //计算出进度条应该显示的宽度
                    final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) bar.getLayoutParams();
                    lp.width = (int) (initWidth * ranNum / finalMaxScale);
                    bar.setLayoutParams(lp);
                    //定时器
                    item.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            //获取bar应该显示宽度
                            final int initWidth = bar.getWidth();
                            //设置动画,1.5秒内从0.0宽度变成1.0宽度(1.0代表100%)
                            final ObjectAnimator anim = ObjectAnimator.ofFloat(bar, "alpha", 0.0F, 1.0F).setDuration(1500);
                            //动画监听
                            anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                                @Override
                                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                                    //事实计算宽度,应该显示的宽度乘以当前进度,再事实设置给bar
                                    float cVal = (Float) anim.getAnimatedValue();
                                    lp.width = (int) (initWidth * cVal);
                                    bar.setLayoutParams(lp);
                                }
                            });
                            //动画开始
                            anim.start();
                        }
                    }, 0);
                    return false;
                }
            });
            //设置隔断并添加隔断到linearlayout
            TextView textView = new TextView(this);
            textView.setHeight(dip2px(10));
            linearlayout.addView(textView);
            //添加item到添加隔断到linearlayout
            linearlayout.addView(item);
        }
    }

点击下载源码

点击跳转到第二版

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值