最近实现了一个竖线目录的结构图如下:
上图左侧为竖线 加伸缩扩展图标;
分析有5种状态:如图
下面实现:
package cn.vko.ring.common.weight;
import cn.vko.ring.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/** * Created by JiaRH on 2015/10/21. */
public class TreeIconLineView extends View {
public static final int SHOW_ICON_DONWLINE = 0;
public static final int SHOW_ICON_UPLINE = 1;
public static final int SHOW_ICON_ALLLINE = 2;
public static final int SHOW_ICON_ALONG = 3;
public static final int SHOW_LINE_ALONG = 4;
private int CURRENT_STATE = -1;
private Bitmap centerIcon;
private int lineColor = Color.parseColor("#378dcc");
private float lineWith = 2.0f;
//中心点的坐标
private int centerX, centerY;
private int density;
private Paint mPaint;
private Bitmap b;
public TreeIconLineView(Context context) {
this(context, null);
}
public TreeIconLineView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TreeIconLineView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
density = (int)(cn.com.mink.utils.ViewUtils.getScreenDensity(context)+0.5);
lineWith=lineWith*density;
initPaint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
switch (CURRENT_STATE) {
case SHOW_ICON_ALLLINE:
drawIconAllLine(canvas);
break;
case SHOW_ICON_DONWLINE:
drawIconDownLine(canvas);
break;
case SHOW_ICON_UPLINE:
drawIconUpLine(canvas);
break;
case SHOW_ICON_ALONG:
drawIconAlong(canvas);
break;
case SHOW_LINE_ALONG:
drawlineAlong(canvas);
break;
default:
drawlineAlong(canvas);
break;
}
invalidate();
}
private void drawlineAlong(Canvas canvas) {
canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight(), mPaint);
}
private void drawIconAlong(Canvas canvas) {
canvas.drawBitmap(b, getWidth() / 2-b.getWidth()/2, getHeight() / 2-b.getHeight()/2, mPaint);
}
private void drawIconUpLine(Canvas canvas) {
drawUpLine(canvas);
drawIconAlong(canvas);
}
private void drawUpLine(Canvas canvas) {
canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight() / 2, mPaint);
}
private void drawDownLine(Canvas canvas) {
canvas.drawLine(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight(), mPaint);
}
private void drawIconDownLine(Canvas canvas) {
drawDownLine(canvas);
drawIconAlong(canvas);
}
private void drawIconAllLine(Canvas canvas) {
drawlineAlong(canvas);
drawIconAlong(canvas);
}
private void initPaint() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(lineColor);
mPaint.setStrokeWidth(lineWith);
b = BitmapFactory.decodeResource(getResources(), R.drawable.class_main_b_unfold);
}
public int getCURRENT_STATE() {
return CURRENT_STATE;
}
public void setCURRENT_STATE(int CURRENT_STATE) {
this.CURRENT_STATE = CURRENT_STATE;
}
public Bitmap getCenterIcon() {
return centerIcon;
}
public void setCenterIcon(Bitmap centerIcon) {
this.centerIcon = centerIcon;
}
public int getLineColor() {
return lineColor;
}
public void setLineColor(int lineColor) {
this.lineColor = lineColor;
}
public float getLineWith() {
return lineWith;
}
public void setLineWith(float lineWith) {
this.lineWith = lineWith;
}
public Bitmap getB() {
return b;
}
public void setB(Bitmap b) {
this.b = b;
}
}
其中的lineColor ,lineWidth可以自己抽出来,自定义属性
看用法:
if (groupPosition==0) {
parentViewHolder.parentIcon.setCURRENT_STATE(TreeIconLineView.SHOW_ICON_DONWLINE);
}else if(groupPosition==mModels.size()-1){
parentViewHolder.parentIcon.setCURRENT_STATE(TreeIconLineView.SHOW_ICON_UPLINE);
}else{
parentViewHolder.parentIcon.setCURRENT_STATE(TreeIconLineView.SHOW_ICON_ALLLINE);
}
其中parentIcon即咱们自定义的view,根据设置不同的状态来实现展示不同的方式。
上图中右下角有个星星布局实现,顺便贴一下,便于以后使用
package cn.vko.ring.test.weight;
import cn.vko.ring.R;
import cn.vko.ring.utils.ViewUtils;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/** * Created by JiaRH on 2015/10/15. */
public class StarView extends View {
private Paint mPaint;
private int startX, startY;
private Bitmap leftBitMap, rightBitMap;
private int rightRectColor = Color.parseColor("#979797");
private int textCorlor = Color.parseColor("#000099");
private RectF mRectF;
private String text = "0";
private int marginLeftIconTopRate = 12;
private int fx = 10;
private int fy = 10;
private int textSize = 18;
private int density;
public StarView(Context context) {
this(context, null);
}
public StarView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public StarView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
density = (int)(cn.com.mink.utils.ViewUtils.getScreenDensity(context)+0.5);
initAttrbutes(context, attrs);
initPaint();
}
private void initPaint() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.FILL);
}
private void initAttrbutes(Context context, AttributeSet attrs) {
TypedArray a = getResources().obtainAttributes(attrs, R.styleable.StarView);
leftBitMap = BitmapFactory.decodeResource(getResources(),
a.getResourceId(R.styleable.StarView_leftIcon, R.drawable.my_ico_star));
text = a.getString(R.styleable.StarView_textContent);
marginLeftIconTopRate = a.getInt(R.styleable.StarView_marginTopLeftIconRate, density>2?12*density:12);
textSize = a.getInt(R.styleable.StarView_textStarSize, density>2?10*density:20);
if (density>2&&density<4) {
fx=19;
fy=19;
}
fx = a.getInt(R.styleable.StarView_textbgX, fx)*(density>2?(density>3?density:1):1);
fy = a.getInt(R.styleable.StarView_textbgY, fy)*(density>2?(density>3?density:1):1);
textCorlor = a.getColor(R.styleable.StarView_textStarColor, textCorlor);
rightRectColor = a.getColor(R.styleable.StarView_textBgColor, rightRectColor);
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int withMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int withSize = MeasureSpec.getSize(widthMeasureSpec);
int heithSize = MeasureSpec.getSize(heightMeasureSpec);
int with = withSize - getPaddingLeft() - getPaddingRight();
int height = heithSize - getPaddingBottom() - getPaddingTop();
if (withMode == MeasureSpec.AT_MOST) {
with = Math.min(with, (int) (leftBitMap.getWidth() * 2.5));
}
if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(height, leftBitMap.getHeight());
}
setMeasuredDimension(with, height);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawRectF(canvas);
drawText(canvas);
drawLeftIcon(canvas);
}
private void drawLeftIcon(Canvas canvas) {
// canvas.drawBitmap(leftBitMap, getWidth() / 2 - leftBitMap.getWidth() / 4, getHeight() / 2
// - leftBitMap.getHeight() / 2, mPaint);
canvas.drawBitmap(leftBitMap, 0, getHeight() / 2 - leftBitMap.getHeight() / 2, mPaint);
}
private void drawText(Canvas canvas) {
mPaint.setTextSize(textSize);
mPaint.setColor(textCorlor);
Paint.FontMetrics fm = mPaint.getFontMetrics();
int textHeight = (int) (Math.ceil(fm.descent - fm.ascent + 2));
canvas.drawText(text, mRectF.left + mRectF.width() * 3 / 5, getHeight() / 2 + textHeight / 4, mPaint);
}
private void drawRectF(Canvas canvas) {
int dy = leftBitMap.getHeight() / marginLeftIconTopRate;
mRectF = new RectF(0, getHeight() / 2 - (leftBitMap.getHeight() / 2 - dy), leftBitMap.getWidth() * 2.5f,
getHeight() / 2 + (leftBitMap.getHeight() / 2 - dy));
// mRectF = new RectF(getWidth() / 2, getHeight() / 2 - (leftBitMap.getHeight() / 2 - dy),
// getWidth() / 2 + leftBitMap.getWidth() * 2.5f, getHeight() / 2 + (leftBitMap.getHeight()
// / 2 - dy));
mPaint.setColor(rightRectColor);
canvas.drawRoundRect(mRectF, fx, fy, mPaint);
}
public void setRightRectColor(int rightRectColor) {
this.rightRectColor = rightRectColor;
}
public void setTextCorlor(int textCorlor) {
this.textCorlor = textCorlor;
}
public void setTextSize(int textSize) {
this.textSize = textSize;
}
public void setMarginLeftIconTopRate(int marginLeftIconTopRate) {
this.marginLeftIconTopRate = marginLeftIconTopRate;
}
public void setFx(int fx) {
this.fx = fx;
}
public void setFy(int fy) {
this.fy = fy;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
自定义属性:
<declare-styleable name="StarView">
<attr name="leftIcon" format="reference" />
<attr name="rightIcon" format="reference" />
<attr name="textContent" format="string"/>
<attr name="textStarColor" format="color"/>
<!--矩形背景色-->
<attr name="textBgColor" format="color"/>
<attr name="textStarSize" format="integer"/>
<!--x,y,方向的圆角半径大小-->
<attr name="textbgX" format="integer"/>
<attr name="textbgY" format="integer"/>
<!--矩形上边距离坐标图标的顶部高度-->
<attr name="marginTopLeftIconRate" format="integer"/>
</declare-styleable>
OK