转载

Android绘制自定义View的方法

因为要帮同学做个空心扇形统计图,要求使用自定义View,在帮她的同时,我也学了自定义View的写法。

自定义View

自定义View毫无疑问要继承 android.view.View ,这里我重写了 onDraw(Canvas)onMeasure(int, int) 方法和构造方法

代码如下:

package com.shyling.customviewdemo; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import java.util.ArrayList; public class PieChart extends View {  private Paint mPaint,mCenterPaint;  private float mRadius;  private int mBackgroundColor;  private String mText;  private RectF mRectF;  private int mTotalValue = 0;  private ArrayList<PieChartDataItem> mValues;  public PieChart(Context context, AttributeSet attrs) {   super(context, attrs);   mPaint = new Paint();   mRectF = new RectF();   mCenterPaint = new Paint();   mValues = new ArrayList<PieChartDataItem>();   //读取xml中的配置   TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.PieChart);   mRadius = typedArray.getDimension(R.styleable.PieChart_Radius, 0);   mBackgroundColor = typedArray.getColor(R.styleable.PieChart_Background,Color.WHITE);   typedArray.recycle();   //设置反锯齿   mPaint.setAntiAlias(true);   mCenterPaint.setAntiAlias(true);   mCenterPaint.setTextSize(79);   mCenterPaint.setTextAlign(Paint.Align.CENTER);  }  /*  绘制View  @param canvas#画布   */  @Override  protected void onDraw(Canvas canvas) {   super.onDraw(canvas);   canvas.drawColor(mBackgroundColor);   int degrees = 0;   for(PieChartDataItem pieChartDataItem:mValues){    mPaint.setColor(pieChartDataItem.getColor());    canvas.drawArc(mRectF, degrees, pieChartDataItem.getDegrees(), true, mPaint);    degrees+=pieChartDataItem.getDegrees();   }   canvas.translate(mRadius / 2, mRadius / 2);   mCenterPaint.setColor(Color.WHITE);   canvas.drawCircle(0, 0, mRadius / 4, mCenterPaint);   mCenterPaint.setColor(Color.BLACK);   canvas.drawText(this.getText(), 0, 0, mCenterPaint);  }  /*  设置View中心文本内容  @param text#文本内容   */  public void setText(String text){   this.mText = text;  }  /*  获得View中心文本  @return text   */  public String getText(){   if(this.mText==null){    return "";   }else{    return this.mText;   }  }  /*  添加Item  @param itemTitle#item标题  @param itemValue#item值  @param itemColor#item颜色  @see #addItem(PieChartDataItem)   */  public void addItem(String itemTitle,int itemValue,int itemColor){   addItem(new PieChartDataItem(itemTitle, itemValue, itemColor));  }  /*  添加item  @param pieChartDataItem#PieChartDataItem实例   */  public void addItem(PieChartDataItem pieChartDataItem){   if(pieChartDataItem.getValue()<0){    throw new NumberFormatException("itemValue must big than zero");   }   mTotalValue +=pieChartDataItem.getValue();   mValues.add(pieChartDataItem);  }  /*  重置View数据   */  public void reset(){   mTotalValue=0;   mValues.clear();  }  /*  获得View内全部数据  @return PieChartDataItem[]   */  public PieChartDataItem[] getValues(){   PieChartDataItem[] pieChartDataItems = new PieChartDataItem[mValues.size()];   mValues.toArray(pieChartDataItems);   return pieChartDataItems;  }  /*  对VIew内数据进行处理,生成对应角度   */  public void cal(){   for(PieChartDataItem pieChartDataItem : mValues){    pieChartDataItem.setDegrees(360*pieChartDataItem.getValue()/mTotalValue+1);   }   this.invalidate();  }  /*  初始化View大小,根据长宽中最小值确定圆半径   */  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   super.onMeasure(widthMeasureSpec, heightMeasureSpec);   int width = MeasureSpec.getSize(widthMeasureSpec);   int height = MeasureSpec.getSize(heightMeasureSpec);   mRadius = Math.min(width,height);   mRectF.set(0, 0, mRadius, mRadius);   setMeasuredDimension((int)mRadius, (int)mRadius);  } }  

Item Model为:

package com.shyling.customviewdemo; import android.graphics.Color; /**  * Created by shy on 2015/11/3.  */ public class PieChartDataItem {  private String title;  private int value;  private float degrees;  public PieChartDataItem(String title, int value,int color) {   this.color = color;   this.title = title;   this.value = value;  }  private int color;  public int getColor() {   return color;  }  public void setColor(int color) {   this.color = color;  }  public String getTitle() {   return title;  }  public void setTitle(String title) {   this.title = title;  }  public int getValue() {   return value;  }  public void setValue(int value) {   this.value = value;  }  protected void setDegrees(float degrees){   this.degrees = degrees;  }  protected float getDegrees(){   return this.degrees;  } }  

在onDraw中,通过对画布(Canvas)的操作来绘制图形,在onMeasue中对View的大小进行设定。

自定义View属性

在构造方法中,对AttributeSet进行解析来加载xml中的自定义属性。

为了自定义属性。首先需要在资源文件中加入

    <declare-styleable name="PieChart">         <attr name="Radius" format="dimension" />         <attr name="Background" format="color" />     </declare-styleable> 

其中PieChart为类名,attr为各个属性,name为名称,format为属性类型,与代码中相对应,例如:integer,float,dimension,color等。

主Activity

代码很简单,仅仅为了使用自定义View

package com.shyling.customviewdemo; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity {  PieChart pieChart;  @Override  protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.activity_main);   pieChart = (PieChart) findViewById(R.id.piechart);   pieChart.addItem("Title1", 100, Color.GREEN);   pieChart.addItem("Title2", 110, Color.BLUE);   pieChart.addItem("Title3", 100, Color.YELLOW);   pieChart.addItem(new PieChartDataItem("Title4", 60, Color.LTGRAY));   pieChart.addItem("Title5", 120, Color.MAGENTA);   pieChart.setText("Text");   pieChart.cal();  } }  

布局:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  xmlns:app="http://schemas.android.com/apk/res-auto"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:paddingBottom="@dimen/activity_vertical_margin"  android:paddingLeft="@dimen/activity_horizontal_margin"  android:paddingRight="@dimen/activity_horizontal_margin"  android:paddingTop="@dimen/activity_vertical_margin"  tools:context="com.shyling.customviewdemo.MainActivity">  <com.shyling.customviewdemo.PieChart   android:id="@+id/piechart"   app:Radius="300dp"   app:background="@color/piechart_background"   android:layout_width="match_parent"   android:layout_height="match_parent" /> </RelativeLayout>  

效果图:

Android绘制自定义View的方法
正文到此结束
Loading...