RecyclerView+ProgressBar实现简易图表

来源:互联网 发布:java中方法的定义 编辑:程序博客网 时间:2024/06/03 21:24

这里写图片描述

这个图表是根据RecyclerView+ProgressBar结合,并根据数据的比例动态设置右边数字的marginLeft,并可以进行分页的图表列表

准备工作:

1、引用

    compile 'cn.finalteam.loadingviewfinal:ultra-pull-to-refresh:1.0.1'    compile 'cn.finalteam.loadingviewfinal:loading-more-view:1.0.1'    compile 'com.zhy:base-rvadapter:3.0.3'    compile 'com.zhy:base-adapter:3.0.3'    compile 'com.jakewharton:butterknife:7.0.1'

2、主activity布局:

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.zx.tourism.ChartActivity">    <cn.finalteam.loadingviewfinal.RecyclerViewFinal        android:id="@+id/rv_list"        android:layout_width="match_parent"        android:descendantFocusability="beforeDescendants"        android:layout_height="match_parent"        android:cacheColorHint="#00000000"        app:loadMoreMode="click|scroll"        app:loadMoreView="cn.finalteam.loadingviewfinal.DefaultLoadMoreView"        app:noLoadMoreHideView="false" /></FrameLayout>

3、listitem_chart.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">    <TextView        android:id="@+id/tv_product_name"        android:layout_marginLeft="15dp"        android:layout_marginRight="5dp"        android:layout_width="60dp"        android:layout_height="wrap_content"        android:ellipsize="end"        android:gravity="center_vertical|left"        android:singleLine="true"        android:textColor="#aaaaaa"        />    <LinearLayout        android:layout_width="0dp"        android:layout_weight="1"        android:gravity="center_vertical"        android:layout_height="wrap_content"        android:orientation="vertical">        <TextView            android:id="@+id/tv_top"            android:layout_width="1px"            android:layout_height="5dp"            android:background="#dddddd" />        <FrameLayout            android:paddingRight="15dp"            android:layout_width="match_parent"            android:layout_height="wrap_content">            <ProgressBar                android:id="@+id/pb_number"                style="?android:attr/progressBarStyleHorizontal"                android:layout_width="match_parent"                android:layout_height="25dp"                android:max="100"                android:progress="40"                android:progressDrawable="@drawable/progressbar_color"                 />            <TextView                android:layout_gravity="center_vertical"                android:id="@+id/tv_boxing_number"                android:textSize="10sp"                android:textColor="#aaaaaa"                android:text="0"                android:layout_marginLeft="5dp"                android:layout_width="wrap_content"                android:layout_height="wrap_content" />        </FrameLayout>        <TextView            android:id="@+id/tv_bottom"            android:layout_width="1px"            android:layout_height="5dp"            android:background="#dddddd" />    </LinearLayout></LinearLayout>

4、Chart.java

package com.zx.tourism;import java.io.Serializable;/** * Created by user on 2017/8/15. */public class Chart implements Serializable {    private String productName;    private int number;    public String getProductName() {        return productName;    }    public void setProductName(String productName) {        this.productName = productName;    }    public int getNumber() {        return number;    }    public void setNumber(int number) {        this.number = number;    }}

5、progressbar_color.xml,控制背景

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android" >    <!-- 背景  gradient是渐变,corners定义的是圆角 -->    <item android:id="@android:id/background">        <shape>            <solid android:color="#ffffff" />        </shape>    </item>    <!-- 第二条进度条颜色 -->    <item android:id="@android:id/secondaryProgress">        <clip>            <shape>                <corners android:radius="10dip" />                <gradient                    android:angle="90.0"                    android:centerColor="@android:color/white"                    android:centerY="0.45"                    android:endColor="@android:color/white"                    android:startColor="@android:color/white" />            </shape>        </clip>    </item>    <!-- 进度条 -->    <item android:id="@android:id/progress">        <clip>            <shape>                <solid android:color="#FF9c24" />            </shape>        </clip>    </item></layer-list>

通过layer-list控制progressBar的背景

准备工作做好了,下面看主Activity的实现

