固定支付宝收款图php记账,Android自定义控件实现支付宝记账饼图

本文实例为大家分享了Android实现支付宝记账饼图,点击旋转到最下面,供大家参考,具体内容如下

bfb4982f751285db8e4fe9e9d3c93e19.png

代码:

package com.example.a_102.myapplication7.ui;

import java.util.ArrayList;

import java.util.List;

import android.animation.Animator;

import android.animation.ValueAnimator;

import android.annotation.TargetApi;

import android.content.Context;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Rect;

import android.graphics.RectF;

import android.os.Build;

import android.text.TextUtils;

import android.util.AttributeSet;

import android.util.Log;

import android.view.MotionEvent;

import android.view.View;

import android.view.animation.AccelerateInterpolator;

import com.example.a_102.myapplication7.util.Util;

/**

*

*/

public class SelectPieView extends View {

private static final String TAG = "CustomPie_tag";

private int width;

private SelectPieCallBack mCallBack;

private boolean initPostion = false;

/**

* 当前选中的区域

*/

private int currentDownPostion;

public SelectPieView(Context context) {

super(context);

}

public SelectPieView(Context context, AttributeSet attrs) {

super(context, attrs);

}

public SelectPieView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int width;

int hight;

int widthmode = MeasureSpec.getMode(widthMeasureSpec);

int widthsize = MeasureSpec.getSize(widthMeasureSpec);

int hightmode = MeasureSpec.getMode(heightMeasureSpec);

int hightsize = MeasureSpec.getSize(heightMeasureSpec);

if (MeasureSpec.EXACTLY == widthmode) {

width = widthsize;

} else {

width = 200;

if (MeasureSpec.AT_MOST == widthmode) {

width = Math.min(widthsize, 200);

}

}

if (MeasureSpec.EXACTLY == hightmode) {

hight = hightsize;

} else {

hight = 200;

if (MeasureSpec.AT_MOST == hightmode) {

hight = Math.min(hightsize, 200);

}

}

setMeasuredDimension(Math.min(width, hight), Math.min(width, hight));

}

/**

* 笔宽

*/

private int mPaintWid;

/**

* 外边圆半径

*/

private int mOutRoot;

/**

* 内边圆半径

*/

private int mIntRoot;

/**

* 空白处宽度

*/

private int emptysize = -1;

/**

* 点击前的圆和点击后的圆半径差距

*/

private float betweenSize = 10;

/**

* 向限

*/

private int XIANGXAIN;

/**

* 开始的角度

*/

private float start = 360;

/**

* 旋转过的角度

*/

private List haveRoats = new ArrayList<>();

/**

*

*/

private String mTitle = "总消费";

/**

*

*/

private String mSubTitle = "00";

/**

*

*/

private String mSubTitleDot = "00";

/**

* 是否在运行

*/

private boolean isRun = true;

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

private Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

/**

* 整数部分

*/

private Paint textPaintSubTitle= new Paint(Paint.ANTI_ALIAS_FLAG);

/**

* 小数部分

*/

private Paint textPaintSubTitleDot= new Paint(Paint.ANTI_ALIAS_FLAG);

@Override

