控制TextView侧边图标大小以及显示位置

一般来说TextView侧边的图标位置都是居中显示的,并且图标大小是按照图标的尺寸来显示的。例如,假如你给TextView设置了drawableLeft,此时该图标的位置以及大小是不可控的,这样就会出现两种问题:
1、如果TextView文字过长导致换行,然而左边的图标仍然是按照TextView的高度垂直居中显示,然而我们想要的却是想让图标在第一行居中显示;
2、图标过大或者过小不可控;

此时就要考虑自定义TextView来解决此类问题了。具体思路为:
1、对于图标的位置,可以考虑设置图标Drawable的整体偏移量;
2、对于图标的大小,则是自定义其大小;

具体显示效果如下:


图标方位及大小.png

具体实现如下:

public class DrawableTextView extends AppCompatTextView {
    // 控件左、上、右、下图标的宽和高
    private int drawableLeftWidth, drawableTopWidth, drawableRightWidth, drawableBottomWidth;
    private int drawableLeftHeight, drawableTopHeight, drawableRightHeight, drawableBottomHeight;
    // 默认显示方式
    private boolean alignCenter = true;
    private int mWidth;

    public DrawableTextView(Context context) {
        this(context, null);
    }

    public DrawableTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DrawableTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs);
    }

    private void initView(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DrawableTextView);
        drawableLeftWidth = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_drawableLeftWidth, 0);
        drawableTopWidth = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_drawableTopWidth, 0);
        drawableRightWidth = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_drawableRightWidth, 0);
        drawableBottomWidth = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_drawableBottomWidth, 0);
        drawableLeftHeight = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_drawableLeftHeight, 0);
        drawableTopHeight = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_drawableTopHeight, 0);
        drawableRightHeight = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_drawableRightHeight, 0);
        drawableBottomHeight = typedArray.getDimensionPixelSize(R.styleable.DrawableTextView_drawableBottomHeight, 0);
        alignCenter = typedArray.getBoolean(R.styleable.DrawableTextView_alignCenter, true);
        typedArray.recycle();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        Drawable[] drawables = getCompoundDrawables();
        Drawable drawableLeft = drawables[0];
        Drawable drawableTop = drawables[1];
        Drawable drawableRight = drawables[2];
        Drawable drawableBottom = drawables[3];
        if (drawableLeft != null) {
            setDrawable(drawableLeft, 0, drawableLeftWidth, drawableLeftHeight);
        }
        if (drawableTop != null) {
            setDrawable(drawableTop, 1, drawableTopWidth, drawableTopHeight);
        }
        if (drawableRight != null) {
            setDrawable(drawableRight, 2, drawableRightWidth, drawableRightHeight);
        }
        if (drawableBottom != null) {
            setDrawable(drawableBottom, 3, drawableBottomWidth, drawableBottomHeight);
        }
        this.setCompoundDrawables(drawableLeft, drawableTop, drawableRight, drawableBottom);
    }

    /**
     * 设置图标大小及其偏移量
     */
    private void setDrawable(Drawable drawable, int tag, int drawableWidth, int drawableHeight) {
        int width = drawableWidth == 0 ? drawable.getIntrinsicWidth() : drawableWidth;
        int height = drawableHeight == 0 ? drawable.getIntrinsicHeight() : drawableHeight;
        int left = 0, top = 0, right = 0, bottom = 0;
        switch (tag) {
            case 0:
            case 2:
                left = 0;
                top = alignCenter ? 0 : -getLineCount() * getLineHeight() / 2 + getLineHeight() / 2;
                right = width;
                bottom = top + height;
                break;
            case 1:
            case 3:
                left = alignCenter ? 0 : -mWidth / 2 + width / 2;
                top = 0;
                right = left + width;
                bottom = top + height;
                break;
        }
        drawable.setBounds(left, top, right, bottom);
    }
}

你可能感兴趣的:(控制TextView侧边图标大小以及显示位置)