RecyclerView+ProgressBar實現簡易圖表

這裏寫圖片描述

這個圖表是根據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;

這樣比例變大了,就不會出現右邊的文字位置顯示不正確的情況的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章