最近在開發(fā)時遇到這樣一種需求两残,為一些特殊點(diǎn)顯示標(biāo)簽忌栅,類似默認(rèn)顯示多個markview。如下圖(demo):
image
在網(wǎng)上并沒有相關(guān)資料,在此做下記錄分享
下面上代碼:
首先創(chuàng)建一個類繼承LineChart,重寫init()方法:
@Override
protected void init() {
super.init();
//獲取屏幕寬度,上圖最邊上標(biāo)簽跳仿,會根據(jù)屏幕寬度適配
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
mRenderer = new HbFundLineChartRenderer(this, mAnimator, mViewPortHandler, metrics.widthPixels);
}
接下來是主要內(nèi)容,也就是自己實(shí)現(xiàn)的LineChartRenderer即渲染器,用來畫點(diǎn)捐晶、線等.
首先是一些變量,分別是標(biāo)記控件的寬高邊距等,這里寫的是一些根據(jù)我們需求來的默認(rèn)值:
private int mWidth;//屏幕寬度,在構(gòu)造方法中傳進(jìn)來賦值
private float hViewLength = Utils.convertDpToPixel(30f);//vie寬30dp
private float vViewLength = Utils.convertDpToPixel(20f);//view高20dp
private float viewRect= Utils.convertDpToPixel(4f);//矩形高低差
然后,在LineChartRenderer中有一個drawValues,它是主要負(fù)責(zé)根據(jù)值來畫點(diǎn)的,我們要做的就是在super()之后加上我們自己的東西:
@Override
public void drawValues(Canvas c) {
super.drawValues(c);
if (isShowLabel) {
LineDataSet dataSetByIndex = (LineDataSet) mChart.getLineData().getDataSetByIndex(0);
Transformer trans = mChart.getTransformer(dataSetByIndex.getAxisDependency());
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//抗鋸齒畫筆
paint.setTextSize(Utils.convertDpToPixel(textSixe));//設(shè)置字體大小
//畫首中尾三個label
float[] firstFloat = getFloat(dataSetByIndex.getValues(), 0);//根據(jù)數(shù)據(jù)集獲取點(diǎn)
drawPointLabel(trans, paint, c, firstFloat);
float[] middleFloat = getFloat(dataSetByIndex.getValues(), (dataSetByIndex.getValues().size() - 1) / 2);
drawPointLabel(trans, paint, c, middleFloat);
float[] endFloat = getFloat(dataSetByIndex.getValues(), dataSetByIndex.getValues().size() - 1);
drawPointLabel(trans, paint, c, endFloat);
}
}
首先獲取點(diǎn)的數(shù)據(jù)集,然后得到Transformer,它可以根據(jù)點(diǎn)數(shù)據(jù)集里的某一點(diǎn)來得到這個點(diǎn)在屏幕中的位置
然后分別傳入transformer惑灵、畫筆、畫布對象佩憾、點(diǎn),進(jìn)行繪制:
private void drawPointLabel(Transformer trans, Paint paint, Canvas c, float[] floatPosition) {
MPPointD maxPoint = trans.getPixelForValues(floatPosition[0], floatPosition[1]);
float highX = (float) maxPoint.x;
float highY = (float) maxPoint.y;
TextView view = (TextView) LayoutInflater.from(mContext).inflate(R.layout.mark_view, null, false);
if (highX > mWidth - mWidth / 4) {//標(biāo)識朝左
view.setBackgroundResource(R.mipmap.sm_lable_bg_buy_r);
Bitmap bitmap = createBitmap(view, (int) hViewLength, (int) vViewLength);
c.drawBitmap(bitmap, (int) (highX - hViewLength), (int) (highY - vViewLength - viewRect), paint);
} else if (highX < mWidth / 4) {//標(biāo)識朝右
view.setBackgroundResource(R.mipmap.sm_lable_bg_buy_l);
Bitmap bitmap = createBitmap(view, (int) hViewLength, (int) vViewLength);
c.drawBitmap(bitmap, (int) (highX), (int) (highY - vViewLength - viewRect), paint);
} else {//標(biāo)識居中
view.setBackgroundResource(R.mipmap.sm_lable_bg_buy_c);
Bitmap bitmap = createBitmap(view, (int) hViewLength, (int) vViewLength);
c.drawBitmap(bitmap, (int) (highX - hViewLength / 2), (int) (highY - vViewLength - viewRect), paint);
}
}
此處鸯屿,我們隨意定義幾個點(diǎn),可以根據(jù)實(shí)際需求進(jìn)行設(shè)置:
private float[] getFloat(List<Entry> lists, int index) {
float[] maxEntry = new float[2];
maxEntry[0] = lists.get(index).getX();
maxEntry[1] = lists.get(index).getY();
return maxEntry;
}
view轉(zhuǎn)bitmap方法如下:
private Bitmap createBitmap(View v, int width, int height) {
//測量使得view指定大小
int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
v.measure(measuredWidth, measuredHeight);
//調(diào)用layout方法布局后谅辣,可以得到view的尺寸大小
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap bmp = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
v.draw(c);
return bmp;
}
最后附上原文鏈接及代碼