最近做比特幣相關(guān)的行情展示,涉及到這個大量的double類型數(shù)據(jù)的處理。為了顯示整齊好看,同時針對位數(shù)什么的進行限制,以及精度控制。順帶說下,這個曲線圖用的是PhilJay/MPAndroidChart ,蠻強大的。如果是簡單的其實自己也可以開發(fā)的,小白打算后面就自己搞一個demo學(xué)習(xí)下。


誤區(qū):一開始小萌新以為是控制精度(小數(shù)點后幾位),然后進度控制完后如果位數(shù)不足就末尾補0. 然后就發(fā)現(xiàn)如果是0.0000233這些,如果你進行了進度過濾,那么將會得到0,很尷尬。 哈哈。。。
實際上只需要:
1. substring截取從0開始的幾位數(shù)(比如七位)
2. 然后進行位數(shù)不足, 末尾補0的操作
3. 如果獲取的double類型發(fā)現(xiàn)是0.232323233-E6這樣色的,那么就不能直接做字符串截取,會得到0.23232 - 實際上是0.000000232....。 所以這種情況需要BigDecimal進行一個轉(zhuǎn)換才行,然后再做截取
所以粘貼下下相關(guān)代碼處理: formatNum方法小萌新做了改動。
import android.content.Context;
import java.math.BigDecimal;
import java.util.regex.Pattern;
/*
*@Description: 數(shù)字處理工具
*@Author: hl
*@Time: 2018/12/25 17:35
*/
public class NumberFormateTool {
/**
* <pre>
* 數(shù)字格式化顯示
* 小于萬默認(rèn)顯示 大于萬以1.7萬方式顯示最大是9999.9萬
* 大于億以1.1億方式顯示最大沒有限制都是億單位
* </pre>
*
* @param num 格式化的數(shù)字
* @param kBool 是否格式化千,為true,并且num大于999就顯示999+,小于等于999就正常顯示
* @return
*/
public static String formatNum(Context context, String num, Boolean kBool) {
StringBuffer sb = new StringBuffer();
// if (!StringUtils.isNumeric(num))
// return "0";
if (kBool == null)
kBool = false;
BigDecimal b0 = new BigDecimal("1000");
BigDecimal b1 = new BigDecimal("10000");
BigDecimal b2 = new BigDecimal("100000000");
BigDecimal b3 = new BigDecimal(num);
String formatNumStr = "";
String nuit = "";
// 以千為單位處理
if (kBool) {
if (b3.compareTo(b0) == 0 || b3.compareTo(b0) == 1) {
return "999+";
}
return num;
}
// 以萬為單位處理
if (b3.compareTo(b1) == -1) {
sb.append(b3.toString());
} else if ((b3.compareTo(b1) == 0 && b3.compareTo(b1) == 1)
|| b3.compareTo(b2) == -1) {
formatNumStr = b3.divide(b1).toString();
nuit = "萬";
} else if (b3.compareTo(b2) == 0 || b3.compareTo(b2) == 1) {
formatNumStr = b3.divide(b2).toString();
nuit = "億";
}
if (!"".equals(formatNumStr)) {
// int i = formatNumStr.indexOf(".");
// if (i == -1) {
// sb.append(formatNumStr).append(nuit);
// } else {
// i = i + 1;
// String v = formatNumStr.substring(i, i + 1);
// if (!v.equals("0")) {
// sb.append(formatNumStr.substring(0, i + 2)).append(nuit);
// } else {
// sb.append(formatNumStr.substring(0, i + 2)).append(nuit);
// }
// }
if (!formatNumStr.contains(".")) {
sb.append(formatNumStr).append(nuit);
} else {
sb.append(String.format("%.2f", Double.parseDouble(formatNumStr))).append(nuit);
}
}
if (sb.length() == 0)
return "0";
return sb.toString();
}
/**
* 數(shù)字流水號長度不夠補0方法
* @param liuShuiHao
* @return
*/
public static String numLengthFomate(String liuShuiHao, int length) {
String zeroS = liuShuiHao;
for(int i = liuShuiHao.length(); i < length; ++i){
zeroS += "0";
}
return zeroS;
}
/**
* 截取7位顯示
* @param liuShuiHao
* @return
*/
public static String numLengthFomate7(String liuShuiHao) {
String zeroS = liuShuiHao.substring(0, liuShuiHao.length() > 7 ? 7 : liuShuiHao.length());
return zeroS;
}
/*
* 是否為浮點數(shù)?double或float類型。
* @param str 傳入的字符串。
* @return 是浮點數(shù)返回true,否則返回false。
*/
public static boolean isDoubleOrFloat(String str) {
Pattern pattern = Pattern.compile("^[-\\+]?[.\\d]*$");
return pattern.matcher(str).matches();
}
}
處理部分Big處理->截取七位->末尾不足補0:

