自定义视图

Android提供了一个精致而强大的组件化模式来创建你的用户界面,基于基础的布局类:视图 View和视图组ViewGroup。平台包含了多种预定义视图和视图组子类-分别称为部件和布局-这些可以用来构造你的用户界面。

一部分可用部件包括按钮Button,文本视图TextView,编辑文本框EditText,列表视图ListView,组合框CheckBox, 单选按钮RadioButton, 画廊Gallery, 微调器Spinner,以及一些用于特定场合的自动补全文本视图AutoCompleteTextView,图片切换器ImageSwitcher, 和文本切换器TextSwitcher.

可用布局有线性布局LinearLayout,框架布局FrameLayout, 相对布局RelativeLayout, 以及其他。更多例子,参见常用布局对象Common LayoutObjects.

如果这些预定义的部件或布局不能满足你的需求,你可以创建你自己的视图类。如果你只需要在现有的部件或布局上做些调整,你只需要子类化这个部件或布局并重写它的方法。

创建自己的视图子类让你可以精确控制界面元素的外形和功能。为了对这种控制有个大概的印象,下面是一些例子说明你可以用它们做什么:

·你可以把一组视图组件组合进一个单独的组件里,如在gridView中,自定义Item的布局,是其包含一个ImageView和一个TextView等等。

·你可以创建一个完全自定义绘制的视图类型,比如一个条形统计图。

第一种是自定义布局组合视图,可以参考RUI代码中的AppIcon这个类。第二种是重写父类的方法自定义视图,可以参考RUI代码中的BubbleTextView和CellLayout这两个类。第二种的实现相对要求对View类的相关API了解的更加深入一些,因此,实现的难度比第一种大。在此,主要介绍第二种方法来绘制一个条形统计图。

结果演示:


图1 原始图



图 2 绘制图

在结果演示当中的原始图是国外的调查机构发布的调查结果,绘制图是根据原始图,在重写OnDraw()方法绘制出来的。

相关源码:

MyView类:

public class MyView extends View {
    private Paint myPaint; 
    private static final String mTitle = "最受开发者喜爱的平台"; 
    private static final String mSource = "来源:http://www.52rd.com/S_TXT/2012_3/TXT34667.HTM"; 
    
    public MyView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }
    public MyView(Context context,AttributeSet attr) { 
        super(context,attr); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
        // TODO Auto-generated method stub 
        super.onDraw(canvas);
        myPaint = new Paint();  
        //绘制标题
        myPaint.setColor(Color.BLACK); //设置画笔颜色
        myPaint.setTextSize(18);//设置文字大小
        canvas.drawText(mTitle, 20, 20, myPaint); 
        //绘制坐标轴
        canvas.drawLine(50, 80, 50, 500, myPaint);//纵坐标轴       
        canvas.drawLine(50, 500, 800, 500, myPaint);//横坐标轴
        int[] arrayInt = new int[]{0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
        int[] DrawableIds = new int[]{R.drawable.ios, R.drawable.android, R.drawable.wp7, R.drawable.bb};
        //绘制纵坐标刻度
        myPaint.setTextSize(10);//设置文字大小
        canvas.drawText("百分比", 20, 70, myPaint); 
        for (int i = 0; i < arrayInt.length; i++) {
            canvas.drawLine(50, 500 - arrayInt[i] * 4, 54, 500 - arrayInt[i] * 4, myPaint);
            canvas.drawText(arrayInt[i] + "", 20, 500 - arrayInt[i] * 4, myPaint);
        }
        //绘制横坐标文字
        String[] arrayName = new String[]{"IOS", "Android", "WP7", "BlackBerry"};
        for (int i = 0; i < arrayName.length; i++) {
//            canvas.drawText(arrayName[i], arrayInt[i] * 15 + 80, 520, myPaint);
            canvas.drawBitmap(BitmapFactory.decodeResource(this.getResources(), DrawableIds[i]),
                    arrayInt[i] * 15 + 80, 520, myPaint);
        }
        //绘制条形图
        myPaint.setColor(Color.BLUE); //设置画笔颜色 
        myPaint.setStyle(Style.FILL); //设置填充 
        canvas.drawRect(new Rect(80, 500 - (40 * 9), 110, 500), myPaint);//画一个矩形,前两个参数是矩形左上角坐标,后两个参数是右下角坐标        
        canvas.drawRect(new Rect(230, 500 - (40 * 8), 260, 500), myPaint);//第二个矩形     
        canvas.drawRect(new Rect(380, 500 - (int) (40 * 3.7), 410, 500), myPaint);//第三个矩形    
        canvas.drawRect(new Rect(530, 500 - (int) (40 * 1.6), 560, 500), myPaint);//第四个矩形
        myPaint.setColor(Color.BLACK); //设置画笔颜色
        canvas.drawText("90%", 80, 500 - (40 * 9 + 5), myPaint);//第一个矩形的数字说明
        canvas.drawText("80%", 230, 500 - (40 * 8 + 5), myPaint);
        canvas.drawText("37%", 380, 500 - (int) (40 * 3.7 + 5), myPaint);
        canvas.drawText("16%", 530, 500 - (int) (40 * 1.6 + 5), myPaint);
        //绘制出处
        myPaint.setColor(Color.BLACK); //设置画笔颜色
        myPaint.setTextSize(16);//设置文字大小        
        canvas.drawText(mSource, 20, 600, myPaint); 
    } 
}

布局文件 main.xml



    


注意事项:

1.     大家细看布局文件,就会发现MyView和其它的View(TextView等等)有所不同,是因为前面加了包名。这样在Activity中就不用在做它的任何设置,只需在OnCreate()方法中使用setContentView(R.layout.main)即可。

2.     设备中的绘图坐标是左上角为坐标原点,向下为y轴,向右为x轴。如下图所示:


图中的ABC三点就是有下面两句代码确定的

        canvas.drawLine(50,80, 50, 500, myPaint);//纵坐标轴      

        canvas.drawLine(50, 500, 800, 500,myPaint);//横坐标轴


你可能感兴趣的:(android)