自定义组件之【柱状图】详解 已封装成View


http://www.eoeandroid.com/thread-83414-1-1.html

先上图,里面的数据时伪数据,用的时候传入参数即可。柱状图会根据数值的大小来变换显示的颜色,比如绿色、土黄色和红色。柱状图升高采用了类似于动画效果,可以在创建时设置是否启动动画效果。这个柱状图实现很简单,已经封装成一个view,大家可以直接使用,有什么问题和意见欢迎大家指教。

 
上代码了:(命名不是很规范,E文不行,请见谅)
ConfigurationView   柱状图组件
  1. package org.gmy.view.config;

  2. import android.content.Context;
  3. import android.graphics.Canvas;
  4. import android.graphics.Paint;
  5. import android.os.Handler;
  6. import android.os.Message;
  7. import android.view.View;
  8. import android.widget.TextView;

  9. public class ConfigurationView extends View {

  10. private Paint paint;
  11. private Paint font_Paint;
  12. // 数值显示的偏移量
  13. private int numWidth = 9;

  14. // 起始高度为 最大高度减去 80 【注意这里的高度是反的,也就是说,y轴是逐渐减少的】
  15. private float startHeight = Configuration.HEIGHT-80;
  16. private float endHeight = startHeight;
  17. // 柱状图的宽度
  18. private int viewWidth = 20;

  19. // 组态图的高度 【显示的数值,100 为 100%】
  20. private int maxSize = 43;
  21. private int indexSize = 0;
  22. // 要显示的模式 【类型,比如:℃和百分比等】
  23. private String displayMode = "%";
  24. // 模式
  25. private boolean mode = false;
  26. // 线程控制
  27. private boolean display = true;
  28. // 是否开启动画效果
  29. private boolean animMode = true;

  30. /**

  31. * @param context
  32. * @param maxSize 需要显示的数值
  33. * @param displayMode 显示的类型
  34. */
  35. public ConfigurationView(Context context, int maxSize, String displayMode) {
  36. super(context);
  37. this.maxSize = maxSize;
  38. this.displayMode = displayMode;
  39. init();
  40. }

  41. /**

  42. * @param context
  43. * @param maxSize 需要显示的数值
  44. * @param displayMode 显示的类型
  45. * @param mode 显示的模式,默认为false,数值越高,颜色越偏向红色。为true反之
  46. */
  47. public ConfigurationView(Context context, int maxSize, String displayMode, boolean mode) {
  48. super(context);
  49. this.maxSize = maxSize;
  50. this.displayMode = displayMode;
  51. this.mode = mode;
  52. init();
  53. }

  54. /**

  55. * @param context
  56. * @param maxSize 需要显示的数值
  57. * @param displayMode 显示的类型
  58. * @param mode 显示的模式,默认为false,数值越高,颜色越偏向红色。为true反之
  59. * @param animMode 是否显示动画加载效果,默认为true
  60. */
  61. public ConfigurationView(Context context, int maxSize, String displayMode, boolean mode, boolean animMode) {
  62. super(context);
  63. this.maxSize = maxSize;
  64. this.displayMode = displayMode;
  65. this.mode = mode;
  66. this.animMode = animMode;
  67. init();
  68. }

  69. // 绘制界面
  70. @Override
  71. protected void onDraw(Canvas canvas) {
  72. super.onDraw(canvas);
  73. canvas.drawRect(10, endHeight, 10+viewWidth, startHeight, paint);
  74. if(!display){
  75. // 这段if语句可以放在初始化中,这个就交给大家吧。
  76. if(!mode && indexSize >= 50){
  77. paint.setARGB(255, 200, 200, 60);
  78. if(!mode && indexSize >= 80){
  79. paint.setARGB(255, (indexSize<100)?(110+indexSize+45):255, (indexSize<100)?210-(indexSize+45):0, 20);
  80. }
  81. }else if(mode && indexSize <= 50){
  82. paint.setARGB(255, 200, 200, 60);
  83. if(mode && indexSize <= 30){
  84. paint.setARGB(255, 255-indexSize, indexSize, 20);
  85. }
  86. }
  87. canvas.drawRect(10, endHeight, 10+viewWidth, startHeight, paint);
  88. paint.setARGB(255, 99, 66, 0);
  89. canvas.drawText(""+indexSize, numWidth, endHeight-5, paint);
  90. paint.setARGB(255, 110, 210, 60);
  91. }
  92. canvas.drawText(displayMode, 0, startHeight+15, font_Paint);
  93. }

  94. // 初始化
  95. private void init(){
  96. // 数值初始化
  97. paint = new Paint();
  98. paint.setARGB(255, 110, 210, 20);
  99. font_Paint = new Paint();
  100. font_Paint.setARGB(255, 66, 66, 66);

  101. // 设置顶端数值显示的偏移量,数值越小,偏移量越大
  102. numWidth = 9;
  103. if(maxSize < 10){
  104. numWidth = 15;
  105. }else if(maxSize < 100){
  106. numWidth = 12;
  107. }

  108. if(animMode){
  109. // 启动一个线程来实现柱状图缓慢增高
  110. thread.start();
  111. }else{
  112. // 不启用动画效果,则直接赋值进行绘制
  113. display = false;
  114. indexSize = maxSize;
  115. endHeight = startHeight-(float) (maxSize*1.5);
  116. invalidate();
  117. }
  118. }

  119. private Handler handler = new Handler(){
  120. @Override
  121. public void handleMessage(Message msg) {
  122. super.handleMessage(msg);
  123. // 通过endHeight >= 20将柱状图的高度控制在150以内,这样刚好循环一百次到顶部
  124. if(msg.what == 1 && indexSize < maxSize && endHeight >= 20){
  125. endHeight -= 1.5;
  126. indexSize += 1;
  127. }else{
  128. display = false;
  129. }
  130. invalidate();
  131. }
  132. };


  133. private Thread thread = new Thread(){
  134. @Override
  135. public void run(){
  136. while(!Thread.currentThread().isInterrupted() && display )
  137. {
  138. Message msg = new Message();
  139. msg.what = 1;
  140. handler.sendMessage(msg);
  141. try {
  142. // 每隔15毫秒触发,尽量使升高的效果看起来平滑
  143. Thread.sleep(15);
  144. } catch (InterruptedException e) {
  145. System.err.println("InterruptedException!线程关闭");
  146. this.interrupt();
  147. }
  148. }
  149. }
  150. };

  151. }
