Android 上自定義的複式折線圖(二)
轉發請註明出處:http://blog.csdn.net/qq_30552993/article/details/51564048
寫這篇文章主要是對Android 上自定義的複式折線圖(一)進行了一些修改.因為在(一)中出現瞭如下問題:
1.沒有自適應螢幕大小,使得有時候LineView這個控制元件右邊會有多餘的
2.如果沒有資料的時候LineView就不會顯示Y軸的標籤;
修復後的功能:
1.表格中X軸預設有10個單位,如果沒有資料沒有10也是會顯示錶格(這裡的預設10是可以進行設定的)
2.表格中資料超過10個就會進行水平滾動
3.因為預設10個單位的表格的話這樣才可以實現自適應螢幕問題,不過這裡要傳一個這個控制元件的所佔寬度大小
4.同時也去掉之前(一)中的一些方法,就沒有說可以設計表格單位的大小等等一些方法
這裡就先不多說,先附上效果圖:
LineView.java
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import java.util.ArrayList;
@SuppressLint("DrawAllocation")
public class LineView extends View {
private static final String TAG = "LineView";
// 預設邊距
private int Margin = 20;
// 原點座標
private int Xpoint;
private int Ypoint;
// X,Y軸的單位長度,即表格中的正方形的寬高
private int Yscale;
private int Xscale;
//是否顯示錶格
private boolean isShowGrid = false;
//是否展示表格為虛線
private boolean isDottedLine = false;
// X最左邊跟Y左下面的線的顏色
private int XYColor = Color.WHITE;
// X軸字型的顏色
private int XTextColor = Color.WHITE;
// Y軸字型的顏色
private int YTextColor = Color.WHITE;
// 表格字型的顏色
private int GridColor = Color.WHITE;
// 資料字型的顏色
private int DataColor = Color.WHITE;
private int XTextSize = 8;
private int YTextSize = 8;
private int marginLeft = 0;
private int marginBottom = 0;
private Resources r = Resources.getSystem();
// X軸上面的顯示文字
private ArrayList<String> XLabel;
// Y軸上面的顯示文字
private ArrayList<String> YLabel;
// 曲線資料
private ArrayList<ArrayList<Integer>> dataLists;
private ArrayList<Integer> dataColorList;
// 單前資料
private ArrayList<Integer> dataList;
private int color;
private int viewWidth;
private int defXCount = 10;
private int dataCount;
public LineView(Context context) {
super(context);
initSize();
}
public LineView(Context context, AttributeSet attrs) {
super(context, attrs);
initSize();
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (dataLists.size() > 0 && viewWidth > 0) {
Xscale = (viewWidth - this.Margin * 2) / defXCount;
Yscale = Xscale / 2;
if (dataLists.get(0).size() <= defXCount) {
dataCount = defXCount;
} else {
dataCount = dataLists.get(0).size();
}
}
Log.e(TAG, "Xscale:" + Xscale + " ;Yscale:" + Yscale);
setMeasuredDimension(Xscale * dataCount + this.Margin * 2 + marginLeft,
Yscale * YLabel.size() + this.Margin + marginBottom);
}
private void initSize() {
setXTextSize(XTextSize);
setYTextSize(YTextSize);
setMarginLeft(marginLeft);
setMarginBottom(marginBottom);
this.Margin = setDimensionDIP(Margin);
}
// 初始化資料值
public void init() {
Xpoint = this.Margin + marginLeft;
Ypoint = this.getHeight() - this.Margin - marginBottom;
}
@Override
protected void onDraw(Canvas canvas) {
Paint p1 = new Paint();
p1.setStyle(Paint.Style.STROKE);
p1.setAntiAlias(true);
p1.setColor(XYColor);
p1.setStrokeWidth(2);
init();
if (isShowGrid) {
this.drawTable(canvas);
} else {
this.drawXLine(canvas, p1);
this.drawYLine(canvas, p1);
}
if (dataLists != null) {
for (int i = 0; i < dataLists.size(); i++) {
this.drawData(canvas, i);
}
}
}
// 畫表格
private void drawTable(Canvas canvas) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(GridColor);
Path path = new Path();
if (isDottedLine) {
PathEffect effects = new DashPathEffect(new float[]{5, 5, 5, 5}, 1);//畫虛線
paint.setPathEffect(effects);
}
int startX = 0;
int startY = 0;
int stopX = 0;
int stopY = 0;
// 縱向線
for (int i = 0; i <= dataCount; i++) {
startX = Xpoint + i * Xscale;
startY = Ypoint;
stopY = Ypoint - (this.YLabel.size() - 1) * Yscale;
if (i != 0) {
path.moveTo(startX - Xscale / 2, startY);
path.lineTo(startX - Xscale / 2, stopY);
canvas.drawPath(path, paint);
}
path.moveTo(startX, startY);
path.lineTo(startX, stopY);
canvas.drawPath(path, paint);
}
// 橫向線
for (int i = 0; i < YLabel.size(); i++) {
startX = Xpoint;
startY = Ypoint - i * Yscale;
stopX = Xpoint + (dataCount) * Xscale;
path.moveTo(startX, startY);
path.lineTo(stopX, startY);
paint.setColor(GridColor);
canvas.drawPath(path, paint);
}
Log.e(TAG, "defXCount :" + defXCount);
}
//畫縱軸
private void drawXLine(Canvas canvas, Paint p) {
p.setColor(XYColor);
float stopX = Xpoint;
float stopY = Ypoint - Yscale * (YLabel.size() - 1);
canvas.drawLine(Xpoint, Ypoint, stopX, stopY, p);
// Y軸最後是否有箭頭
canvas.drawLine(stopX, stopY, stopX - Xscale / 6, stopY + Yscale / 3, p);
canvas.drawLine(stopX, stopY, stopX + Xscale / 6, stopY + Yscale / 3, p);
}
// 畫橫軸
private void drawYLine(Canvas canvas, Paint p) {
p.setColor(XYColor);
float stopX = Xpoint + Xscale * dataCount;
float stopY = Ypoint;
canvas.drawLine(Xpoint, Ypoint, stopX, stopY, p);
// X軸最後是否有箭頭
canvas.drawLine(stopX, stopY, stopX - Xscale / 6, stopY - Yscale / 3, p);
canvas.drawLine(stopX, stopY, stopX - Xscale / 6, stopY + Yscale / 3, p);
}
// 畫資料
private void drawData(Canvas canvas, int pos) {
dataList = dataLists.get(pos);
color = dataColorList.get(pos);
Paint p = new Paint();
p.setAntiAlias(true);
// 縱軸資料
for (int i = 0; i < YLabel.size(); i++) {
int startY = Ypoint - i * Yscale;
p.setColor(YTextColor);
p.setTextSize(XTextSize);
p.setTextAlign(Paint.Align.RIGHT);
canvas.drawText(this.YLabel.get(i), this.Margin / 4 * 3 + marginLeft,
startY + this.Margin / 4, p);
}
//橫軸資料
for (int i = 0; i < dataCount; i++) {
int startX = Xpoint + i * Xscale;
p.setColor(XTextColor);
p.setTextSize(YTextSize);
p.setTextAlign(Paint.Align.CENTER);
String text = "";
if (i < XLabel.size()) {
text = this.XLabel.get(i);
}
canvas.drawText(text, startX + Xscale / 2,
this.getHeight() - this.Margin / 2 - marginBottom, p);
p.setColor(dataColorList.size() > 0 ? color : DataColor);
if (i < XLabel.size()) {
canvas.drawCircle(startX + Xscale / 2, calY(dataList.get(i)), 4, p);
}
if (i < XLabel.size() - 1) {
canvas.drawLine(startX + Xscale / 2, calY(dataList.get(i)),
Xpoint + (i + 1) * Xscale + Xscale / 2,
calY(dataList.get(i + 1)), p);
}
}
}
/**
* @param y
* @return
*/
private int calY(int y) {
int y0 = 0;
int y1 = 0;
// Log.i("zzzz", "y:"+y);
try {
y0 = Integer.parseInt(YLabel.get(0));
// Log.i("zzzz", "y0"+y0);
y1 = Integer.parseInt(YLabel.get(1));
// Log.i("zzzz","y1"+y1);
} catch (Exception e) {
// Log.i("zzzz", "string changed is err");
return 0;
}
try {
// Log.i("zzzz", "返回資料"+(Ypoint-(y-y0)*Yscale/(y1-y0)) );
return Ypoint - ((y - y0) * Yscale / (y1 - y0));
} catch (Exception e) {
// Log.i("zzzz", "return is err");
return 0;
}
}
public void setXYColor(int XYColor) {
this.XYColor = XYColor;
}
public void setXTextColor(int XTextColor) {
this.XTextColor = XTextColor;
}
public void setYTextColor(int YTextColor) {
this.YTextColor = YTextColor;
}
public void setGridColor(int gridColor) {
this.GridColor = gridColor;
}
public void setDataColor(int dataColor) {
this.DataColor = dataColor;
}
public void setDataColorList(ArrayList<Integer> dataColorList) {
this.dataColorList = dataColorList;
}
public void setXTextSize(int XTextSize) {
this.XTextSize = setDimensionSP(XTextSize);
}
public void setYTextSize(int YTextSize) {
this.YTextSize = setDimensionSP(YTextSize);
}
public void setMarginLeft(int marginLeft) {
this.marginLeft = setDimensionDIP(marginLeft);
}
public void setMarginBottom(int marginBottom) {
this.marginBottom = setDimensionDIP(marginBottom);
}
public void setDefXCount(int defXCount) {
this.defXCount = defXCount;
}
public void setShowGrid(boolean isShowGrid) {
this.isShowGrid = isShowGrid;
}
public void setDottedLine(boolean isDottedLine) {
this.isDottedLine = isDottedLine;
}
public void setXYLabel(ArrayList<String> xlabel, ArrayList<String> ylabel,
int viewWidth) {
this.XLabel = xlabel;
this.YLabel = ylabel;
this.viewWidth = viewWidth;
}
public void setDataList(ArrayList<ArrayList<Integer>> dataLists) {
this.dataLists = dataLists;
postInvalidate();
}
private int setDimensionDIP(int size) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size,
r.getDisplayMetrics());
}
private int setDimensionSP(int size) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, size,
r.getDisplayMetrics());
}
}
這裡先來一個列子,說明怎麼使用LineView
MainActivity.java
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import java.util.ArrayList;
public class MainActivity extends Activity {
private LinearLayout mLineLL;
private LineView mSkinLineView;
private ArrayList<Integer> colorList = new ArrayList<>();//折線的顏色列表
private ArrayList<String> XLabel = new ArrayList<>(); //X軸上的標籤資料列表
private ArrayList<String> YLabel = new ArrayList<>(); //Y軸上的標籤資料列表
private ArrayList<ArrayList<Integer>> dataLists;//折線上的資料列表
private int width;
private int height;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
colorList.add(getResources().getColor(R.color.using_before));
colorList.add(getResources().getColor(R.color.using_after));
for (int i = 0; i < 0; i++) {
XLabel.add(String.valueOf(i));
}
for (int i = 0; i < 11; i++) {
YLabel.add(String.valueOf(i * 10));
}
mLineLL = (LinearLayout) findViewById(R.id.LineLL);
mSkinLineView = (LineView) findViewById(R.id.skinLineView);
mSkinLineView.setDataColorList(colorList);
mSkinLineView.setXYLabel(XLabel, YLabel, getLineViewWidth());
mSkinLineView.setShowGrid(true);
mSkinLineView.setDottedLine(true);
mSkinLineView.setGridColor(Color.LTGRAY);
randSet(mSkinLineView);
findViewById(R.id.resetBtn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
randSet(mSkinLineView);
}
});
}
private void randSet(LineView lineView) {
ArrayList<ArrayList<Integer>> dataLists = new ArrayList<>();
ArrayList<Integer> dataList1 = new ArrayList<Integer>();
int random1 = (int) (Math.random() * 99 + 1);
for (int i = 0; i < XLabel.size(); i++) {
dataList1.add((int) (Math.random() * random1));
}
ArrayList<Integer> dataList2 = new ArrayList<Integer>();
int random2 = (int) (Math.random() * 99 + 1);
for (int i = 0; i < XLabel.size(); i++) {
dataList2.add((int) (Math.random() * random2));
}
dataLists.add(dataList1);
dataLists.add(dataList2);
lineView.setDataList(dataLists);
}
private int getLineViewWidth() {
width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();
FrameLayout.LayoutParams params
= (FrameLayout.LayoutParams) mLineLL.getLayoutParams();
int LineViewWidth = width - params.leftMargin - params.rightMargin;
return LineViewWidth;
}
}
佈局檔案activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099FF"
android:id="@+id/LineLL"
android:orientation="vertical">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<sl.myapplication.LineView
android:id="@+id/skinLineView"
android:layout_width="match_parent"
android:layout_height="200dip" />
</LinearLayout>
</HorizontalScrollView>
<Button
android:id="@+id/resetBtn"
android:text="重新整理"
android:textColor="@color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
相關文章
- Android 上自定義的複式折線圖(一)Android
- 自定義View:畫布實現自定義View(折線圖的實現)View
- Flutter自定義折線圖並新增點選事件Flutter事件
- 自定義View之顏色漸變折線圖View
- Android開發自定義控制元件實現一個折線圖Android控制元件
- 自定義控制元件之kotlin繪製折線圖和曲線圖控制元件Kotlin
- Android之自定義控制元件實現天氣溫度折線圖和餅狀圖Android控制元件
- excel折線圖自定x軸y軸 excel折線圖xy設定Excel
- Android 折線圖的實現Android
- 第十七篇:複製控制( 上 ) --- 自定義複製函式函式
- 【詳解】純 React Native 程式碼自定義折線圖元件 (譯)React Native元件
- 【Android自定義View】繪圖之Path篇(二)AndroidView繪圖
- android自定義View&自定義ViewGroup(上)AndroidView
- 自定義餅狀圖(二)
- 自定義條柱圖(二)
- Android自定義ImageView 在圖片上新增一個圖層AndroidView
- Android自定義View:View(二)AndroidView
- Android 折線圖之hellocharts (餅狀圖)餅圖Android
- android中自定義屬性重複定義Android
- android自定義button樣式Android
- 自定義上傳圖片拼圖遊戲遊戲
- (Android自定義控制元件)Android自定義狀態提示圖表Android控制元件
- 微信小程式折線圖表折線圖加區域圖微信小程式
- R : 折線圖
- Flex SDK 4(Gumbo)更方便的自定義樣式、自定義SparkSkin(二)薦FlexSpark
- 如何使用Android自定義複合檢視Android
- Android 自定義 地圖 室內Android地圖
- Android 自定義帶動畫的柱狀圖Android動畫
- Android 自定義貝塞爾曲線工具Android
- Android開發之自定義View(二)AndroidView
- Android自定義View,畫一個好看帶延長線的餅狀圖AndroidView
- echarts 折線圖拼接Echarts
- Label--自定義可貼上複製的Label
- Android 自定義 View 繪圖基礎AndroidView繪圖
- Android 自定義一個輪播圖Android
- android 自定義帶動畫的統計餅圖Android動畫
- excel折線圖自定x軸y軸 excel做xy軸座標圖Excel
- Typora中自定義命令上傳圖片