實(shí)現(xiàn)豎直的步驟進(jìn)度條漩蟆,先看效果:
QQ截圖20160527173654.png
可以看到罚斗,實(shí)現(xiàn)的主要難點(diǎn)在于步驟條的線的高度是要跟右邊的布局保持一致的跺株,而右邊的布局的高度是不定的郑什,也就是用 wrap_content府喳,
所以如果左邊線高度使用 match_parent 的話就會(huì)撐到滿屏。
所有解決方法就是蘑拯,定義一個(gè) ViewGroup 包著左邊的線和右邊的布局劫拢,然后獲取這個(gè) ViewGroup 的高度作為左邊的線的高度。
這里的 ViewGroup 我選擇繼承 LinearLayout 强胰,也可以繼承其他舱沧。
看代碼:
public class ProLinearLayout extends LinearLayout {
private ProLine mProLine; //左邊的進(jìn)度條
//線的類型,實(shí)線還是虛線
public final static String typeSolid = "solid";
public final static String typeDotted = "dotted";
//是否是第一個(gè)或者是最后一個(gè)線
private boolean isLastOne = false;
private boolean isTopOne = false;
//最上面的一個(gè)的線是不是虛線
private boolean isTopTypeDotted = false;
private String lineType = typeSolid;
//那個(gè)圈的圖片偶洋,也可以自己畫熟吏,我這里就用圖片
private Bitmap imgBitmap;
public ProLinearLayout(Context context) {
super(context);
init();
}
public ProLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
LayoutParams lp;
private void init() {
imgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pro_readed);
//將線添加到 LinearLayout 的左邊,并設(shè)置一些邊距,這里注意一點(diǎn)就是 LayoutParams 第二個(gè)參數(shù)牵寺,如果平時(shí)正常情況悍引,
//可以使用 LayoutParams.WRAP_CONTENT,但如果外層有使用 ScrollView 帽氓,就要使用 LayoutParams.MATCH_PARENT趣斤,
//不然控件就會(huì)展不開,就會(huì)不顯示黎休。
mProLine = new ProLine(getContext());
lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
lp.rightMargin = todp(14);
lp.leftMargin = todp(16);
this.addView(mProLine, lp);
}
public ProLinearLayout setLineType(String lineType) {
this.lineType = lineType;
return this;
}
public ProLinearLayout setImageResources(int resId) {
this.imgBitmap = BitmapFactory.decodeResource(getResources(), resId);
return this;
}
public ProLinearLayout setIsLastOne(boolean isLastOne) {
this.isLastOne = isLastOne;
return this;
}
public ProLinearLayout setIsTopTypeDotted(boolean isTopTypeDotted) {
this.isTopTypeDotted = isTopTypeDotted;
return this;
}
public ProLinearLayout setIsTopOne(boolean isTopOne) {
this.isTopOne = isTopOne;
return this;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mProLine.setParentHeight(getMeasuredHeight()); //將 LinearLayout 的高度設(shè)置成左邊線的高度
mProLine.setLineType(lineType).setImageBitmap(imgBitmap)
.setIsLastOne(isLastOne).setIsTopOne(isTopOne).setIsTopTypeDotted(isTopTypeDotted);
}
private int todp(int px) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, px, getResources().getDisplayMetrics());
}
}
下面看左邊線的代碼:
public class ProLine extends View {
private Paint mPaint;
private Path path;
private PathEffect effects;
public final static String typeSolid = "solid";
public final static String typeDotted = "dotted";
private boolean isLastOne = false;
private boolean isTopOne = false;
private boolean isTopTypeDotted = false;
private String lineType = typeSolid;
private Bitmap imgBitmap;
private int mParentHeight = 0;
public ProLine(Context context) {
super(context);
init();
}
public ProLine(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mPaint = new Paint();
path = new Path();
effects = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1);
mPaint.setColor(Color.parseColor("#979797"));
imgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pro_readed);
}
public ProLine setLineType(String lineType) {
this.lineType = lineType;
return this;
}
public ProLine setImageBitmap(Bitmap bitmap) {
this.imgBitmap = bitmap;
return this;
}
public ProLine setIsLastOne(boolean isLastOne) {
this.isLastOne = isLastOne;
return this;
}
public void setParentHeight(int mParentHeight) {
this.mParentHeight = mParentHeight;
setMeasuredDimension(imgBitmap.getWidth(), this.mParentHeight); //這里再設(shè)置一次是因?yàn)槿绻季謩?dòng)態(tài)改變(例如有個(gè)控件從隱藏到
顯示狀態(tài))時(shí)浓领,左邊的線條高度不會(huì)變,還是原來(lái)的势腮,原因是 onMeasure 方法不調(diào)用联贩,所有無(wú)奈在這再寫一次,不知道怎么改捎拯。
}
public ProLine setIsTopTypeDotted(boolean isTopTypeDotted) {
this.isTopTypeDotted = isTopTypeDotted;
return this;
}
public ProLine setIsTopOne(boolean isTopOne) {
this.isTopOne = isTopOne;
return this;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(imgBitmap.getWidth(), mParentHeight); // 測(cè)量高度等于外層 LinearLayout 高度
} else if (widthSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(imgBitmap.getWidth(), heightSpecSize);
} else if (heightSpecMode == MeasureSpec.AT_MOST) {
setMeasuredDimension(widthSpecSize, mParentHeight); // 測(cè)量高度等于外層 LinearLayout 高度
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 下面是各種判斷和各種畫圖
float startX = imgBitmap.getWidth() / 2;
float stopX = startX;
float startY = imgBitmap.getHeight();
float stopY = mParentHeight;
int paddingTop = todp(12);
if (!isLastOne) {
canvas.drawBitmap(imgBitmap, 0, paddingTop, mPaint);
if (isTopOne) {
canvas.drawLine(startX, startY, stopX, stopY, mPaint);
} else {
if (isTopTypeDotted && lineType.equals(typeSolid)) {
drawDottedLine(canvas, startX, 0, startX, paddingTop);
canvas.drawLine(startX, startY, stopX, stopY, mPaint);
}
if (!isTopTypeDotted && lineType.equals(typeSolid)) {
canvas.drawLine(startX, 0, stopX, paddingTop, mPaint);
canvas.drawLine(startX, startY, stopX, stopY, mPaint);
}
if (isTopTypeDotted && lineType.equals(typeDotted)) {
drawDottedLine(canvas, startX, 0, startX, paddingTop);
drawDottedLine(canvas, startX, startY, stopX, stopY);
}
if (!isTopTypeDotted && lineType.equals(typeDotted)) {
canvas.drawLine(startX, 0, stopX, paddingTop, mPaint);
drawDottedLine(canvas, startX, startY, stopX, stopY);
}
}
} else {
canvas.drawBitmap(imgBitmap, 0, stopY - startY - paddingTop, mPaint);
if (lineType.equals(typeSolid)) {
canvas.drawLine(startX, 0, stopX, stopY - startY - paddingTop, mPaint);
} else if (lineType.equals(typeDotted)) {
drawDottedLine(canvas, startX, 0, stopX, stopY - startY - paddingTop);
}
}
}
private void drawDottedLine(Canvas canvas, float startX, float startY, float stopX, float stopY) {
mPaint.setStyle(Paint.Style.STROKE);
path.moveTo(startX, startY);
path.lineTo(stopX, stopY);
mPaint.setPathEffect(effects);
canvas.drawPath(path, mPaint);
}
private int todp(int px) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, px, getResources().getDisplayMetrics());
}
用法:
<com.text.lzx.ProLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</com.text.lzx.ProLinearLayout>
java 代碼中要設(shè)置的話就各種 set 方法就行泪幌。