复制代码
Configuration 类
一个普通的activity,创建了五个柱状图用于测试。第一个view = new ConfigurationView(this, 100, "温度/℃", false, false);没有使用动画效果。
  1. package org.gmy.view.config;

  2. import org.gmy.view.R;

  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.view.Gravity;
  6. import android.view.ViewGroup.LayoutParams;
  7. import android.widget.EditText;
  8. import android.widget.LinearLayout;
  9. import android.widget.TableRow;

  10. public class Configuration extends Activity {

  11. public static final int WIDTH = 280;
  12. public static final int HEIGHT = 250;

  13. private ConfigurationView view, view1, view2, view3, view4;
  14. private LinearLayout layout;

  15. @Override
  16. protected void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.config_dialog);
  19. layout = (LinearLayout) findViewById(R.id.configLayout);

  20. view = new ConfigurationView(this, 100, "温度/℃", false, false);
  21. layout.addView(view, new LayoutParams(50, LayoutParams.FILL_PARENT));

  22. view1 = new ConfigurationView(this, 100, "电量/%", true);
  23. layout.addView(view1, new LayoutParams(50, LayoutParams.FILL_PARENT));

  24. view2 = new ConfigurationView(this, 80, "电量/%", true);
  25. layout.addView(view2, new LayoutParams(50, LayoutParams.FILL_PARENT));

  26. view3 = new ConfigurationView(this, 40, "电量/%", true);
  27. layout.addView(view3, new LayoutParams(50, LayoutParams.FILL_PARENT));

  28. view4 = new ConfigurationView(this, 2, "电量/%", true);
  29. layout.addView(view4, new LayoutParams(50, LayoutParams.FILL_PARENT));
  30. }

  31. }
复制代码
config_dialog.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical"
  5. android:layout_width="280dip"
  6. android:layout_height="250dip"
  7. android:padding="10dip"
  8. android:layout_gravity="center_horizontal"
  9. android:background="@drawable/dialog_alert_bg2" 
  10. >
  11. <TextView
  12. android:id="@+id/configTitle"
  13. android:layout_width="fill_parent"
  14. android:layout_height="wrap_content"
  15. android:gravity="center_horizontal"
  16. android:text="柱状图"
  17. android:textSize="18dip"
  18. android:textColor="#fdb814"
  19. />
  20. <LinearLayout
  21. android:orientation="horizontal"
  22. android:id="@+id/configLayout"
  23. android:layout_width="260dip"
  24. android:layout_height="220dip"
  25. >

  26. </LinearLayout>
  27. </LinearLayout>
复制代码
AndroidManifest.xml  使用了对话框的主题
  1. <activity android:name=".Configuration" android:label="@string/app_name" android:theme="@android:style/Theme.Dialog" >
  2. <intent-filter>
  3. <action android:name="android.intent.action.MAIN" />
  4. <category android:name="android.intent.category.LAUNCHER" />
  5. </intent-filter>
  6. </activity>
复制代码
有问题的随时问我,代码已给出,demo已经上传,欢迎提意见,觉得不错请顶下,3Q
背景图片:
 

  Configuration.rar (36.5 KB, 下载次数: 134) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值