五邊形最後的效果圖:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSPFRUT41kaNRTTU10dVNDTwYVbiVHNHpleO1GTulzRilWO5xkNNh0YwIFSh9Fd4VGdsATMfd3bkFGazxyaHRGcWdUYuVzVa9GczoVdG1mWfVGc5RHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cWZwpmLzgzNxATMygTM4EjMxgTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpeg)
/**
* 自定義一個五邊型,定義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); //标簽逆時針展示
}
我好久沒有寫部落格了,希望對大家有用,謝謝!