<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                轉載請注明出處:http://write.blog.csdn.net/postedit/50434634 接上篇?[Android 圓形百分比(進度條) 自定義view](http://blog.csdn.net/wingichoy/article/details/50334595) 昨天分手了,不開心,來練練自定義view麻痹自己,畢竟菜鳥只能靠不斷練習提高。#程序員不應該有女朋友# 我們要實現的是一種只有來看趨勢,不需要看具體數值,比較簡約的折線圖。比如下圖這樣的: ![](https://box.kancloud.cn/2016-03-21_56efaea1ada45.jpg) 這個時候,一些比較優秀的第三方圖表庫如:MPChart 就顯得比較臃腫了。所以我們需要自定義一個折線圖。 老規矩,先來看最終的實現效果: ![](https://box.kancloud.cn/2016-03-21_56efaea223261.jpg) 其實這種做的很簡約,大概分三個步驟: 一、畫坐標軸 二、畫點 三、畫線 那么我們開始吧Let's go (Let it go)。 設計一下大概需要的東西。首先把X軸和Y軸的數據存放在兩個String[]里。 具體的點的位置用一個Map<Integer,Integer>來存放. **步驟:** 一、新建一個類,取名為SimpleLineChart繼承View 重寫他的構造方法。這里為了簡便,就不添加自定義屬性了attr.xml。 ~~~ <span style="font-size:18px;"> </span><span style="font-size:12px;"> public SimpleLineChart(Context context) { this(context, null); } public SimpleLineChart(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SimpleLineChart(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }</span> ~~~ 二、測量大小。(繼續偷懶,只支持EXACTLY,AT_MOST直接丟異常) ~~~ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { mWidth = widthSize; }else if(widthMode == MeasureSpec.AT_MOST){ throw new IllegalArgumentException("width must be EXACTLY,you should set like android:width=\"200dp\""); } if (heightMode == MeasureSpec.EXACTLY) { mHeight = heightSize; }else if(widthMeasureSpec == MeasureSpec.AT_MOST){ throw new IllegalArgumentException("height must be EXACTLY,you should set like android:height=\"200dp\""); } setMeasuredDimension(mWidth, mHeight); } ~~~ 三、重點來了,開始draw。首先處理幾種異常情況。當X軸或者Y軸為沒有文字(也就是沒有刻度的時候),拋出異常。 ~~~ if(mXAxis.length==0||mYAxis.length==0){ throw new IllegalArgumentException("X or Y items is null"); } ~~~ 當沒有任何點的數據的時候,顯示字符串提醒用戶沒有數據(實際上是往中心drawText)。? ~~~ ?//畫坐標線的軸 ? ? ? ? Paint axisPaint = new Paint(); ? ? ? ? axisPaint.setTextSize(mYAxisFontSize); ? ? ? ? axisPaint.setColor(Color.parseColor("#3F51B5")); ~~~ ~~~ if (mPointMap == null || mPointMap.size() == 0) { int textLength = (int) axisPaint.measureText(mNoDataMsg); canvas.drawText(mNoDataMsg, mWidth/2 - textLength/2, mHeight/2, axisPaint); } ~~~ 異常情況處理完了,開始上面三個步驟挨個畫,首先來畫個Y軸,計算每個刻度的間隔。他的值應該是mWidth / Y軸文字個數,然后用循環把每個刻度都畫出來。再申請一個數組yPoints,存放每個Y刻度的具體坐標。 ~~~ //畫 Y 軸 //存放每個Y軸的坐標 int[] yPoints = new int[mYAxis.length]; //計算Y軸 每個刻度的間距 int yInterval = (int) ((mHeight - mYAxisFontSize - 2) / (mYAxis.length)); //測量Y軸文字的高度 用來畫第一個數 Paint.FontMetrics fm = axisPaint.getFontMetrics(); int yItemHeight = (int) Math.ceil(fm.descent - fm.ascent); Log.e("wing", mHeight + ""); for (int i = 0; i < mYAxis.length; i++) { canvas.drawText(mYAxis[i], 0, mYAxisFontSize + i * yInterval, axisPaint); yPoints[i] = (int) (mYAxisFontSize + i * yInterval); } ~~~ 我們運行一下,看到了如下效果: ![](https://box.kancloud.cn/2016-03-21_56efaea235e04.jpg) 需要注意的是,這里的坐標需要微調,大家多試一下。同理開始畫X軸: ~~~ //畫 X 軸 //x軸的刻度集合 int[] xPoints = new int[mXAxis.length]; Log.e("wing", xPoints.length + ""); //計算Y軸開始的原點坐標 int xItemX = (int) axisPaint.measureText(mYAxis[1]); //X軸偏移量 int xOffset = 50; //計算x軸 刻度間距 int xInterval = (int) ((mWidth - xOffset) / (mXAxis.length)); //獲取X軸刻度Y坐標 int xItemY = (int) (mYAxisFontSize + mYAxis.length * yInterval); for (int i = 0; i < mXAxis.length; i++) { canvas.drawText(mXAxis[i], i * xInterval + xItemX + xOffset, xItemY, axisPaint); xPoints[i] = (int) (i * xInterval + xItemX + axisPaint.measureText(mXAxis[i]) / 2 + xOffset + 10); // Log.e("wing", xPoints[i] + ""); } ~~~ 注意這里X軸的y坐標就是畫Y軸時候的最下面的文字(最后一個)的坐標,存成了xItemY。 ![](https://box.kancloud.cn/2016-03-21_56efaea249448.jpg) 之后我們來畫點,這里我采用的方法是畫圓。直接drawCircle。從map中取出所有點的對應i,j然后再從兩個數組 xPoints[] yPoints[]取出真實的X,Y坐標,最后畫出來 ~~~ //畫點 Paint pointPaint = new Paint(); pointPaint.setColor(mLineColor); Paint linePaint = new Paint(); linePaint.setColor(mLineColor); linePaint.setAntiAlias(true); //設置線條寬度 linePaint.setStrokeWidth(mStrokeWidth); pointPaint.setStyle(Paint.Style.FILL); for (int i = 0; i < mXAxis.length; i++) { if (mPointMap.get(i) == null) { throw new IllegalArgumentException("PointMap has incomplete data!"); } //畫點 canvas.drawCircle(xPoints[i], yPoints[mPointMap.get(i)], mPointRadius, pointPaint); if (i > 0) {//畫線 canvas.drawLine(xPoints[i - 1], yPoints[mPointMap.get(i - 1)], xPoints[i], yPoints[mPointMap.get(i)], linePaint); } } ~~~ 上面畫完點之后開始畫線drawLine,參數是前一個點的坐標,和后一個點的坐標。挨個畫出來。 ![](https://box.kancloud.cn/2016-03-21_56efaea25d4db.jpg) ??這時候我們的最復雜的繪制就完成了。接下來來加入一點功能:參數的設置。 ~~~ /** * 設置map數據 * @param data */ public void setData(HashMap<Integer,Integer> data){ mPointMap = data; invalidate(); } /** * 設置Y軸文字 * @param yItem */ public void setYItem(String[] yItem){ mYAxis = yItem; } /** * 設置X軸文字 * @param xItem */ public void setXItem(String[] xItem){ mXAxis = xItem; } public void setLineColor(int color){ mLineColor = color; invalidate(); } ~~~ 以上代碼很簡單 我就不多說了。整個View完工,接下來介紹如何使用。 **使用:** ****和普通的View一樣,我們直接在XML布局文件中加入SimpleLineChart,注意不要忘記包名。 ~~~ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context="com.wingsofts.simplelinechart.MainActivity"> <com.wingsofts.simplelinechart.SimpleLineChart android:id="@+id/simpleLineChart" android:layout_width="400dp" android:layout_height="200dp" /> </RelativeLayout> ~~~ 然后在Activity中findviewbyid,給他設置X軸的文字 Y軸的文字 還有數據源 ~~~ public class MainActivity extends AppCompatActivity { private SimpleLineChart mSimpleLineChart; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSimpleLineChart = (SimpleLineChart) findViewById(R.id.simpleLineChart); String[] xItem = {"1","2","3","4","5","6","7"}; String[] yItem = {"10k","20k","30k","40k","50k"}; if(mSimpleLineChart == null) Log.e("wing","null!!!!"); mSimpleLineChart.setXItem(xItem); mSimpleLineChart.setYItem(yItem); HashMap<Integer,Integer> pointMap = new HashMap(); for(int i = 0;i<xItem.length;i++){ pointMap.put(i, (int) (Math.random()*5)); } mSimpleLineChart.setData(pointMap); } } ~~~ 簡單的幾步,就可以得到預覽圖的效果了!是不是很好玩!覺得好的話評論一下,star一下。祭奠我死去的愛情。 項目下載地址(求關注 求星星 ):[點擊打開鏈接](https://github.com/githubwing/SimpleLineChart/) 下一篇來一個比較炫 比較復雜的view 自定義儀表盤 :[時尚自定義儀表盤](http://blog.csdn.net/wingichoy/article/details/50468674)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看