您的位置:首页 > 其它

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

2012-05-02 11:35 381 查看
  这是我以前在eoeandroid发的一个帖子,现在贴在我的博客中。

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



ConfigurationView 柱状图组件

package org.gmy.view.config;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;

public class ConfigurationView extends View {

private Paint paint;
private Paint font_Paint;
// 数值显示的偏移量
private int numWidth = 9;

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

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

/**
*
* @param context
* @param maxSize 需要显示的数值
* @param displayMode 显示的类型
*/
public ConfigurationView(Context context, int maxSize, String displayMode) {
super(context);
this.maxSize = maxSize;
this.displayMode = displayMode;
init();
}

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

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

// 绘制界面
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(10, endHeight, 10+viewWidth, startHeight, paint);
if(!display){
// 这段if语句可以放在初始化中,这个就交给大家吧。
if(!mode && indexSize >= 50){
paint.setARGB(255, 200, 200, 60);
if(!mode && indexSize >= 80){
paint.setARGB(255, (indexSize<100)?(110+indexSize+45):255, (indexSize<100)?210-(indexSize+45):0, 20);
}
}else if(mode && indexSize <= 50){
paint.setARGB(255, 200, 200, 60);
if(mode && indexSize <= 30){
paint.setARGB(255, 255-indexSize, indexSize, 20);
}
}
canvas.drawRect(10, endHeight, 10+viewWidth, startHeight, paint);
paint.setARGB(255, 99, 66, 0);
canvas.drawText(""+indexSize, numWidth, endHeight-5, paint);
paint.setARGB(255, 110, 210, 60);
}
canvas.drawText(displayMode, 0, startHeight+15, font_Paint);
}

// 初始化
private void init(){
// 数值初始化
paint = new Paint();
paint.setARGB(255, 110, 210, 20);
font_Paint = new Paint();
font_Paint.setARGB(255, 66, 66, 66);

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

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

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

private Thread thread = new Thread(){
@Override
public void run(){
while(!Thread.currentThread().isInterrupted() && display )
{
Message msg = new Message();
msg.what = 1;
handler.sendMessage(msg);
try {
// 每隔15毫秒触发,尽量使升高的效果看起来平滑
Thread.sleep(15);
} catch (InterruptedException e) {
System.err.println("InterruptedException!线程关闭");
this.interrupt();
}
}
}
};

}


  Configuration 类
一个普通的activity,创建了五个柱状图用于测试。第一个view = new ConfigurationView(this, 100, "温度/℃", false, false);没有使用动画效果。

package org.gmy.view.config;

import org.gmy.view.R;

import android.app.Activity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TableRow;

public class Configuration extends Activity {

public static final int WIDTH = 280;
public static final int HEIGHT = 250;

private ConfigurationView view, view1, view2, view3, view4;
private LinearLayout layout;

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

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

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

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

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

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

}


  config_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="280dip"
android:layout_height="250dip"
android:padding="10dip"
android:layout_gravity="center_horizontal"
android:background="@drawable/dialog_alert_bg2"
>
<TextView
android:id="@+id/configTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="柱状图"
android:textSize="18dip"
android:textColor="#fdb814"
/>
<LinearLayout
android:orientation="horizontal"
android:id="@+id/configLayout"
android:layout_width="260dip"
android:layout_height="220dip"
>

</LinearLayout>
</LinearLayout>


  AndroidManifest.xml 使用了对话框的主题

<activity android:name=".Configuration" android:label="@string/app_name" android:theme="@android:style/Theme.Dialog" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>


  

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: