五边形最后的效果图:
/**
* 自定义一个五边型,定义5个固定点,然后相连
* @author guotianhui
*/
public class PentagonView extends View {
private Paint paint;
private Context mContext;
private int mLinesColor;
private Path path, pathTwo;
private int mFirstMarginTop; // 设置第一个矩形距离头部的高度
private int mSecondMarginTop; //设置第二个矩形距离头部的高度00
private int mFirstRecHeight;//设置第一个矩形的高
private int mSecondRecHight; //设置第二个矩形的高
private int mDebugTopTextMargin;
private int mDebugTextLeftMargin; //根据文字的长度,适配左边文字位置
private int mDebugTextRightMargin; //根据文字长度,适配右边文字的间距
private boolean mIsSetPointColor;
private int mDebugMargin =dp2px(8);
private int mHeadLayoutTopMargin ;
private FrameLayout mHeaderImageView;
private int mExpainTextColor,mPentagonTextSize;
private String mPointOneText,mPointTowText,mPointThereText,mPointFourText,mPointFiveText;
public PentagonView(Context context) {
super(context);
this.mContext = context;
}
public PentagonView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
}
public PentagonView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//动态设置头像布局距离顶部的距离/
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(-2, -2);
layoutParams.topMargin = mHeadLayoutTopMargin;
layoutParams.gravity = Gravity.CENTER_HORIZONTAL;
mHeaderImageView.setLayoutParams(layoutParams);
//设置五边形距离顶部的高度,让头像始终在布局中间
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(-2, -2);
params.topMargin = mHeadLayoutTopMargin -dp2px(75);
params.gravity = Gravity.CENTER_HORIZONTAL;
setLayoutParams(params);
//设置五边形的外形
mFirstMarginTop = dp2px(25);
mSecondMarginTop = mFirstMarginTop +dp2px(15);
mFirstRecHeight = mHeaderImageView.getWidth()+dp2px( 60);
mSecondRecHight = mHeaderImageView.getWidth()+dp2px(35);
//创建一支画笔
paint = new Paint();
paint.setColor(mLinesColor);
paint.setAntiAlias(true);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.STROKE);
//获取屏幕的宽高
WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display defaultDisplay = windowManager.getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
defaultDisplay.getMetrics(displayMetrics);
int width = displayMetrics.widthPixels;
//创建一个路径
path = new Path();
path.moveTo(width/2,mFirstMarginTop+mDebugMargin+dp2px(8)); // 第一个点
path.lineTo((width/2)-(mFirstRecHeight/2),mFirstRecHeight/2+mFirstMarginTop);//第二个点
path.lineTo(width/2 -(mFirstRecHeight/3),mFirstMarginTop+mFirstRecHeight+mDebugMargin);//第三个点
path.lineTo(width/2+(mFirstRecHeight/3) ,mFirstMarginTop+mFirstRecHeight+mDebugMargin);//第四个点
path.lineTo((width/2)+(mFirstRecHeight/2),mFirstRecHeight/2+mFirstMarginTop);//第五个点
path.close();
canvas.drawPath(path,paint);
//画一个更大的五边形
pathTwo = new Path();
pathTwo.moveTo(width/2,mSecondMarginTop+mDebugMargin+dp2px(5)); // 第一个点
pathTwo.lineTo((width/2)-(mSecondRecHight/2),mSecondRecHight/2+mSecondMarginTop);//第二个点
pathTwo.lineTo(width/2 -(mSecondRecHight/3),mSecondMarginTop+mSecondRecHight+mDebugMargin);//第三个点
pathTwo.lineTo(width/2+(mSecondRecHight/3) ,mSecondMarginTop+mSecondRecHight+mDebugMargin);//第四个点
pathTwo.lineTo((width/2)+(mSecondRecHight/2),mSecondRecHight/2+mSecondMarginTop);//第五个点
pathTwo.close();
canvas.drawPath(pathTwo,paint);
//画五个不同颜色的点
paint.setStyle(Paint.Style.FILL);
//是否设置点的不同颜色
if(mIsSetPointColor) {
paint.setColor(Color.parseColor("#C84D17"));
canvas.drawCircle(width / 2, mFirstMarginTop+mDebugMargin+dp2px(8), dp2px(4), paint); // 第一个点
paint.setAlpha(30);
canvas.drawCircle(width / 2, mFirstMarginTop+mDebugMargin+dp2px(8), dp2px(8), paint); // 第一个点
paint.setColor(Color.parseColor("#F9B89B"));
canvas.drawCircle((width / 2) - (mFirstRecHeight / 2), mFirstRecHeight / 2 + mFirstMarginTop, dp2px(4), paint); //第二个点
paint.setAlpha(30);
canvas.drawCircle((width / 2) - (mFirstRecHeight / 2), mFirstRecHeight / 2 + mFirstMarginTop, dp2px(8), paint); //第二个点
paint.setColor(Color.parseColor("#F19A74"));
canvas.drawCircle(width / 2 - (mFirstRecHeight / 3), mFirstMarginTop + mFirstRecHeight+mDebugMargin, dp2px(4), paint);//第三个点
paint.setAlpha(30);
canvas.drawCircle(width / 2 - (mFirstRecHeight / 3), mFirstMarginTop + mFirstRecHeight+mDebugMargin, dp2px(8), paint);//第三个点
paint.setColor(Color.parseColor("#E7865B"));
canvas.drawCircle(width / 2 + (mFirstRecHeight / 3), mFirstMarginTop + mFirstRecHeight+mDebugMargin, dp2px(4), paint);//第四个点
paint.setAlpha(30);
canvas.drawCircle(width / 2 + (mFirstRecHeight / 3), mFirstMarginTop + mFirstRecHeight+mDebugMargin, dp2px(8), paint);//第四个点
paint.setColor(Color.parseColor("#E07140"));
canvas.drawCircle((width / 2) + (mFirstRecHeight / 2), mFirstRecHeight / 2 + mFirstMarginTop, dp2px(4), paint); //第五个点
paint.setAlpha(30);
canvas.drawCircle((width / 2) + (mFirstRecHeight / 2), mFirstRecHeight / 2 + mFirstMarginTop, dp2px(8), paint); //第五个点
}else{
paint.setColor(Color.WHITE);
canvas.drawCircle(width / 2, mFirstMarginTop+mDebugMargin+dp2px(8), dp2px(4), paint); // 第一个点
canvas.drawCircle((width / 2) - (mFirstRecHeight / 2), mFirstRecHeight / 2 + mFirstMarginTop, dp2px(4), paint); //第二个点
canvas.drawCircle(width / 2 - (mFirstRecHeight / 3), mFirstMarginTop + mFirstRecHeight+mDebugMargin, dp2px(4), paint);//第三个点
canvas.drawCircle(width / 2 + (mFirstRecHeight / 3), mFirstMarginTop + mFirstRecHeight+mDebugMargin, dp2px(4), paint);//第四个点
canvas.drawCircle((width / 2) + (mFirstRecHeight / 2), mFirstRecHeight / 2 + mFirstMarginTop, dp2px(4), paint); //第五个点
}
//顶部文字和左边的文字之间的间距使用mDebugTextMargin参数来微调,文字从左往右逆时针设置的
paint.setColor(mExpainTextColor); //设置文字颜色
paint.setTextSize(mPentagonTextSize);//设置文字的大小,文字设置从左往右,逆时针设置
if(!"".equals(mPointOneText) && mPointOneText != null) {
getDebugMarginByTextLength(mPointOneText);
canvas.drawText(mPointOneText, width / 2 -(dp2px(20)+mDebugTopTextMargin), mFirstMarginTop+dp2px(8)-dp2px(5), paint);//青少年
}
if(!"".equals(mPointTowText) && mPointTowText != null) {
getDebugMarginByTextLength(mPointTowText);
canvas.drawText(mPointTowText,(width / 2 - (mFirstRecHeight/ 2)-mDebugTextLeftMargin),mFirstRecHeight/2+mFirstMarginTop+dp2px(3),paint);//古人
}
if(!"".equals(mPointThereText) && mPointThereText != null) {
getDebugMarginByTextLength(mPointThereText);
canvas.drawText(mPointThereText,(width / 2 - (mFirstRecHeight/ 2)-mDebugTextLeftMargin)+dp2px(20),mFirstMarginTop+mFirstRecHeight+mDebugMargin+dp2px(3),paint);//绘画
}
//右边的文字设置间距使用@mDebugLeftTextMargin,来微调右边文字的间距
if(!"".equals(mPointFourText) && mPointFourText != null) {
getDebugMarginByTextLength(mPointFourText);
canvas.drawText(mPointFourText,width/2+(mFirstRecHeight/3)+mDebugTextRightMargin,mFirstMarginTop+mFirstRecHeight+mDebugMargin+dp2px(3),paint);//物理
}
if(!"".equals(mPointFiveText) && mPointFiveText != null) {
getDebugMarginByTextLength(mPointFiveText);
canvas.drawText(mPointFiveText,(width/2)+(mFirstRecHeight/2)+mDebugTextRightMargin,mFirstRecHeight/2+mFirstMarginTop+dp2px(3),paint);//科学研究
}
}
/**
* 根据标签的长度,微调文字的绘制位置
*/
private void getDebugMarginByTextLength(String textLength){
switch (textLength.length()){
case 2: //标签两个文字
mDebugTopTextMargin = dp2px(-2);
mDebugTextLeftMargin = dp2px(39);
mDebugTextRightMargin = dp2px(10);
break;
case 3:
mDebugTopTextMargin = dp2px(2);
mDebugTextLeftMargin = dp2px(52);
mDebugTextRightMargin = dp2px(10);
break;
case 4: //标签四个文字
mDebugTopTextMargin = dp2px(5);
mDebugTextLeftMargin = dp2px(68);
mDebugTextRightMargin = dp2px(10);
break;
default:{
if(textLength.length() >4){
mDebugTopTextMargin = dp2px(30);
mDebugTextLeftMargin = dp2px(107);
mDebugTextRightMargin = dp2px(10);
}
}
break;
}
}
/**
* dp转px
* @param dpValue
* @return
*/
protected int dp2px(int dpValue){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dpValue,getResources().getDisplayMetrics());
}
/**
* 提供一个方法,拿到中间的头像
*/
public void getHeadPictureMarginTop(FrameLayout headImageView,int topMargin){
this.mHeaderImageView = headImageView;
this.mHeadLayoutTopMargin = topMargin;
}
/**
* 定义一个方法,设置五边形连线的颜色
*/
public void setPentagonLinesColor(int linesColor){
this.mLinesColor = linesColor;
}
/**
* 设置五边形说明文字
* @param textString
*/
public void setPentagonViewText(String[] textString){
if(ObjectUtils.isNotEmpty(textString)) {
if(textString.length >=1){
this.mPointOneText = textString[0];
if(textString.length >= 2){
this.mPointFiveText = textString[1];
if(textString.length >=3){
this.mPointFourText = textString[2];
if(textString.length >= 4){
this.mPointThereText = textString[3];
if(textString.length >=5){
this.mPointTowText = textString[4];
}
}
}
}
}
}
}
/**
* 设置五边形说明文字的字体大小和颜色
*/
public void setPentagonTextColor(int textColor){
this.mExpainTextColor = textColor;
}
/**
* 设置五边形说明文字的大小
*/
public void setPentagonTextSize(int textSize){
this.mPentagonTextSize = textSize;
}
/**
* 判断是否显示不同点的颜色
*/
public void isSetFivePointDifferentColor(boolean isDiffColor){
this.mIsSetPointColor = isDiffColor;
}
}
实现的总体思路是,
1)画点、连线,主要是这五个点的选择非常重要,要注意观察,发现第一个点在屏幕的最中央,还有就是点二、五和三、四是项目对称的,然后可以根据屏幕的宽和高来确定点的位置,最后定义一个画笔,把线连起来,最后再各个端点画一个更大的圆点。
2)点旁边的文字也是画出来的,也不难,最主要的是需要调试,文字和点之间的间距。
最后的调用代码:
if(ObjectUtils.isNotEmpty(label)){
String[] labels = label.split(",");
//测试数据
// String[] labelString = {"你好","地方","啥事","好的","近平"};
mPentagonView.setPentagonViewText(labels); //标签逆时针展示
}
我好久没有写博客了,希望对大家有用,谢谢!