android自定义控件之中间是斜线的占比条
来源:互联网 发布:淘宝如何设置客户权限 编辑:程序博客网 时间:2024/05/24 06:03
最近一直在看各路大神的自定义控件,自己受益非浅,可是一直也没有自己动手写一个,这几天有一个项目中要求有如下图这样一个功能:
两个动态值,根据其占比,在这个横柱上显示出来,中间的隔线要有一定的斜角。
在网上找了半天,没有发现什么现成的。突然想到,学了这么长时间自定义控件了,感觉这个也不是很难,就自己做一个试试呗。先理清一下思路。
首先,这个不能采用画矩形图,因为中间无法成斜线,可以采用Path的方法。用路径 的方法画来。里面的百分比,直接进行百分比计算就完了,没什么特别的地方,显示百分比会有两种情况,一种是图中的样子,两部分全有值,百分比显示在左右两边, 另一种是其中一个值为0,则另一个会为100%,这样让百分比显示在中间。这个加一个判断也就OK了。这样简单分析一下,感觉很简单没什么东西了。下面给出代码:
attrs.xml这里定义一些属性
<?xml version="1.0" encoding="utf-8"?><resources> //自定义属性名,定义公共属性 <attr name="iNum" format="float" /> <attr name="iColor" format="color" /> <attr name="oNum" format="float" /> <attr name="oColor" format="color" /> <attr name="Inclination" format="integer"/> <attr name="iTextColor" format="color" /> <attr name="TextSize" format="dimension" /> <attr name="oTextColor" format="color" /> //自定义控件的主题样式 <declare-styleable name="MyPre"> <attr name="iNum" /> <attr name="iColor" /> <attr name="oNum" /> <attr name="oColor" /> <attr name="Inclination" /> <attr name="iTextColor" /> <attr name="TextSize" /> <attr name="oTextColor" /> </declare-styleable></resources>
mPre.java
package com.example.cg.custompre.custom;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Rect;import android.util.AttributeSet;import android.util.TypedValue;import android.view.View;import com.example.cg.custompre.R;import java.text.DecimalFormat;/** * 自定义百分比左右进度条,根据两个值的百分比不同,在一个进度条中显示出来,中间的隔线为斜线 * Created by cg on 2016/7/28 0028. */public class mPre extends View { private float iNum = 50; //进(左)的数量 private int iColor = Color.RED; //进的颜色 private float oNum = 50; //出(右)的数量 private int oColor = Color.GREEN; //出的颜色 private int mInclination = 40; //两柱中间的倾斜度 private int iTextColor = Color.WHITE; //进的百分比数字颜色 private int oTextColor = Color.WHITE; //出的百分比数字颜色 private int TextSize = 30; //百分比字体大小 private float iPre; private float oPre; private String txtiPre; //显示进的百分比 private String txtoPre; //显示出的百分比 private Paint mPaint; private Rect mBound; //包含文字的框 public mPre(Context context) { this(context, null); } public mPre(Context context, AttributeSet attrs) { this(context, attrs, 0); } public mPre(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray arry = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyPre,defStyleAttr,0); int n = arry.getIndexCount(); for(int i=0;i<n;i++) { int attr = arry.getIndex(i); switch (attr) { case R.styleable.MyPre_iNum: iNum = arry.getFloat(attr, 50); break; case R.styleable.MyPre_iColor: iColor = arry.getColor(attr, Color.RED); break; case R.styleable.MyPre_oNum: oNum = arry.getFloat(attr, 50); break; case R.styleable.MyPre_oColor: oColor = arry.getColor(attr,Color.GREEN); break; case R.styleable.MyPre_Inclination: mInclination = arry.getInt(attr,40); break; case R.styleable.MyPre_iTextColor: iTextColor = arry.getColor(attr,Color.WHITE); break; case R.styleable.MyPre_oTextColor: oTextColor = arry.getColor(attr,Color.WHITE); break; case R.styleable.MyPre_TextSize: TextSize = arry.getDimensionPixelSize(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); break; } } arry.recycle(); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); mPaint.setStrokeWidth(5); mBound = new Rect(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width ; int height ; if(widthMode==MeasureSpec.EXACTLY) { width = widthSize; }else { width = getPaddingLeft() + getWidth() + getPaddingRight(); } if(heightMode==MeasureSpec.EXACTLY) { height = heightSize; }else { height = getPaddingTop() + getHeight() + getPaddingBottom(); } setMeasuredDimension(width,height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); iPre = (iNum /(iNum + oNum)) * getWidth(); oPre = (oNum /(iNum + oNum)) * getWidth(); //Log.e("mPre", "iPre:" + iPre + " oPre:" + oPre + "width" + getWidth()); //如果进值或出值有一个为0,则另一个就会占满整个进度条,这时就不需要倾斜角度了 if(iNum==0 || oPre==0) { mInclination = 0; } Path iPath = new Path(); iPath.moveTo(0, 0); iPath.lineTo(iPre + mInclination, 0); iPath.lineTo(iPre, getHeight()); iPath.lineTo(0, getHeight()); iPath.close(); mPaint.setColor(iColor); canvas.drawPath(iPath, mPaint); Path oPath = new Path(); oPath.moveTo(iPre + mInclination, 0); oPath.lineTo(getWidth(), 0); oPath.lineTo(getWidth(), getHeight()); oPath.lineTo(iPre - mInclination, getHeight()); oPath.close(); mPaint.setColor(oColor); canvas.drawPath(oPath, mPaint); txtiPre = getProValText(iNum /(iNum + oNum) * 100); txtoPre = getProValText(oNum /(iNum + oNum) * 100); mPaint.setColor(iTextColor); mPaint.setTextSize(TextSize); mPaint.getTextBounds(txtiPre, 0, txtiPre.length(), mBound); //判断一下,如果进值为0则不显示,如果进值不为空而出值为0,则进值的数值显示居中显示 if(iNum!=0 && oNum!=0) { canvas.drawText(txtiPre, 20, getHeight() / 2 + mBound.height() / 2, mPaint); }else if(iNum!=0 && oNum==0){ canvas.drawText(txtiPre, getWidth()/2 - mBound.width()/2, getHeight() / 2 + mBound.height() / 2, mPaint); } mPaint.setColor(oTextColor); mPaint.getTextBounds(txtoPre, 0, txtoPre.length(), mBound); if(oNum!=0 && iNum!=0) { canvas.drawText(txtoPre, getWidth() - 20 - mBound.width(), getHeight() / 2 + mBound.height() / 2, mPaint); }else if(oNum!=0 && iNum==0){ canvas.drawText(txtoPre, getWidth()/2 - mBound.width()/2, getHeight() / 2 + mBound.height() / 2, mPaint); } } /** * 格式化显示的百分比 * @param proValue * @return */ private String getProValText(float proValue) { DecimalFormat format = new DecimalFormat("#0.0"); return format.format(proValue) + "%"; } /** * 动态设置进值 * @param iNum */ public void setINum(float iNum) { this.iNum = iNum; postInvalidate(); } /** * 动态设置出值 * @param oNum */ public void setONum(float oNum) { this.oNum = oNum; postInvalidate(); }}
调用的时候:
布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context="com.example.cg.custompre.MainActivity" android:orientation="vertical"> <com.example.cg.custompre.custom.mPre android:id="@+id/myPre" android:layout_width="match_parent" android:layout_height="50dp" android:layout_margin="100dp" app:TextSize="14dp"/> <Button android:id="@+id/btn_Add" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="变化开始"/></LinearLayout>
MainActivity.java
package com.example.cg.custompre;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import com.example.cg.custompre.custom.mPre;public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button btn_Add; private mPre myPre; private int iNum = 50; private int oNum = 50; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initControls(); } /** * 初始化控件 */ private void initControls() { myPre = (mPre)findViewById(R.id.myPre); btn_Add = (Button)findViewById(R.id.btn_Add); btn_Add.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btn_Add: iNum = iNum + 5; myPre.setINum(iNum); //myPre.setONum(0); break; } }}
0 0
- android自定义控件之中间是斜线的占比条
- android自定义控件之滚动广告条
- android自定义控件之滚动广告条
- Android自定义控件之拖动条
- Android 自定义控件之滚动字幕条
- Android自定义view 圆环占比 动画绘制
- Android自定义view绘制圆环占比动画
- android机型占比
- PWM的周期和占空比是如何计算
- Android 控件之RatingBar评分条(五星)自定义样式
- Android自定义控件之实现一个球赛比分条
- Android自定义音量条控件
- Android自定义控件-等级条
- 自定义控件-中间画线的view
- VerticalBannerView 是一个 android 平台下的自定义控件,通常用来展示广告,类似淘宝头条
- Android自定义控件之——文字圆形边框(将文字绘制在圆中间)
- Android自定义控件之——文字圆形边框(将文字绘制在圆中间)
- Android学习笔记之RatingBar1>简介 RatingBar为评分条控件,默认效果为若干个绿色的星星,如果想将其换成其他自定义图片就要自定义它的style。 RatingBar是SeekBa
- JAVA总结
- nlogn最长单调递增
- ASP.NET Core 开发-Logging 使用NLog 写日志文件
- Java日历横向输出
- 我的奋斗
- android自定义控件之中间是斜线的占比条
- FXBlurView模糊图片处理
- a20 nand更换emmc 版本sdk修改记录
- CS231n winter 2016 学习笔记lecture 1
- 摇杆的简单使用 Unity3d
- MySQL学习笔记(1)视图操作
- 设置Office 365移动设备管理MDM服务——创建APNs证书
- java string 字符串替换:replace
- xmpp协议框架包介绍:org.xmpp.packet.Packet+JID+PacketInterceptor+Session