編輯:關於Android編程
帶觸控的圖表類,後期會把這個功能類,添加到這個框架裡:
效果如下
public class BaseFundChartView extends View implements View.OnTouchListener{ Paint linePaint; Paint textPaint; Paint xyChartPaint; Paint chartLinePaint; Paint chartJianbianPaint; Paint huodongPaint; Paint huodongPaintText; Listpoints; public BaseFundChartView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public BaseFundChartView(Context context) { this(context, null); } public BaseFundChartView(Context context, AttributeSet attrs) { this(context, attrs, 0); } PathEffect effect; Path path; private float getWidthYMax(){ return getWidth()-15; } private void init() { linePaint = new Paint(); textPaint = new Paint(); xyChartPaint = new Paint(); chartLinePaint = new Paint(); chartJianbianPaint = new Paint(); huodongPaint = new Paint(); huodongPaintText = new Paint(); //設置繪制模式為-虛線作為背景線。 effect = new DashPathEffect(new float[] { 6, 6, 6, 6, 6}, 2); //背景虛線路徑. path = new Path(); //只是繪制的XY軸 linePaint.setStyle(Paint.Style.STROKE); // linePaint.setStrokeWidth((float) 0.7); linePaint.setStrokeWidth((float) 1.0); //設置線寬 linePaint.setColor(Color.BLACK); linePaint.setAntiAlias(true);// 鋸齒不顯示 //XY刻度上的字 textPaint.setStyle(Paint.Style.FILL);// 設置非填充 textPaint.setStrokeWidth(1);// 筆寬5像素 textPaint.setColor(Color.BLACK);// 設置為藍筆 textPaint.setAntiAlias(true);// 鋸齒不顯示 textPaint.setTextAlign(Paint.Align.CENTER); textPaint.setTextSize(15); //繪制XY軸上的字:Y開關狀態、X時間 xyChartPaint.setStyle(Paint.Style.FILL); xyChartPaint.setStrokeWidth(1); xyChartPaint.setColor(Color.BLUE); xyChartPaint.setAntiAlias(true); xyChartPaint.setTextAlign(Paint.Align.CENTER); xyChartPaint.setTextSize(18); //繪制的折線 chartLinePaint.setStyle(Paint.Style.STROKE); chartLinePaint.setStrokeWidth(5); chartLinePaint.setColor(Color.BLUE); chartLinePaint.setAntiAlias(true); //繪制的折線 chartJianbianPaint.setStyle(Paint.Style.FILL); chartJianbianPaint.setStrokeWidth(5); //chartJianbianPaint.setColor(Color.YELLOW); chartJianbianPaint.setAntiAlias(true); huodongPaint.setStyle(Paint.Style.STROKE); huodongPaint.setStrokeWidth((float) 3.0); //設置線寬 huodongPaint.setColor(Color.GRAY); huodongPaint.setAntiAlias(true);// 鋸齒不顯示 huodongPaintText.setStyle(Paint.Style.STROKE); huodongPaintText.setStrokeWidth((float) 2.0); //設置線寬 huodongPaintText.setTextSize(40); huodongPaintText.setColor(Color.GRAY); huodongPaintText.setAntiAlias(true);// 鋸齒不顯示 setOnTouchListener(this); } /** * 重要參數,兩點之間分為幾段描畫,數字愈大分段越多,描畫的曲線就越精細. */ private static final int STEPS = 12; float gridX,gridY,xSpace = 0,ySpace = 0,spaceYT = 0; Float yStart=null,yStop = null; Integer yCount = null; List text = null; public void setText(List text) { this.text = text; } public void setyCount(Integer yCount) { this.yCount = yCount; } public void setyStart(Float yStart) { this.yStart = yStart; } public void setyStop(Float yStop) { this.yStop = yStop; } String yFormat=null; public void setFormat(String yFormat){ this.yFormat = yFormat; } List dateX = null; List dateY = null; List > data = null; List
colors = null; public void setColors(List colors) { this.colors = colors; } public List getDateY() { return dateY; } public void setDateY(List dateY) { this.dateY = dateY; } public List > getData() { return data; } public void setData(List
> data) { this.data = data; } public List
getDateX() { return dateX; } public void setDateX(List dateX) { this.dateX = dateX; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //基准點。 gridX = 40; gridY = getHeight() - 50; //XY間隔。 if(dateX!=null&&dateX.size()>0){ xSpace = (getWidthYMax() - gridX)/dateX.size(); } /** * 如果設置開頭和結尾的話,就直接生成y軸 */ if(yStart!=null&&yStop!=null&&yCount!=null){ dateY = new ArrayList<>(); ySpace = (gridY - 70)/yCount; float ze = (yStop-yStart)/yCount; for(int i=0;i 2){ spaceYT = dateY.get(1)-dateY.get(0); } }else{ if(dateY!=null&&dateY.size()>0){ ySpace = (gridY - 70)/dateY.size(); yStart = dateY.get(0); if(dateY.size()>2){ spaceYT = dateY.get(1)-dateY.get(0); } } } UIUtils.log("rewqfdesa",gridY,"fdsafdsa"); //畫Y軸(帶箭頭)。 canvas.drawLine(gridX, gridY - 20 - 10, gridX, 10, linePaint); canvas.drawLine(gridX, 10, gridX - 6, 14 + 10, linePaint);//Y軸箭頭。 canvas.drawLine(gridX, 10, gridX + 6, 14 + 10, linePaint); //畫Y軸名字。 //由於是豎直顯示的,先以原點順時針旋轉90度後為新的坐標系 //canvas.rotate(-90); //當xyChartPaint的setTextAlign()設置為center時第二、三個參數代表這四個字中點所在的xy坐標 //canvas.drawText("開關狀態", -((float) (getHeight() - 60) - 15 - 5 - 1 / ((float) 1.6 * 1) * (getHeight() - 60) / 2), gridX - 15, xyChartPaint); //繪制Y軸坐標 //canvas.rotate(90); //改變了坐標系還要再改過來 float y = 0; //畫X軸。 y = gridY - 20; canvas.drawLine(gridX, y - 10, getWidthYMax(), y - 10, linePaint);//X軸. canvas.drawLine(getWidthYMax(), y - 10, getWidthYMax() - 14, y - 6 - 10, linePaint);//X軸箭頭。 canvas.drawLine(getWidthYMax(), y - 10, getWidthYMax() - 14, y + 6 - 10, linePaint); //繪制X刻度坐標。 float x = 0; if(dateX!=null){ for (int n = 0; n < dateX.size(); n++) { //取X刻度坐標. x = gridX + (n) * xSpace;//在原點(0,0)處也畫刻度(不畫的話就是n+1),向右移動一個跨度。 //畫X軸具體刻度值。 if (dateX.get(n) != null) { //canvas.drawLine(x, gridY - 30, x, gridY - 18, linePaint);//短X刻度。 canvas.drawText(dateX.get(n), x, gridY + 5, textPaint);//X具體刻度值。 } } } float my = 0; if(dateY!=null){ for(int n=0;n 0){ float lastPointX = 0; //前一個點 float lastPointY = 0; float currentPointX = 0;//當前點 float currentPointY = 0; for(int n=0;n da = data.get(n); List da_x = new ArrayList<>(); List da_y = new ArrayList<>(); /** * 曲線路勁 */ Path curvePath = new Path(); /** * 漸變色路徑 */ Path jianBianPath = new Path(); for(int m=0;m 0){ // canvas.drawLine(lastPointX, lastPointY, currentPointX, currentPointY, chartLinePaint); // } // lastPointX = currentPointX; // lastPointY = currentPointY; } List calculate_y = calculate(da_y); List calculate_x = calculate(da_x); curvePath.moveTo(calculate_x.get(0).eval(0), calculate_y.get(0).eval(0)); jianBianPath.moveTo(gridX,gridY - 20 - 10); jianBianPath.lineTo(calculate_x.get(0).eval(0), calculate_y.get(0).eval(0)); chartLinePaint.setColor(colors.get(n)); float lastx = 0; for (int i = 0; i < calculate_x.size(); i++) { for (int j = 1; j <= STEPS; j++) { float u = j / (float) STEPS; curvePath.lineTo(calculate_x.get(i).eval(u), calculate_y.get(i) .eval(u)); jianBianPath.lineTo(calculate_x.get(i).eval(u), calculate_y.get(i) .eval(u)); lastx = calculate_x.get(i).eval(u); } } jianBianPath.lineTo(lastx,gridY - 20 - 10); canvas.drawPath(curvePath, chartLinePaint); Shader mShader = new LinearGradient(0,30 + 10,0,gridY - 20 - 10,new int[] {colors.get(n),Color.TRANSPARENT},null,Shader.TileMode.REPEAT); //新建一個線性漸變,前兩個參數是漸變開始的點坐標,第三四個參數是漸變結束的點的坐標。連接這2個點就拉出一條漸變線了,玩過PS的都懂。然後那個數組是漸變的顏色。下一個參數是漸變顏色的分布,如果為空,每個顏色就是均勻分布的。最後是模式,這裡設置的是循環漸變 chartJianbianPaint.setShader(mShader); canvas.drawPath(jianBianPath, chartJianbianPaint); } } if(lineX!=null){ if(text!=null&&text.size()>0){ Paint.FontMetrics metrics = huodongPaintText.getFontMetrics(); float top = metrics.top; float bootom = metrics.bottom; float h = bootom-top; float th = h + h*text.size(); float w=0; float fx = 1; if(lineX>getWidth()/2){ fx = -1; }else{ fx = 1; } for(int i=0;i w){ w = width; } canvas.drawText(text.get(i),fx==1?lineX+10:lineX-10-width,40+ h*(i+1),huodongPaintText); } canvas.drawLine(lineX, gridY - 20 - 10, lineX, 30 + 10, huodongPaint); //canvas.drawRect(lineX,40,lineX+w*fx+20*fx,40+th,huodongPaint); } } // //起始點。 // float lastPointX = 0; //前一個點 // float lastPointY = 0; // float currentPointX = 0;//當前點 // float currentPointY = 0; // if (dateY != null) { // //1.繪制折線。 // for (int n = 0; n < dateY.length; n++) { // //get current point // currentPointX = n * xSpace + gridX; // currentPointY = (float) (getHeight() - 60) - 15 - 5 - (float) dateY[n] / ((float) 1.6 * 1) * (getHeight() - 60); // if (dateX[n] != null) {//用X來判斷,就是用來如果剛開始的點數少於7個則從左到右遞增,從而沒有了剛開始的幾個虛點;(因為X和Y的數組初始化時都沒賦值,所以剛開始的時候用這個就可以判斷數組中到底幾個點) // if (n > 0) {//從第二個點開始判斷 // if (dateY[n - 1] == dateY[n]) {//如果相鄰兩個點相等一直畫直線 // //draw line // canvas.drawLine(lastPointX, lastPointY, currentPointX, currentPointY, chartLinePaint);//第一條線[藍色] // } else {//如果相鄰間的點不相等證明是從開到關或者關到開的狀態,要畫豎線 // //draw line 橫線 // canvas.drawLine(lastPointX, lastPointY, currentPointX, lastPointY, chartLinePaint);//第一條線[藍色] // //draw line 豎線 // canvas.drawLine(currentPointX, lastPointY, currentPointX, currentPointY, chartLinePaint);//第一條線[藍色] // } // } // } // // lastPointX = currentPointX; // lastPointY = currentPointY; // } // } //畫背景虛線,一條(因為除去了X軸),畫Y軸刻度 // y = (float) (getHeight() - 60) - 15 - 5 - 1 / ((float) 1.6 * 1) * (getHeight() - 60);//虛線的Y,開關是開的時候的Y。 // linePaint.setPathEffect(effect);//設法虛線間隔樣式。 // //畫除X軸之外的------背景虛線一條------- // path.moveTo(gridX, y);//背景【虛線起點】。 // path.lineTo(getWidth(), y);//背景【虛線終點】。 // canvas.drawPath(path, linePaint); // //畫Y軸刻度。 // canvas.drawText("關", gridX - 6 - 7, gridY - 20, textPaint); // canvas.drawText("開", gridX - 6 - 7, y + 10, textPaint); // // //繪制X刻度坐標。 // float x = 0; // if (dateX[0] != null) { //用X來判斷,就是用來如果剛開始的點數少於7個則從左到右遞增,從而沒有了剛開始的幾個虛點;(因為X和Y的數組初始化時都沒賦值,所以剛開始的時候用這個就可以判斷數組中到底幾個點) // for (int n = 0; n < dateX.length; n++) { // //取X刻度坐標. // x = gridX + (n) * xSpace;//在原點(0,0)處也畫刻度(不畫的話就是n+1),向右移動一個跨度。 // //畫X軸具體刻度值。 // if (dateX[n] != null) { // canvas.drawLine(x, gridY - 30, x, gridY - 18, linePaint);//短X刻度。 // canvas.drawText(dateX[n], x, gridY + 5, textPaint);//X具體刻度值。 // } // } // } // // //起始點。 // float lastPointX = 0; //前一個點 // float lastPointY = 0; // float currentPointX = 0;//當前點 // float currentPointY = 0; // if (dateY != null) { // //1.繪制折線。 // for (int n = 0; n < dateY.length; n++) { // //get current point // currentPointX = n * xSpace + gridX; // currentPointY = (float) (getHeight() - 60) - 15 - 5 - (float) dateY[n] / ((float) 1.6 * 1) * (getHeight() - 60); // if (dateX[n] != null) {//用X來判斷,就是用來如果剛開始的點數少於7個則從左到右遞增,從而沒有了剛開始的幾個虛點;(因為X和Y的數組初始化時都沒賦值,所以剛開始的時候用這個就可以判斷數組中到底幾個點) // if (n > 0) {//從第二個點開始判斷 // if (dateY[n - 1] == dateY[n]) {//如果相鄰兩個點相等一直畫直線 // //draw line // canvas.drawLine(lastPointX, lastPointY, currentPointX, currentPointY, chartLinePaint);//第一條線[藍色] // } else {//如果相鄰間的點不相等證明是從開到關或者關到開的狀態,要畫豎線 // //draw line 橫線 // canvas.drawLine(lastPointX, lastPointY, currentPointX, lastPointY, chartLinePaint);//第一條線[藍色] // //draw line 豎線 // canvas.drawLine(currentPointX, lastPointY, currentPointX, currentPointY, chartLinePaint);//第一條線[藍色] // } // } // } // // lastPointX = currentPointX; // lastPointY = currentPointY; // } // } // //畫X軸名字。 // canvas.drawText("時間", getWidth() / 2 - 10, getHeight() - 18, xyChartPaint); } // /** // * 畫點. // * // * @param canvas // */ // private void drawPoints(Canvas canvas) { // for (int i = 0; i < points.size(); i++) { // Point p = points.get(i); // canvas.drawCircle(p.x, p.y, 5, paint); // } // } /** * 計算曲線. * * @param x * @return */ private List calculate(List x) { int n = x.size() - 1; float[] gamma = new float[n + 1]; float[] delta = new float[n + 1]; float[] D = new float[n + 1]; int i; /* * We solve the equation [2 1 ] [D[0]] [3(x[1] - x[0]) ] |1 4 1 | |D[1]| * |3(x[2] - x[0]) | | 1 4 1 | | . | = | . | | ..... | | . | | . | | 1 4 * 1| | . | |3(x[n] - x[n-2])| [ 1 2] [D[n]] [3(x[n] - x[n-1])] * * by using row operations to convert the matrix to upper triangular and * then back sustitution. The D[i] are the derivatives at the knots. */ gamma[0] = 1.0f / 2.0f; for (i = 1; i < n; i++) { gamma[i] = 1 / (4 - gamma[i - 1]); } gamma[n] = 1 / (2 - gamma[n - 1]); delta[0] = 3 * (x.get(1) - x.get(0)) * gamma[0]; for (i = 1; i < n; i++) { delta[i] = (3 * (x.get(i + 1) - x.get(i - 1)) - delta[i - 1]) * gamma[i]; } delta[n] = (3 * (x.get(n) - x.get(n - 1)) - delta[n - 1]) * gamma[n]; D[n] = delta[n]; for (i = n - 1; i >= 0; i--) { D[i] = delta[i] - gamma[i] * D[i + 1]; } /* now compute the coefficients of the cubics */ List cubics = new LinkedList (); for (i = 0; i < n; i++) { Cubic c = new Cubic(x.get(i), D[i], 3 * (x.get(i + 1) - x.get(i)) - 2 * D[i] - D[i + 1], 2 * (x.get(i) - x.get(i + 1)) + D[i] + D[i + 1]); cubics.add(c); } return cubics; } Float lineX = null; Integer temp = null; @Override public boolean onTouch(View v, MotionEvent event) { getParent().requestDisallowInterceptTouchEvent(true); switch(event.getAction()){ case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: float zhi = (event.getX()-gridX)%xSpace; boolean fanwei = zhi>0&&zhi 0&&fanwei&&event.getX()
Intent意圖是android中非常重要的部分,他在Activity,service中有較為廣泛的應用。 1 public void startActiv
在本文當中,我將會與大家分享一個封裝了PopupWindow實現彈出菜單的類,並說明它的實現與使用。 因對界面的需求,android原生的彈出菜單已不能滿足我們的需求,自
講到http就必需要了解URI和URL URI (uniform resource identifier)統一資源標志符; URL(uniform resource lo
1、概述 關於手機圖片加載器,在當今像素隨隨便便破千萬的時代,一張圖片占據的內存都相當可觀,作為高大尚程序猿的我們,有必要掌握圖片的壓縮,緩存等處理,以到達