編輯:關於Android編程
今天做項目需要用到簡單的橫向的柱狀圖,上網查了一下,沒找到合適的框架,於是決定自己動手寫一個自定義View,來實現三種柱狀圖。
那麼先看效果圖
橫向的柱狀圖,只有柱子的比例和文字。
縱向的柱狀圖,加上了坐標軸的繪制。
比例式柱狀圖,只接受長度為2的數組,會自己判斷將長的置於背景。
那麼我們看一下這個自定義View的代碼:
package com.example.day09; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; import android.view.animation.Animation; import android.view.animation.ScaleAnimation; /** * Created by Administrator on 2016/11/3. */ public class Histogram extends View { private int[] nums; private String[] names; private int[] colors; private Context context; private int max = 0; private int type; private int wheretext; private int maxlong; private int j; private int width; private int kong; private boolean useAnimation; private Histogram v; public void setNames(String[] names) { this.names = names; } public void setMax(int max) { this.max = max; } public void setType(int type) { this.type = type; } public void setWheretext(int wheretext) { this.wheretext = wheretext; } public void setMaxlong(int maxlong) { this.maxlong = maxlong; } public void setWidth(int width) { this.width = width; } public void setKong(int kong) { this.kong = kong; } public void setUseAnimation(boolean useAnimation) { this.useAnimation = useAnimation; } public Histogram(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.context = context; v = this; } public Histogram(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; v = this; } public Histogram(Context context) { super(context); v = this; this.context = context; } /** * 初始化柱狀圖的方法 * * @param nums 存放每個元素數量的數組 * @param names 存放每個元素文字的數組 * @param colors 存放每個元素使用的顏色的數組 * @param type 定義柱狀圖的類型 1為橫向,2為縱向,其余為比例 * @param wheretext 定義柱狀圖文字的位置 (若橫向)1為圖前,2為圖後,其余為無文字;(若縱向)1為圖下,其余無文字 * @param maxlong 柱狀圖的最大長度(px) * @param max 最大長度對應的數值 * @param width 每條柱子的寬度 * @param kong 柱子之間的空隙寬度 */ public void SetHistogram(int[] nums, String[] names, int[] colors, int type, int wheretext, int maxlong, int max, int width, int kong, boolean useAnimation) { this.colors = colors; this.names = names; this.nums = nums; this.type = type; this.wheretext = wheretext; this.maxlong = maxlong; this.max = max; j = maxlong / max; this.width = width; this.kong = kong; this.useAnimation = useAnimation; } public void SetHistogram(int[] nums, int[] colors, int type) { SetHistogram(nums, null, colors, type, 0, 800, 100, 50, 0, false); } public void SetHistogram(int[] nums, int[] colors) { SetHistogram(nums, colors, 1); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); switch (type) { case 1: DrawHeng(canvas, p); break; case 2: DrawShu(canvas, p); break; default: DrawBiLi(canvas, p); break; } } /** * 畫橫向比例柱狀圖 * * @param canvas * @param p */ private void DrawBiLi(Canvas canvas, Paint p) { int i, j; if (nums[0] > nums[1]) { i = 0; j = 1; } else { i = 1; j = 0; } int[] numss = new int[]{nums[i], nums[j]}; int[] colorss = new int[]{colors[i], colors[j]}; String[] namess = new String[]{names[i], names[j]}; float bili = (0.0F + numss[0]) / (0.0F + numss[1]); switch (wheretext) { case 1: p.setColor(colorss[0]); canvas.drawRect(0, 0, maxlong, width, p); p.setColor(colorss[1]); canvas.drawRect(0, 0, maxlong / bili, width, p); //寫字 p.setColor(Color.WHITE); p.setTextSize(width - 10); p.setTextAlign(Paint.Align.LEFT); canvas.drawText(namess[0], 10, width, p); canvas.drawText(namess[1], maxlong / bili + 10, width, p); if (useAnimation) { setAnimationHeng(); } break; default: p.setColor(colorss[0]); canvas.drawRect(0, 0, maxlong, width, p); p.setColor(colorss[1]); canvas.drawRect(0, 0, maxlong / bili, width, p); if (useAnimation) { setAnimationHeng(); } break; } } /** * 畫縱向柱狀圖 * * @param canvas * @param p */ private void DrawShu(Canvas canvas, Paint p) { switch (wheretext) { case 1: //畫坐標軸 p.setStrokeWidth(5); p.setColor(Color.BLACK); canvas.drawLine(30, maxlong, nums.length * (width + kong) + 150, maxlong, p); canvas.drawLine(nums.length * (width + kong) + 150, maxlong, nums.length * (width + kong) + 120, maxlong - 30, p); canvas.drawLine(nums.length * (width + kong) + 150, maxlong, nums.length * (width + kong) + 120, maxlong + 30, p); canvas.drawLine(30, maxlong, 30, 0, p); canvas.drawLine(30, 0, 0, 30, p); canvas.drawLine(30, 0, 60, 30, p); //畫柱子 for (int i = 0; i < nums.length; i++) { p.setColor(colors[i]); canvas.drawRect(60 + kong + (i * (kong + width)), maxlong - (j * nums[i]), 60 + kong + (i * (kong + width)) + width, maxlong, p); p.setColor(Color.BLACK); p.setTextSize(width - 10); p.setTextAlign(Paint.Align.LEFT); canvas.drawText(names[i], 60 + ((width + kong) * i) + width / 4, maxlong + width, p); } if (useAnimation) { setAnimationShu(); } break; default: //畫坐標軸 p.setStrokeWidth(5); p.setColor(Color.BLACK); canvas.drawLine(30, maxlong, nums.length * (width + kong) + 150, maxlong, p); canvas.drawLine(nums.length * (width + kong) + 150, maxlong, nums.length * (width + kong) + 120, maxlong - 30, p); canvas.drawLine(nums.length * (width + kong) + 150, maxlong, nums.length * (width + kong) + 120, maxlong + 30, p); canvas.drawLine(30, maxlong, 30, 0, p); canvas.drawLine(30, 0, 0, 30, p); canvas.drawLine(30, 0, 60, 30, p); //畫柱子 for (int i = 0; i < nums.length; i++) { p.setColor(colors[i]); canvas.drawRect(60 + kong + (i * (kong + width)), maxlong - (j * nums[i]), 60 + kong + (i * (kong + width)) + width, maxlong, p); } if (useAnimation) { setAnimationShu(); } break; } } /** * 畫橫向柱狀圖 * * @param canvas * @param p */ private void DrawHeng(Canvas canvas, Paint p) { switch (wheretext) { case 1: for (int i = 0; i < nums.length; i++) { p.setColor(Color.BLACK); p.setTextSize(width - 10); p.setTextAlign(Paint.Align.RIGHT); canvas.drawText(names[i], 80, width + width * i, p); p.setColor(colors[i]); canvas.drawRect(100, i * width + kong, 100 + nums[i] * j, width + i * width, p); if (useAnimation) { setAnimationHeng(); } } break; case 2: for (int i = 0; i < nums.length; i++) { p.setColor(colors[i]); canvas.drawRect(0, i * width + kong, nums[i] * j, width + i * width, p); p.setColor(Color.BLACK); p.setTextSize(width - 10); p.setTextAlign(Paint.Align.LEFT); canvas.drawText(names[i], nums[i] * j + 20, width + width * i, p); if (useAnimation) { setAnimationHeng(); } } break; default: for (int i = 0; i < nums.length; i++) { p.setColor(colors[i]); canvas.drawRect(0, i * width + kong, nums[i] * j, width + i * width, p); if (useAnimation) { setAnimationHeng(); } } break; } } /** * 設置動畫(橫向) */ private void setAnimationHeng() { ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 1.0f, 1.0f , Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f); scaleAnimation.setDuration(1000); this.setAnimation(scaleAnimation); scaleAnimation.startNow(); } /** * 設置動畫(橫向) */ private void setAnimationShu() { ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.0f, 0.0f, 1.0f , Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f); scaleAnimation.setDuration(1000); this.setAnimation(scaleAnimation); scaleAnimation.startNow(); } }
/** * 初始化柱狀圖的方法 * * @param nums 存放每個元素數量的數組 * @param names 存放每個元素文字的數組 * @param colors 存放每個元素使用的顏色的數組 * @param type 定義柱狀圖的類型 1為橫向,2為縱向,其余為比例 * @param wheretext 定義柱狀圖文字的位置 (若橫向)1為圖前,2為圖後,其余為無文字;(若縱向)1為圖下,其余無文字 * @param maxlong 柱狀圖的最大長度(px) * @param max 最大長度對應的數值 * @param width 每條柱子的寬度 * @param kong 柱子之間的空隙寬度 */ public void SetHistogram(int[] nums, String[] names, int[] colors, int type, int wheretext, int maxlong, int max, int width, int kong, boolean useAnimation) { this.colors = colors; this.names = names; this.nums = nums; this.type = type; this.wheretext = wheretext; this.maxlong = maxlong; this.max = max; j = maxlong / max; this.width = width; this.kong = kong; this.useAnimation = useAnimation; }後面的代碼都是根據這個方法傳進來的參數做出相應的繪制,當然,大多數有用的屬性也單獨提供了Set方法;
接下來我們簡單的試驗一下一個縱向的柱狀圖,代碼如下:
MainActivity:
package com.example.day09; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.view.animation.Animation; import android.view.animation.ScaleAnimation; public class MainActivity extends Activity { Histogram histogram; int[] nums; int[] colors; String[] names; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); histogram= (Histogram) findViewById(R.id.imageId); nums=new int[]{55,24,64,35,100}; colors=new int[]{Color.BLUE,Color.YELLOW,0Xffabcdef,Color.GREEN,Color.RED}; names=new String[]{"A","B","C","D","E"}; histogram.SetHistogram(nums,names,colors,2,1,1000,100,80,10,false); ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 1.0f, 1.0f , Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f); scaleAnimation.setDuration(1000); histogram.setAnimation(scaleAnimation); scaleAnimation.startNow(); scaleAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { histogram.setVisibility(View.VISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } }); } }
這樣就做出了一個簡單的柱狀圖了,截圖效果:
首先自定義一個View子類: package com.example.androidtest0.myView; import android.content.Conte
NFC簡介:Near Field Communication 近場通信,是一種數據傳輸技術。與wifi、藍牙、紅外線等數據傳輸技術的一個主要差異就是有效距離一般不能超過4
0、基礎回顧PropertyAnimation,屬性動畫,顧名思義就是利用對象的屬性變化形成動畫的效果。屬性動畫的類可以用Animator這個抽象類來表示,通常使用它的子
屬性動畫---res/animator屬性動畫故名思議就是通過動畫的方式改變對象的屬性了,我們首先需要了解幾個屬性:Duration動畫的持續時間,默認300ms。Tim