自定义控件(一) 一个比例饼状图
来源:互联网 发布:金融公司网络推广 编辑:程序博客网 时间:2024/04/30 02:28
前言:看了很多鸿洋的文章,感觉受益匪浅,正巧 今天在android聊天群里看到有这个需求,发现和鸿洋的这篇博客(http://blog.csdn.net/lmj623565791/article/details/24500107)很类似,正好我项目也不忙,我就自己实现了一下。
前期分析:外面的圆环就是根据比例把圆弧画出来就可以了,里边的文字和图片,刚看时我是想也画出来,但是后来考虑如果里边的东西以后改变了,修改起来也是很麻烦的,于是我就改成勇相对布局嵌套一下,我想这样也是更好实现,扩展性也比较好。
一,首先分析一下这个图
这个图外边圆环中圆弧的比例需要传递过来,颜色也需要指定,和外环的宽度也要指定,比例和颜色应该用集合的形式传递,而圆环的宽度可以用自定义属性。
-----------------------------------------------------------------------------------------------------
1.自定义属性
<resources> <attr name="strokeWidth" format="dimension" /> <declare-styleable name="RoundChatView"> <attr name="strokeWidth" /> </declare-styleable></resources>
2.获取我们自定义的属性
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RoundChatView, defStyleAttr, 0);int n = a.getIndexCount();for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.RoundChatView_strokeWidth: // 圆环宽度 mStrokeWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics())); break; }}
3.重写onDraw()方法
@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); mWidth = getWidth(); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mStrokeWidth); // 设置圆环的宽度 int centre = mWidth / 2; // 获取圆心的x坐标 int radius = centre - mStrokeWidth / 2;// 半径 RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限 // 画圆环 for (int i = 0; i < mCount; i++) { float degree = mDegree.get(i); lastDegree += degree; mPaint.setColor(i > mColor.length ? mColor[i - mColor.length] : mColor[i]); // 循环取颜色值 canvas.drawArc(oval, -90 - lastDegree, degree, false, mPaint); // 根据角度画圆弧 }}
4.在布局中使用
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" 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.aijie.viewandgroupapp.MainActivity"> <com.aijie.viewandgroupapp.view.RoundChatView android:id="@+id/roundChat" android:layout_width="300dp" android:layout_height="300dp" android:layout_centerInParent="true" custom:strokeWidth="50dp" /> <LinearLayout android:layout_width="150dp" android:layout_height="150dp" android:layout_centerInParent="true" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="总支出" android:textColor="#666666" android:textSize="17sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="12120.00" android:textColor="#666666" android:textSize="26sp" android:textStyle="bold" /> <ImageView android:layout_width="30dp" android:layout_height="30dp" android:layout_marginTop="25dp" android:src="@drawable/icon_center" /> </LinearLayout></RelativeLayout>
5.在代码中设置
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); act = this; roundChat = (RoundChatView) findViewById(R.id.roundChat); List<Float> ratioList = new ArrayList<Float>(); ratioList.add(0.2f); ratioList.add(0.1f); ratioList.add(0.35f); ratioList.add(0.2f); ratioList.add(0.15f); // 设置饼状图的比例 roundChat.setCount(5, ratioList);}
6.最终效果图
基本实现效果,具体的颜色控制可以再优化。
这个附上这个自定义控件的源码:
package com.aijie.viewandgroupapp.view;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.util.Log;import android.util.TypedValue;import android.view.View;import com.aijie.viewandgroupapp.R;import java.util.ArrayList;import java.util.List;/** * Created by Administrator on 2016/7/8 0008. * 饼状图 */public class RoundChatView extends View { private Context mContext; /** * 控件的宽度 */ private int mWidth; /** * 圆环的宽度 */ private int mStrokeWidth; /** * 画笔 */ private Paint mPaint; /** * 一共多少份 */ private int mCount = 0; /** * 每份所占的比例 */ private List<Float> mList = new ArrayList<Float>(); /** * 饼状图每块的颜色 */ private int[] mColor = {Color.RED, Color.BLUE, Color.YELLOW, Color.GREEN, Color.BLUE}; /** * 存储没份所占的角度 */ private List<Float> mDegree = new ArrayList<>(); public RoundChatView(Context context) { this(context, null); } public RoundChatView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RoundChatView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // 获取自定义的属性 TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RoundChatView, defStyleAttr, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.RoundChatView_strokeWidth: // 圆环宽度 mStrokeWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics())); break; } } } private void initData(Context context) { // 计算角度 if (mList.size() > 0) { for (int i = 0; i < mList.size(); i++) { Float ratio = mList.get(i); Float degree = 360 * ratio; mDegree.add(degree); } } } /** * 设置份数和所占比例 * * @param count * @param list */ public void setCount(int count, List<Float> list) { this.mCount = count; this.mList = list; initData(mContext); } private int lastDegree = 0; //已经画过的角度 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mWidth = getWidth(); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mStrokeWidth); // 设置圆环的宽度 int centre = mWidth / 2; // 获取圆心的x坐标 int radius = centre - mStrokeWidth / 2;// 半径 RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限 // 画圆环 for (int i = 0; i < mCount; i++) { float degree = mDegree.get(i); Log.i("aijie", "角度==" + degree); lastDegree += degree; mPaint.setColor(i > mColor.length ? mColor[i - mColor.length] : mColor[i]); // 循环取颜色值 canvas.drawArc(oval, -90 - lastDegree, degree, false, mPaint); // 根据角度画圆弧 } }}
0 0
- 自定义控件(一) 一个比例饼状图
- 自定义控件:等比例显示控件RatioLayout
- 234_自定义一个百分比例的环形饼状图
- 自定义宽高比例的布局控件
- 自定义控件【按照宽高比例显示】
- 自定义图片比例适配控件 ProportionImageView
- 【一】控件等比例缩放EasySize.h
- android自定义可任意调节比例的控件
- Android自定义控件之矩形View(长宽比例限制)
- Android开发自定义控件实现一个饼状图
- 自定义控件(一)
- 自定义控件(一)
- 自定义UIPageControl 控件(一)
- 自定义UIPageControl 控件(一)
- 自定义控件(一)
- 自定义控件一
- 自定义控件(一)
- Android自定义控件(一)
- Maven骨架archetype
- Day01(HTML)
- Android 设计模式 笔记 - 策略模式
- 微软Detours链接地址
- 项目从wins到linux
- 自定义控件(一) 一个比例饼状图
- linux下编译Qt/E x86 的问题:cmpxchg和cmpxchgl
- 丑数
- nodejs 连接数据库
- 模拟示波器使用总结
- Android驱动开发1——NDK模型
- BZOJ2276 [Poi2011]Temperature
- 解决由于vlc调速播放导致的系统无声音, ubuntu14.04
- 对laravel5概念的理解 -- 资源库模式(Repository)