package com.zx.tourism;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.LinearLayoutManager;import android.util.Log;import android.view.Gravity;import android.widget.FrameLayout;import android.widget.ProgressBar;import android.widget.TextView;import com.zhy.adapter.recyclerview.CommonAdapter;import com.zhy.adapter.recyclerview.base.ViewHolder;import java.util.ArrayList;import java.util.List;import java.util.Random;import butterknife.Bind;import butterknife.ButterKnife;import cn.finalteam.loadingviewfinal.RecyclerViewFinal;public class ChartActivity extends AppCompatActivity {    @Bind(R.id.rv_list)    RecyclerViewFinal mRvList;    private CommonAdapter mCommonAdapter;    private List<Chart> mList = new ArrayList<>();    private float mMaxNumber;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_chart);        ButterKnife.bind(this);        initView();        for (int i = 0; i < 10; i++) {            Chart chart = new Chart();            chart.setProductName("产品" + i);            int number = new Random().nextInt(10000);            chart.setNumber(number);            mList.add(chart);        }        doSort();        int firstNumber = mList.get(0).getNumber();        //设置bar的最大值值 = 当前数据最大值 + 它的六分之一        // 以给右边数字提供足够的显示空间        mMaxNumber = firstNumber + firstNumber / 6;    }    //简单冒泡排序    private void doSort() {        for (int i = 0; i < mList.size() - 1; i++) {            for (int j = 0; j < mList.size() - i - 1; j++) {                if (mList.get(j).getNumber() < mList.get(j + 1).getNumber()) {                    //临时保存第一个数                    Chart temp = mList.get(j);                    //第二个数和第一个数换位置                    mList.set(j, mList.get(j + 1));                    mList.set(j + 1, temp);                }            }        }    }    private void initView() {        mRvList.setLayoutManager(new LinearLayoutManager(this));        mCommonAdapter = new CommonAdapter<Chart>(this, R.layout.listitem_chart, mList) {            @Override            protected void convert(final ViewHolder holder, final Chart chart, final int position) {                final ProgressBar pbNumber = holder.getView(R.id.pb_number);                final TextView tvBoxingNumber = holder.getView(R.id.tv_boxing_number);                //设置bar右边的数值,通过post方法的到空间的宽度                pbNumber.post(new Runnable() {                    @Override                    public void run() {                    //转到主线程                        runOnUiThread(new Runnable() {                            @Override                            public void run() {                                int number = Integer.parseInt(chart.getNumber() + "");                                //得到当前值和最大值的比例                                float proportion = number / mMaxNumber;                                //当前ProgressBar的宽度*比例 = 居左边的距离                                int margingLeft = (int) (pbNumber.getWidth() * proportion);                                FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);                                lp.setMargins(margingLeft + 2, 0, 0, 0);                                lp.gravity = Gravity.CENTER_VERTICAL;                                tvBoxingNumber.setLayoutParams(lp);                                holder.setText(R.id.tv_product_name, chart.getProductName());                                holder.setText(R.id.tv_boxing_number, chart.getNumber() + "");                                holder.setProgress(R.id.pb_number, number, (int) mMaxNumber);                            }                        });                    }                });            }        };        mRvList.setAdapter(mCommonAdapter);    }}

以上代码有2个关键点:

关键点1:

设置bar的最大值 = 当前数据最大值 + 它的六分之一
其中,这个六分之一就是给右边数字的宽度

关键点2:

通过View.post() 方法得到当前控件的宽度,根据数值的比例计算marginleft

关键点3:

如果number太小,那么比例就比较小,右边的数据就不够位置显示了
可以把number统一变大(即比例变大),但是右边的值不变

把下面的代码

       //设置bar的最大值值 = 当前数据最大值 + 它的六分之一        // 以给右边数字提供足够的显示空间        mMaxNumber = firstNumber + firstNumber / 6;

换为

mMaxNumber = firstNumber * 100 + (firstNumber * 100) / 6;

把下面的代码:

int number = Integer.parseInt(chart.getNumber() + "");                                //得到当前值和最大值的比例 float proportion = number / mMaxNumber;

换为:

int number = Integer.parseInt(chart.getNumber() + ""); //得到当前值和最大值的比例 number = number * 100; float proportion = number / mMaxNumber;

这样比例变大了,就不会出现右边的文字位置显示不正确的情况的

原创粉丝点击