protected void onDraw(Canvas canvas) {

// reSetData();

if (null == datas || datas.size() == 0)

return;

width = getWidth();

mOutRoot = width / 2;

mPaintWid = Util.dip2px(getContext(), 40);

mIntRoot = mOutRoot - mPaintWid;

paint.setStyle(Paint.Style.STROKE);

paint.setColor(Color.RED);

paint.setStrokeWidth(mPaintWid);

RectF rt = new RectF(mPaintWid / 2 + betweenSize, mPaintWid / 2 + betweenSize,

width - mPaintWid / 2 - betweenSize, width - mPaintWid / 2 - betweenSize);

RectF rt2 = new RectF(mPaintWid / 2, mPaintWid / 2, width - mPaintWid / 2, width - mPaintWid / 2);

int size = datas.size();

float allValues = 0;

for (int i = 0; i < datas.size(); i++) {

allValues += datas.get(i).getValuse();

}

// allValues = allValues + emptysize * size;

float sigleSize = (360 - emptysize * datas.size()) / (allValues * 1f);

float end = 0;

haveRoats.clear();

for (int i = 0; i < size; i++) {

paint.setColor(getResources().getColor(datas.get(i).getColor()));

end = datas.get(i).getValuse() * sigleSize;

if (!isRun && datas.get(i).getPostion() == currentDownPostion && datas.size()>1) {

canvas.drawArc(rt2, start + 3, end - 6, false, paint);

canvas.drawArc(rt, start + 3, end - 6, false, paint);

} else {

canvas.drawArc(rt, start, end, false, paint);

}

Log.i(TAG, "first=" + start % 360 + "==" + end + "postion=" + datas.get(i).getPostion());

haveRoats.add(new startAndRoatData(datas.get(i).getPostion(), start % 360, end));

start = start + end + emptysize;

}

textPaint.setStrokeWidth(Util.dip2px(getContext(), 1));

/** 画图片 */

for (int i = 0; i < haveRoats.size(); i++) {

startAndRoatData startAndRoatData = haveRoats.get(i);

float x = 0;

float y = 0;

if (!isRun && currentDownPostion == haveRoats.get(i).getPostion() && datas.size()>1) {

x = (float) (Math

.cos(Math.PI / 180 * (startAndRoatData.getStartAng() + startAndRoatData.getRoatAng() / 2))

* (mIntRoot + mPaintWid / 2) + mOutRoot);

y = (float) (Math

.sin(Math.PI / 180 * (startAndRoatData.getStartAng() + startAndRoatData.getRoatAng() / 2))

* (mIntRoot + mPaintWid / 2) + mOutRoot);

} else {

x = (float) (Math

.cos(Math.PI / 180 * (startAndRoatData.getStartAng() + startAndRoatData.getRoatAng() / 2))

* (mIntRoot + mPaintWid / 2 - betweenSize) + mOutRoot);

y = (float) (Math

.sin(Math.PI / 180 * (startAndRoatData.getStartAng() + startAndRoatData.getRoatAng() / 2))

* (mIntRoot + mPaintWid / 2 - betweenSize) + mOutRoot);

}

Rect rect = new Rect((int) (x - mPaintWid / 3), (int) (y - mPaintWid / 3), (int) (x + mPaintWid / 3),

(int) (y + mPaintWid / 3));

int width = BitmapFactory.decodeResource(getResources(), datas.get(i).getIcon()).getWidth();

// L=n(圆心角度数)× π(圆周率)× r(半径)/180(角度制)

if (startAndRoatData.getRoatAng() * Math.PI * (mIntRoot + mPaintWid / 2) / 180 > width) {

canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), datas.get(i).getIcon()), null, rect,

null);

}

}

textPaint.setStyle(Paint.Style.FILL);

textPaint.setTextSize(Util.dip2px(getContext(), 14));

/** 写文字 */

canvas.drawText(mTitle, width / 2 - (textPaint.measureText(mTitle)) / 2,

width / 2 - Util.dip2px(getContext(), 8), textPaint);

textPaintSubTitle.setTextSize(Util.dip2px(getContext(), 20));

canvas.drawText(mSubTitle,

width / 2 - (textPaintSubTitle.measureText(mSubTitle)) / 2 - (textPaintSubTitleDot.measureText("."+mSubTitleDot) / 2),

width / 2 + Util.dip2px(getContext(), 15), textPaintSubTitle);

textPaintSubTitleDot.setTextSize(Util.dip2px(getContext(), 15));

canvas.drawText("." + mSubTitleDot,

width / 2 + textPaintSubTitle.measureText(mSubTitle) /2 - (textPaintSubTitleDot.measureText("." + mSubTitleDot))/2,

width / 2 + Util.dip2px(getContext(), 15), textPaintSubTitleDot);

//Toast.makeText(getContext(), "=="+textPaint.measureText(mSubTitle), Toast.LENGTH_SHORT).show();

/** 测试基线 */

/*

* paint.setColor(Color.BLACK);

* paint.setStrokeWidth(Util.dip2px(getContext(), 1));

*

* canvas.drawLine(0, width / 2, width, width / 2, paint);

* canvas.drawLine(width / 2, 0, width / 2, width, paint);

*/

/**

* 初始化位置

* */

