android自定义View实现会议时间的占比效果

android自定义View实现会议时间的占比效果

效果图

效果图

代码

自定义View类

		现在对刻度采用了写死的方式 为了效果展示。实际使用过程中需要根据真是数据计算刻度值。
public class CustomV2 extends View
{
	Paint paint = new Paint();
	Paint textPaint = new Paint();
	private int bgColor = Color.GRAY;
	private int secondColor = Color.parseColor("#FB8152");
	private int textColorGray = bgColor;
	private int textColorOrange = secondColor;
	private int textSize = 16;

	//已有会议分段
	//一共能进行 10小时会议。持续时间除以总时间得到所占时间条的百分比。然后算出起始位置,画上去即可。
	private String[] useTimeValues = {
			//持续时间为3小时。起始位置为x轴0点,终点为 3/(18-8) = 3/10;
			"08:00~11:00",
			//持续时间为0.5小时。起始位置在(3.5/10),终点为 4/10;
			"11:30~12:00",
			//持续时间为2小时15分钟,起始位置在(13:15 - 08:00)/10,终点为起点位置+(2小时15分钟/10)
			"13:15~15:30",
			//持续时间为1小时30分钟,起始位置在(16:30 - 08:00)/10,终点为起点位置+(1小时30分钟/10)
			"16:30~18:00"
	};
	// 根据值 需要全部换算成分钟 进行计算
	//第二个值:持续时间2*60+15 = 135,起始位置 (5*60+15)/(10*60)= 21/40,终点位置为 (21/40 + 27/120) = 3/4
	//第三个值:持续时间1*60+30 = 90,起始位置 (8*60+30)/(10*60) =17/20, 终点位置为 (17/20 + 3/20) = 1。即终点
	//此数组值是根据useTimeValues 计算出来的,实际使用过程中自己计算即可。
	private float[][] usePercentValues = {
			{0f,12f / 40f},
			{7f / 20f,2f / 5f},
			{21f / 40f, 30f / 40f},
			{34f / 40f,1f}};
	//下标
	private String[] timeValues = {
			"08:00",
			"10:00",
			"12:00",
			"14:00",
			"16:00",
			"18:00"
	};
	//	画三角形
	private Path path;

	public CustomV2(Context context)
	{
		this(context, null);
	}

	public CustomV2(Context context, @Nullable AttributeSet attrs)
	{
		this(context, attrs, 0);
	}

	public CustomV2(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
	{
		super(context, attrs, defStyleAttr);

		paint.setAntiAlias(true);
		paint.setStyle(Paint.Style.FILL);
		textPaint.setTextSize(textSize * 2);
		textPaint.setAntiAlias(true);
		textPaint.setStyle(Paint.Style.FILL);
		path = new Path();
	}

	// 重写onDraw方法
	@Override
	protected void onDraw(Canvas canvas)
	{
		super.onDraw(canvas);
		int width = getWidth();
		int height = getHeight();
		// 一共分为三行。第一行 显示橙色文字提示 三角形状为长度为30px,高度为20px
		textPaint.setColor(textColorOrange);
		for(int i = 0; i < useTimeValues.length; i++)
		{
			float startX = usePercentValues[i][0] * width;
			float endX = usePercentValues[i][1] * width;
			Log.e("canvas", "获取刻度起止位置:" + startX + "," + endX);
			// 如果持续时间刻度长度 不够文本显示的长度(eg 08:00~12:00)需要特殊处理 这里判断下
			// 当文本长度小于 刻度长度时,在刻度区间居中显示
			textPaint.setTextSize(textSize * 1.5f);
			float txtWidth = textPaint.measureText(useTimeValues[i]);
			if(txtWidth <= (endX - startX))
			{
				float x = startX + ((endX - startX) / 2 - txtWidth / 2);
				canvas.drawText(useTimeValues[i], x, height / 3 - 20, textPaint);
				Log.e("canvas", "画第一行文字-1:" + x);
			}//当文本长度大于刻度长度时
			else
			{
				// 判断刻度终点位置是否大于文本长度
				if(endX > txtWidth)
				{
					float x = startX - (txtWidth / 2 - (endX - startX) / 2);
					canvas.drawText(useTimeValues[i], x, height / 3 - 20, textPaint);
					Log.e("canvas", "画第一行文字-2:" + x);
				}
				else
				{
					canvas.drawText(useTimeValues[i], 0, height / 3 - 20, textPaint);
					Log.e("canvas", "画第一行文字-3:" + 0);
				}
			}
			float triangleX1 = startX + (endX - startX - 20) / 2;
			float triangleX2 = startX + (endX - startX - 20) / 2 + 10;
			float triangleX3 = startX + (endX - startX - 20) / 2 + 20;
			path.reset();
			path.moveTo(triangleX1, height / 3);
			path.lineTo(triangleX2, height / 3 - 15);
			path.lineTo(triangleX3, height / 3);
			path.close();
			canvas.drawPath(path, textPaint);
			textPaint.setTextSize(textSize * 2f);
		}

		// 第二行  画中间的背景条 高度为View高度的1/3。宽度占满
		//背景底色
		paint.setColor(bgColor);
		canvas.drawRect(0, height / 3, width, height / 3 * 2, paint);
		//第二层颜色 先画一部分用于显示
		paint.setColor(secondColor);
		for(float[] usepercentValue : usePercentValues)
		{
			float left = usepercentValue[0] * width;
			float right = usepercentValue[1] * width;
			canvas.drawRect(left, height / 3, right, height / 3 * 2, paint);
			Log.e("canvas", "画刻度坐标起止位置:" + left + "," + right);
		}
		// 第三行 显示时间文本08:00~18:00, 绘制文本 是以文本左下角为(0,0)点,不是右上角。
		textPaint.setColor(textColorGray);
		for(int i = 0; i < timeValues.length; i++)
		{
			canvas.drawText(timeValues[i], width * i / timeValues.length, height / 3 * 2 + 40, textPaint);
		}
	}
}

调用

public class TestAct extends AppCompatActivity
{
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.act_test);
		FrameLayout container = findViewById(R.id.container);
		CustomV2 customV2 = new CustomV2(this);
		FrameLayout.LayoutParams params1 = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(90));
		params1.setMargins(20, 0, 20, 0);
		container.addView(customV2, params1);
	}
	/**
	 * 根据手机分辨率从DP转成PX
 	 */
	public int dp2px(float dpValue)
	{
		float scale = getResources().getDisplayMetrics().density;
		return (int)(dpValue * scale + 0.5f);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值