树形目录结构 竖线+扩展+收缩 图标的实现

最近实现了一个竖线目录的结构图如下:

上图左侧为竖线 加伸缩扩展图标;
分析有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

你可能感兴趣的:(android,自定义,竖线,树目录)