if (!initPostion) {

initPostion = true;

startAndRoatData roatData = haveRoats.get(0);

float currentCenterAng = roatData.getStartAng() + roatData.getRoatAng() / 2;

if (currentCenterAng < 90) {

starRoat(start, start + 90 - (roatData.getStartAng() + roatData.getRoatAng() / 2), false);

} else if (currentCenterAng > 90 && currentCenterAng < 270) {

starRoat(start, start - (currentCenterAng - 90), false);

} else {

starRoat(start, start + 360 + 90 - (roatData.getStartAng() + roatData.getRoatAng() / 2), false);

}

currentDownPostion = roatData.getPostion();

isRun = false;

invalidate();

}

}

/**

* 设置显示金额

*

* @param number

*/

public void setNumber(String number) {

if (TextUtils.isEmpty(number)) {

number = "0.00";

}

if (number.contains(".")) {

String[] split = number.split("\\.");

mSubTitle = split[0];

mSubTitleDot = split[1];

} else {

mSubTitle = number;

mSubTitleDot = "00";

}

if (mSubTitleDot.length() > 2) {

mSubTitleDot = mSubTitleDot.substring(0, 2);

}

}

private int Lxy2;

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

float x = event.getX();

float y = event.getY();

double atan = Math.atan((x - mOutRoot) / (mOutRoot - y));

double currntAngle = (atan / Math.PI * 180);

double clickAngle = 0;

Lxy2 = (int) Math.pow(x - mOutRoot, 2) + (int) Math.pow(mOutRoot - y, 2);

if (Math.pow(mIntRoot, 2) < Lxy2 && Lxy2 < Math.pow(mOutRoot, 2)) {

if (x > width / 2 && y > width / 2) {

/** currntAngle第四象限是负数 */

// starRoat(start, (float) (start - currntAngle), true);

clickAngle = currntAngle +90;

} else if (x > width / 2 && y < width / 2) {

/** currntAngle第一象限是负数 */

//starRoat(start, (float) (start + 180 - currntAngle), true);

clickAngle = currntAngle +270;

} else if (x < width / 2 && y < width / 2) {

/** currntAngle第二象限是正数 */

//starRoat(start, (float) (start - (180 - Math.abs(currntAngle))), true);

clickAngle = currntAngle +270;

} else {

/** currntAngle第三象限是正数 */

//starRoat(start, (float) (start - Math.abs(currntAngle)), true);

clickAngle = currntAngle +90;

}

int i = clickDownPostion(clickAngle);

startAndRoatData roatData = haveRoats.get(i);

currentDownPostion = roatData.getPostion();

float currentCenterAng = roatData.getStartAng() + roatData.getRoatAng() / 2;

if (currentCenterAng < 90) {

starRoat(start, start + 90 - (roatData.getStartAng() + roatData.getRoatAng() / 2), true);

} else if (currentCenterAng > 90 && currentCenterAng < 270) {

starRoat(start, start - (currentCenterAng - 90), true);

} else {

starRoat(start, start + 360 + 90 - (roatData.getStartAng() + roatData.getRoatAng() / 2), true);

}

}

return true;

}

return super.onTouchEvent(event);

}

private int clickDownPostion(double clickAngle) {

for (int i = 0; i < haveRoats.size(); i++) {

startAndRoatData data = haveRoats.get(i);

if ((data.getStartAng() < clickAngle && data.getStartAng() + data.getRoatAng() > clickAngle)

|| (data.getStartAng() + data.getRoatAng() > 360

&& ((data.getStartAng() + data.getRoatAng()) % 360) > clickAngle)) {

return i;

}

}

return 0;

}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)

public void starRoat(final float star, final float end, boolean isSmooth) {

ValueAnimator valueAnimator = ValueAnimator.ofFloat(star, end);

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

float animatedValue = (float) animation.getAnimatedValue();

start = animatedValue;

isRun = true;

invalidate();

}

});

valueAnimator.setDuration(isSmooth ? (long) (700) : 10);

valueAnimator.setInterpolator(new AccelerateInterpolator());

valueAnimator.start();