補充1 :關(guān)于這個萬,億的顯示,主要是沒考慮千的問題,所以小萌新做了修改,因為我不需要這個"999+”的做法,看你想怎么改了咯。如果是萬以下的單位會直接返回該值,然后了, 我會進行這個截取處理:

**補充2 : **關(guān)于MPAndroidChart,我把我效果的部分代碼配置貼以下:
init部分:
///< k線
//chart.setViewPortOffsets(0, 0, 0, 0);
chart.setBackgroundColor(Color.rgb(255, 255, 255));
// no description text
chart.getDescription().setEnabled(false);
//是否顯示邊界
chart.setDrawBorders(true);
chart.setBorderColor(Color.rgb(227, 227, 227));
//是否展示網(wǎng)格線
//chart.setDrawGridBackground(true);
// enable touch gestures
chart.setTouchEnabled(true);
// enable scaling and dragging
chart.setDragEnabled(true);
chart.setScaleEnabled(false);
// if disabled, scaling can be done on x- and y-axis separately
chart.setPinchZoom(false);
//chart.setDrawGridBackground(true);
//chart.setMaxHighlightDistance(300);
XAxis xAxis = chart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
//xAxis.setDrawGridLines(false);
//xAxis.setDrawLabels(true);
// xAxis.setGranularity(1f);
//xAxis.setCenterAxisLabels(true);//設(shè)置標(biāo)簽居中
xAxis.setValueFormatter(new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
return TimeUtils.longToDate((long) value * 1000, "HH:mm");
}
});
// YAxis y = chart.getAxisLeft();
// //y.setTypeface(tfLight);
// //y.setLabelCount(6, false);
// y.setTextColor(R.color.text_gray);
// y.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
// y.setDrawGridLines(true);
// y.setAxisLineColor(Color.RED);
YAxis yAxis = chart.getAxisLeft();
yAxis.setAxisLineColor(Color.rgb(227, 227, 227));
yAxis.setZeroLineColor(Color.rgb(227, 227, 227));
yAxis.setGridColor(Color.rgb(227, 227, 227));
//yAxis.setDrawGridLines(true);
// yAxis.setValueFormatter(new IAxisValueFormatter() {
// @Override
// public String getFormattedValue(float value, AxisBase axis) {
// return "20%";
// }
// });
chart.getAxisRight().setEnabled(false);
chart.getLegend().setEnabled(false);
//setData(45, 100);
chart.animateXY(2000, 2000);
MyMarkerView mv = new MyMarkerView(context, R.layout.custom_marker_view);
mv.setChartView(chart);
chart.setMarker(mv);
///< 控制是否顯示markerview
chart.setDrawMarkers(true);
// don't forget to refresh the drawing
//chart.invalidate();
數(shù)據(jù)填充更新部分:
setData(...)
/**
* 曲線圖繪制邊框和填充顏色
*/
private int edgeColor = Color.parseColor("#1b77f7");
private int fillColor = Color.parseColor("#428EFF");
/**
* 填充K線數(shù)據(jù)
*
* @param coincapPriceBeanList
*/
private void setData(List<MarketKValueDetailBean.CoincapPriceBean> coincapPriceBeanList) {
ArrayList<Entry> values = new ArrayList<>();
for (int i = 0; i < coincapPriceBeanList.size(); i++) {
Entry entry = new Entry((float) coincapPriceBeanList.get(i).getDate(), (float) coincapPriceBeanList.get(i).getPrice());
entry.setData(TimeUtils.longToDateBy1970(coincapPriceBeanList.get(i).getDate(), "yyyy-MM-dd HH:mm:ss"));
values.add(entry);
}
LineDataSet set1;
if (chart.getData() != null &&
chart.getData().getDataSetCount() > 0) {
set1 = (LineDataSet) chart.getData().getDataSetByIndex(0);
///< 控制高亮線顏色
set1.setHighLightColor(edgeColor);
///< 沿邊顏色以
set1.setColor(edgeColor);
///< 填充顏色
set1.setFillColor(fillColor);
set1.setValues(values);
chart.getData().notifyDataChanged();
chart.notifyDataSetChanged();
chart.invalidate();
} else {
// create a dataset and give it a type
set1 = new LineDataSet(values, "DataSet all");
set1.setMode(LineDataSet.Mode.CUBIC_BEZIER);
set1.setCubicIntensity(0.2f);
set1.setDrawFilled(true);
set1.setDrawCircles(false);
set1.setLineWidth(1.8f);
set1.setCircleRadius(4f);
set1.setCircleColor(Color.WHITE);
set1.setHighLightColor(edgeColor);
///< 控制高亮線顯示
set1.setHighlightEnabled(true);
///< 沿邊顏色以
set1.setColor(edgeColor);
///< 填充顏色
set1.setFillColor(fillColor);
set1.setFillAlpha(100);
set1.setDrawHorizontalHighlightIndicator(false);
// set1.setFillFormatter(new IFillFormatter() {
// @Override
// public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
// return chart.getAxisLeft().getAxisMinimum();
// }
// });
// create a data object with the data sets
LineData data = new LineData(set1);
//data.setValueTypeface(tfLight);
data.setValueTextSize(9f);
///< 拐點值是否顯示
data.setDrawValues(false);
// set data
chart.setData(data);
chart.invalidate();
}
}
對應(yīng)實體類粘貼下吧:
import java.util.List;
public class MarketKValueDetailBean {
/**
* intervalType : 4
* error_code : 0
* error_message : succ
* coincap_price : [{"volume_usd":0,"price_btc":1,"coin_label":"bitcoin","available_supply":1500517590,"date":1367174841,"price":135.3,"coin_name":"BTC","volume_coin":0}]
*/
private String intervalType;
private int error_code;
private String error_message;
private List<CoincapPriceBean> coincap_price;
private MarketKValueDetailBean(){}
public String getIntervalType() {
return intervalType;
}
public void setIntervalType(String intervalType) {
this.intervalType = intervalType;
}
public int getError_code() {
return error_code;
}
public void setError_code(int error_code) {
this.error_code = error_code;
}
public String getError_message() {
return error_message;
}
public void setError_message(String error_message) {
this.error_message = error_message;
}
public List<CoincapPriceBean> getCoincap_price() {
return coincap_price;
}
public void setCoincap_price(List<CoincapPriceBean> coincap_price) {
this.coincap_price = coincap_price;
}
@NotProguard
public static class CoincapPriceBean {
/**
* volume_usd : 0
* price_btc : 1
* coin_label : bitcoin
* available_supply : 1500517590
* date : 1367174841
* price : 135.3
* coin_name : BTC
* volume_coin : 0
*/
private int volume_usd;
private int price_btc;
private String coin_label;
private long available_supply;
private long date;
private double price;
private String coin_name;
private int volume_coin;
private CoincapPriceBean(){}
public int getVolume_usd() {
return volume_usd;
}
public void setVolume_usd(int volume_usd) {
this.volume_usd = volume_usd;
}
public int getPrice_btc() {
return price_btc;
}
public void setPrice_btc(int price_btc) {
this.price_btc = price_btc;
}
public String getCoin_label() {
return coin_label;
}
public void setCoin_label(String coin_label) {
this.coin_label = coin_label;
}
public long getAvailable_supply() {
return available_supply;
}
public void setAvailable_supply(long available_supply) {
this.available_supply = available_supply;
}
public long getDate() {
return date;
}
public void setDate(int date) {
this.date = date;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getCoin_name() {
return coin_name;
}
public void setCoin_name(String coin_name) {
this.coin_name = coin_name;
}
public int getVolume_coin() {
return volume_coin;
}
public void setVolume_coin(int volume_coin) {
this.volume_coin = volume_coin;
}
}
}
還有個時間轉(zhuǎn)換的工具
/**
* long時間轉(zhuǎn)字符串
* @param lo
* @param pattern "yyyy-MM-dd HH:mm:ss"
* @return
*/
public static String longToDate(long lo, String pattern){
Date date = new Date(lo);
SimpleDateFormat sd = new SimpleDateFormat(pattern);
return sd.format(date);
}
/**
* long時間轉(zhuǎn)字符串 - 從1970算起
* @param lo
* @param pattern "yyyy-MM-dd HH:mm:ss"
* @return
*/
public static String longToDateBy1970(long lo, String pattern){
Date date = new Date(lo * 1000L);
SimpleDateFormat sd = new SimpleDateFormat(pattern);
return sd.format(date);
}
基本上就可以了呀。過程中還是遇到很多問題,目前算是基本解決了都。。加油。。每次的不同接觸總會有收獲的....