----------目錄一步一步教你寫(xiě)股票走勢(shì)圖——分時(shí)圖一(概述)一步一步教你寫(xiě)股票走勢(shì)圖——分時(shí)圖二(自定義xy軸)一步一步教你寫(xiě)股票走勢(shì)圖——分時(shí)圖三(對(duì)齊圖表、自定義柱狀圖高亮)一步一步教你寫(xiě)股票走勢(shì)圖——分時(shí)圖四(高亮聯(lián)動(dòng))一步一步教你寫(xiě)股票走勢(shì)圖——分時(shí)圖五(自定義標(biāo)記)----------demo更新地址https://github.com/AndroidJiang/StockChart----------分時(shí)圖開(kāi)發(fā)到現(xiàn)在涛救,基本已經(jīng)完成了,這部分開(kāi)發(fā)完弹沽,就會(huì)開(kāi)始著手k線(xiàn)圖部分的開(kāi)發(fā)。于是我們做了最后的對(duì)比,看下還有什么地方需要增加修改,最后發(fā)現(xiàn)咨察,還有標(biāo)記視圖沒(méi)有,先看下什么是標(biāo)記視圖(博主不知道這個(gè)名字叫啥福青,自己起的):
public abstract class MarkerView extends RelativeLayout { /** * Constructor. Sets up the MarkerView with a custom layout resource. * * @param context * @param layoutResource the layout resource to use for the MarkerView */ public MarkerView(Context context, int layoutResource) { super(context); setupLayoutResource(layoutResource); } /** * Sets the layout resource for a custom MarkerView. * * @param layoutResource */ private void setupLayoutResource(int layoutResource) { View inflated = LayoutInflater.from(getContext()).inflate(layoutResource, this); inflated.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); inflated.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); // measure(getWidth(), getHeight()); inflated.layout(0, 0, inflated.getMeasuredWidth(), inflated.getMeasuredHeight()); } /** * Draws the MarkerView on the given position on the screen with the given Canvas object. * * @param canvas * @param posx * @param posy */ public void draw(Canvas canvas, float posx, float posy) { // take offsets into consideration posx += getXOffset(posx); posy += getYOffset(posy); // translate to the correct position and draw canvas.translate(posx, posy); draw(canvas); canvas.translate(-posx, -posy); } /** * This method enables a specified custom MarkerView to update it's content everytime the MarkerView is redrawn. * * @param e The Entry the MarkerView belongs to. This can also be any subclass of Entry, like BarEntry or * CandleEntry, simply cast it at runtime. * @param highlight the highlight object contains information about the highlighted value such as it's dataset-index, the * selected range or stack-index (only stacked bar entries). */ public abstract void refreshContent(Entry e, Highlight highlight); /** * Use this to return the desired offset you wish the MarkerView to have on the x-axis. By returning -(getWidth() / * 2) you will center the MarkerView horizontally. * * @param xpos the position on the x-axis in pixels where the marker is drawn * @return */ public abstract int getXOffset(float xpos); /** * Use this to return the desired position offset you wish the MarkerView to have on the y-axis. By returning * -getHeight() you will cause the MarkerView to be above the selected value. * * @param ypos the position on the y-axis in pixels where the marker is drawn * @return */ public abstract int getYOffset(float ypos);}
構(gòu)造函數(shù)中要傳入顯示的布局文件,draw會(huì)根據(jù)傳入的position定位碴里,refreshContent更新里面的文本沈矿。源碼讀起來(lái)很簡(jiǎn)單,只有幾個(gè)方法而已咬腋,我們?cè)趯?shí)例的時(shí)候只需傳入我們的布局即可羹膳,于是我們模仿了一個(gè)寫(xiě)法:public class MyMarkerView extends MarkerView { private TextView markerTv; public MyMarkerView(Context context, int layoutResource) { super(context, layoutResource); markerTv = (TextView) findViewById(R.id.marker_tv); } @Override public void refreshContent(Entry e, Highlight highlight) { } @Override public int getXOffset(float xpos) { return 0; } @Override public int getYOffset(float ypos) { return 0; }}…… private void setMarkerView(){ MyMarkerView myMarkerView = new MyMarkerView(MinutesActivity.this, R.layout.mymarkerview); lineChart.setMarkerView(myMarkerView); }
最后圖表進(jìn)行設(shè)置markerview,我們看下效果圖:public void setHighlightValue(Entry e, Highlight h) { this.e = e; if (mData == null) mIndicesToHighlight = null; else { mIndicesToHighlight = new Highlight[]{ h}; } invalidate(); } @Override protected void drawMarkers(Canvas canvas) { if (mIndicesToHighlight != null && myMarkerViewLeft != null && myMarkerViewRight != null) { for (int i = 0; i < mIndicesToHighlight.length; i++) { Entry e = this.e; if (e == null || e.getXIndex() != mIndicesToHighlight[i].getXIndex()) continue; e=mData.getEntryForHighlight(mIndicesToHighlight[i]); float[] pos = getMarkerPosition(e, mIndicesToHighlight[i]); Log.e("!!!!",pos[0]+","+pos[1]); myMarkerViewLeft.draw(canvas, mViewPortHandler.contentLeft() - myMarkerViewLeft.getWidth(), pos[1] - myMarkerViewLeft.getHeight() / 2); myMarkerViewRight.draw(canvas, mViewPortHandler.contentRight(), pos[1] - myMarkerViewRight.getHeight() / 2); float yValForXIndex1 = minuteHelper.getDatas().get(mIndicesToHighlight[i].getXIndex()).chengjiaojia; float yValForXIndex2 = minuteHelper.getDatas().get(mIndicesToHighlight[i].getXIndex()).percentage; myMarkerViewLeft.setData(yValForXIndex1); myMarkerViewRight.setData(yValForXIndex2); myMarkerViewLeft.refreshContent(e, mIndicesToHighlight[i]); myMarkerViewRight.refreshContent(e, mIndicesToHighlight[i]); /*重新計(jì)算大小*/ myMarkerViewLeft.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); myMarkerViewLeft.layout(0, 0, myMarkerViewLeft.getMeasuredWidth(), myMarkerViewLeft.getMeasuredHeight()); myMarkerViewRight.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); myMarkerViewRight.layout(0, 0, myMarkerViewRight.getMeasuredWidth(), myMarkerViewRight.getMeasuredHeight()); } } }
然后在activity中private void setMarkerView(MinuteHelper mData){ MyLeftMarkerView leftMarkerView = new MyLeftMarkerView(MinutesActivity.this, R.layout.mymarkerview); MyRightMarkerView rightMarkerView = new MyRightMarkerView(MinutesActivity.this, R.layout.mymarkerview); lineChart.setMarker(leftMarkerView, rightMarkerView, mData); }
同時(shí)圖表的選中也得進(jìn)行修改傳入?yún)?shù)lineChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() { @Override public void onValueSelected(Entry e, int dataSetIndex, Highlight h) { barChart.highlightValues(new Highlight[]{h}); lineChart.setHighlightValue(e,h); } @Override public void onNothingSelected() { } }); barChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() { @Override public void onValueSelected(Entry e, int dataSetIndex, Highlight h) { // barChart.highlightValues(new Highlight[]{h}); lineChart.setHighlightValue(e, new Highlight(h.getXIndex(),0));//此函數(shù)已經(jīng)返回highlightBValues的變量,并且刷新九巡,故上面方法可以注釋 // barChart.setHighlightValue(h); } @Override public void onNothingSelected() { } });
看得比較亂的同學(xué)图贸,可以直接查看demo代碼,這里只是簡(jiǎn)單的放出代碼而已冕广,邏輯上估計(jì)還有點(diǎn)亂疏日。博主不得不承認(rèn),在處理自定義標(biāo)記的部分代碼寫(xiě)的有點(diǎn)渣撒汉,中間碰到很多坑沟优,最后也是碰巧實(shí)現(xiàn)了效果,博主很納悶睬辐,為啥要從activity中傳入Entry的參數(shù)才行挠阁,而在MyLineChart中直接引用系統(tǒng)的Entry和mData卻行不通宾肺,希望哪位大神研究后能給出答案,或者在處理自定義標(biāo)記這邊有更好見(jiàn)解的歡迎留言或者聯(lián)系我侵俗。下面我們看下效果圖吧(考慮到是仿照自選股app锨用,所以顏色上也基本參考了它):