valueAnimator.addListener(new Animator.AnimatorListener() {

@Override

public void onAnimationStart(Animator animation) {

}

@Override

public void onAnimationEnd(Animator animation) {

if (currentDownPostion == -1) {

start++;

starRoat(start, start++, false);

} else {

isRun = false;

invalidate();//画突出部分

mCallBack.currentPostion(currentDownPostion);

}

}

@Override

public void onAnimationCancel(Animator animation) {

}

@Override

public void onAnimationRepeat(Animator animation) {

}

});

}

private List datas = new ArrayList<>();

public void reSetData(List data) {

datas.clear();

datas.addAll(data);

float all =0;

for (PieData da : datas) {

all += da.getValuse();

}

if (all < 360) {

for (PieData da : datas) {

da.setValuse(da.getValuse() * 200);

}

}

for (PieData da : datas) {

all += da.getValuse();

}

/**强制设置最低值*/

for (PieData da : datas) {

if (da.getValuse() / all < 0.03) {

da.setValuse((float) (all * 0.03));

}

}

invalidate();

}

/**

* 判断当前选择的所在区间

*

* @return

*/

private int findCurrentDownPostion() {

if (haveRoats == null || haveRoats.size() <= 0) {

return 1;

}

for (int i = 0; i < haveRoats.size(); i++) {

float startAng = haveRoats.get(i).getStartAng();

float roatAng = haveRoats.get(i).getRoatAng();

//Utility.Logi(TAG, "currentpostion=sstar=" + startAng + "===rroat=" + roatAng);

if (startAng < 90 && (startAng <= 90 && startAng + roatAng > 90)) {

// Utility.Logi(TAG, "currentpostion=" + haveRoats.get(i).getPostion());

return haveRoats.get(i).getPostion();

} else if (startAng > 90 && startAng - 360 + roatAng > 90) {

//Utility.Logi(TAG, "currentpostion=" + haveRoats.get(i).getPostion());

return haveRoats.get(i).getPostion();

}

}

return -1;

}

public void setCallBack(SelectPieCallBack callBack) {

this.mCallBack = callBack;

}

public interface SelectPieCallBack {

void currentPostion(int postion);

}

public static class PieData {

public PieData(int postion, float valuse, int color, int icon) {

this.postion = postion;

this.valuse = valuse;

this.color = color;

this.icon = icon;

}

private int postion;

private float valuse;

private int color;

private int icon;

public int getPostion() {

return postion;

}

public void setPostion(int postion) {

this.postion = postion;

}

public float getValuse() {

return valuse;

}

public void setValuse(float valuse) {

this.valuse = valuse;

}

public int getColor() {

return color;

}

public void setColor(int color) {

this.color = color;

}

public int getIcon() {

return icon;

}

public void setIcon(int icon) {

this.icon = icon;

}

}

class startAndRoatData {

private int postion;

private float startAng;

private float roatAng;

public startAndRoatData(int postion, float startAng, float roatAng) {

this.postion = postion;

this.startAng = startAng;

this.roatAng = roatAng;

}

public int getPostion() {

return postion;

}

public void setPostion(int postion) {

this.postion = postion;

}

public float getStartAng() {

return startAng;

}

public void setStartAng(float startAng) {

this.startAng = startAng;

}

public float getRoatAng() {

return roatAng;

}

public void setRoatAng(float roatAng) {

this.roatAng = roatAng;

}

@Override

public String toString() {

return "startAndRoatData{" + "postion=" + postion + ", startAng=" + startAng + ", roatAng=" + roatAng + '}';

}

}

}

用法如下:

SelectPieView mPie = (SelectPieView) findViewById(R.id.pie);

mPie.setCallBack(new SelectPieView.SelectPieCallBack() {

@Override

public void currentPostion(int postion) {

Toast.makeText(CustomViewActivity.this, "postion="+postion, Toast.LENGTH_SHORT).show();

}

});

ArrayList datas = new ArrayList<>();

datas.add(new SelectPieView.PieData(1, 200.3f, R.color.read_color, R.drawable.arrow));

datas.add(new SelectPieView.PieData(2, 200.3f, R.color.hx_red, R.drawable.arrow));

datas.add(new SelectPieView.PieData(3, 200.3f, R.color.text_blue, R.drawable.arrow));

mPie.reSetData(datas);

mPie.setNumber("333.33");

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值