image
看出圖中會(huì)員等級(jí)分為4級(jí)闽巩,每一級(jí)的長(zhǎng)度均分4個(gè)實(shí)心的點(diǎn)钧舌,分為四個(gè)區(qū)間,每個(gè)區(qū)間中設(shè)置均分的進(jìn)度涎跨,所以用普通的ProgressBar洼冻、SeekBar是無法實(shí)現(xiàn)的,所以必須自定義View隅很,使用畫筆畫撞牢。
1、畫線
我的思路就是先畫一條灰色的虛線叔营,讓后屋彪,畫四個(gè)點(diǎn),根據(jù)傳入的當(dāng)前的成長(zhǎng)值绒尊,計(jì)算出在哪個(gè)區(qū)間畜挥,進(jìn)而繪畫出紅色的線,并且設(shè)置實(shí)心的紅點(diǎn)的點(diǎn)
package com.wj.progressbardemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* 成長(zhǎng)值進(jìn)度條
*/
public class GrowthValueProgress extends View {
private MyCallback callback;
private Context context;
private int currentValues = 1100;//當(dāng)前成長(zhǎng)值
private int v0Values = 0;//v0會(huì)員成長(zhǎng)值
private int v1Values = 100;//v1會(huì)員成長(zhǎng)值
private int v2Values = 10000;//v2會(huì)員成長(zhǎng)值
private int v3Values = 40000;//v3會(huì)員成長(zhǎng)值
private int v4Values = 80000;//v4會(huì)員成長(zhǎng)值
private Paint paint;//會(huì)員畫筆
private Paint grayPaint;
private Paint pointPaint1;
private Paint pointPaint2;
private Paint pointPaint3;
private Paint pointPaint4;
private int lineHeight = 8;//線的高度
private int pointSize = 8;//圓心的半徑
private int offsetX = 0;//x的坐標(biāo);
private int width;
private int hight;
private List<Paint> paintList;
public GrowthValueProgress(Context context) {
super(context);
this.context = context;
initPaint();
}
public GrowthValueProgress(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
initPaint();
}
public GrowthValueProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
initPaint();
}
public int getCurrentValues() {
return currentValues;
}
public void setCurrentValues(int currentValues) {
this.currentValues = currentValues;
}
private void initPaint() {
lineHeight=hight/2;//線的高度設(shè)置為布局的一半高度
pointSize=hight/2;//圓點(diǎn)的半徑設(shè)置為布局的一半高度
grayPaint = new Paint();
grayPaint.setColor(Color.GRAY);
grayPaint.setStrokeWidth(lineHeight);
grayPaint.setAntiAlias(true);
grayPaint.setTextAlign(Paint.Align.CENTER);
grayPaint.setStyle(Paint.Style.STROKE);
paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(lineHeight);
paint.setAntiAlias(true);
paint.setTextAlign(Paint.Align.CENTER);
paint.setStyle(Paint.Style.STROKE);
pointPaint1 = new Paint();
pointPaint2 = new Paint();
pointPaint3 = new Paint();
pointPaint4 = new Paint();
paintList=new ArrayList<>();
paintList.add(pointPaint1);
paintList.add(pointPaint2);
paintList.add(pointPaint3);
paintList.add(pointPaint4);
for (int i = 0; i < paintList.size(); i++) {
Paint mPaint = paintList.get(i);
mPaint.setStrokeWidth(10);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextAlign(Paint.Align.CENTER);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int lineLength = width / 5;
//繪制底部長(zhǎng)灰線
canvas.drawLine(0, lineHeight, width, lineHeight, grayPaint);
drawProgress(canvas, lineLength);
}
/**
* 畫進(jìn)度
*
* @param canvas
* @param lineLength 每個(gè)區(qū)間的平均長(zhǎng)度
*/
private void drawProgress(Canvas canvas, int lineLength) {
//在V0~V1區(qū)間內(nèi)
if (currentValues >= v0Values && currentValues < v1Values) {
int stopX = currentValues * lineLength / (v1Values - v0Values);
//x起始位置婴谱,y起始位置蟹但,x停止位置,y停止位置
offsetX = stopX;
pointPaint1.setColor(Color.RED);
pointPaint2.setColor(Color.GRAY);
pointPaint3.setColor(Color.GRAY);
pointPaint4.setColor(Color.GRAY);
} else if (currentValues >= v1Values && currentValues < v2Values) {
//在V1~V2區(qū)間內(nèi)
int stopX = (currentValues - v1Values) * lineLength / (v2Values - v1Values);
offsetX = lineLength * 1 + stopX;
pointPaint1.setColor(Color.RED);
pointPaint2.setColor(Color.GRAY);
pointPaint3.setColor(Color.GRAY);
pointPaint4.setColor(Color.GRAY);
} else if (currentValues >= v2Values && currentValues < v3Values) {
//在V2~V3區(qū)間內(nèi)
int stopX = (currentValues - v2Values) * lineLength / (v3Values - v2Values);
offsetX = lineLength * 2 + stopX;
pointPaint1.setColor(Color.RED);
pointPaint2.setColor(Color.RED);
pointPaint3.setColor(Color.GRAY);
pointPaint4.setColor(Color.GRAY);
} else if (currentValues >= 00 && currentValues <= v4Values) {
//在V3~V4區(qū)間內(nèi)
int stopX = (currentValues - v3Values) * lineLength / (v4Values - v3Values);
offsetX = lineLength * 3 + stopX;
pointPaint1.setColor(Color.RED);
pointPaint2.setColor(Color.RED);
pointPaint3.setColor(Color.RED);
pointPaint4.setColor(Color.GRAY);
} else if (currentValues > v4Values) {
int stopX = 10;//超過8萬使用固定值
offsetX = lineLength * 4 + stopX;
pointPaint1.setColor(Color.RED);
pointPaint2.setColor(Color.RED);
pointPaint3.setColor(Color.RED);
pointPaint4.setColor(Color.RED);
}
canvas.drawLine(0, lineHeight, offsetX, lineHeight, paint);
//圓心的XY坐標(biāo)谭羔,圓心半徑
canvas.drawCircle(1 * lineLength - pointSize, pointSize, pointSize, pointPaint1);
canvas.drawCircle(2 * lineLength - pointSize, pointSize, pointSize, pointPaint2);
canvas.drawCircle(3 * lineLength - pointSize, pointSize, pointSize, pointPaint3);
canvas.drawCircle(4 * lineLength - pointSize, pointSize, pointSize, pointPaint4);
if (callback != null) {
callback.callBack(offsetX,currentValues);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = this.getMeasuredWidth();
hight = this.getMeasuredHeight();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
public void getOffsetX(MyCallback callback){
this.callback=callback;
}
public interface MyCallback {
public void callBack(int offsetX,int currentValues);
}
}
2华糖、布局代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:orientation="vertical">
</LinearLayout>
<com.wj.progressbardemo.GrowthValueProgress
android:id="@+id/progress"
android:layout_marginTop="3dp"
android:layout_width="match_parent"
android:layout_height="6dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="V1會(huì)員\n100" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="V2會(huì)員\n10000" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="V3會(huì)員\n40000" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="V4會(huì)員\n80000" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp">
<EditText
android:id="@+id/et_text"
android:layout_width="100dp"
android:layout_height="40dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="btnSetValues"
android:text="設(shè)置" />
</LinearLayout>
</LinearLayout>
ok,那么就有疑問了,線條上面的黑色會(huì)話框口糕,是該怎么搞呢缅阳,我的想法是在View之外搞,根據(jù)接口回調(diào)景描,我能知道我的紅色的線有多長(zhǎng)十办,也就相當(dāng)于我知道我的黑色會(huì)話框距離左邊多遠(yuǎn)
3、設(shè)置黑色會(huì)話框
package com.wj.progressbardemo;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private int values=100;
private EditText et_text;
private GrowthValueProgress progress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress = (GrowthValueProgress) findViewById(R.id.progress);
final LinearLayout ll_content= (LinearLayout) findViewById(R.id.ll_content);
et_text = (EditText) findViewById(R.id.et_text);
progress.setCurrentValues(values);
progress.getOffsetX(new GrowthValueProgress.MyCallback() {
@Override
public void callBack(int offsetX,int currentValues) {
TextView tv=new TextView(MainActivity.this);
tv.setBackgroundResource(R.drawable.ic_growth_values);
if (currentValues>80000){
tv.setText(8+"萬+成長(zhǎng)值");
}else{
tv.setText(currentValues+"成長(zhǎng)值");
}
tv.setTextColor(Color.WHITE);
tv.setTextSize(10);
tv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
ll_content.removeAllViews();
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tv.getLayoutParams();
params.setMargins(offsetX,0,0,0);
ll_content.addView(tv);
}
});
}
public void btnSetValues(View view) {
String trim = et_text.getText().toString().trim();
progress.setCurrentValues(Integer.parseInt(trim));
progress.invalidate();
}
}
看看結(jié)果:image