自定义控件用属性实现selector效果

public class ImageAndTextView extends View
{
    /**
     * 文本内容
     */
    private String mText;
    /**
     * 文本大小
     */
    private float mTextSize;
    /**
     * 文本颜色
     */
    private int mTextColor;
    /**
     * 图片默认的资源id
     */
    private int imageId;
    /**
     * 按下时显示的图片的资源id
     */
    private int imageId_pressed;
    /**
     * 选中时显示的图片的资源id
     */
    private int imageId_selector;
    /**
     * 图片不能点击时显示的资源id
     */
    private int imageId_not_click;
    /**
     * 图片加载的Bitmap对象
     */
    private Bitmap mImage;
    /**
     * 画笔
     */
    private Paint mPaint = new Paint();
    /**
     * 文本的绘制区域
     */
    private Rect textRect = new Rect();
    /**
     * 图片的绘制区域
     */
    private Rect rect = new Rect();
    /**
     * 图片和文本的间距
     */
    private final int SPACING = 16;


    public ImageAndTextView(Context context, AttributeSet attrs,
            int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
    }


    public ImageAndTextView(Context context, AttributeSet attrs)
    {
        super(context, attrs);


        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.ImageAndTextView);
        mText = a.getString(R.styleable.ImageAndTextView_text);
        if (mText == null)
        {
            mText = "默认";
        }
        mTextColor = a.getColor(R.styleable.ImageAndTextView_textColor,
                Color.BLACK);
        mTextSize = a.getDimension(R.styleable.ImageAndTextView_textSize, 24);
        imageId = a.getResourceId(R.styleable.ImageAndTextView_src_default,
                R.drawable.ic_launcher);
        imageId_pressed = a.getResourceId(
                R.styleable.ImageAndTextView_src_pressed, imageId);
        imageId_not_click = a.getResourceId(
                R.styleable.ImageAndTextView_src_noClick, imageId);
        imageId_selector = a.getResourceId(
                R.styleable.ImageAndTextView_src_selector, imageId);
        // 调用结束后务必调用recycle()方法,否则这次的设定会对下次的使用造成影响
        a.recycle();
        mImage = BitmapFactory.decodeResource(getResources(), imageId);


        mPaint.setTextSize(mTextSize);
        mPaint.getTextBounds(mText, 0, mText.length(), textRect);// 计算文本尺寸
    }


    public ImageAndTextView(Context context)
    {
        super(context);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);


        int width;
        int height;


        // 计算宽度
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specize = MeasureSpec.getSize(widthMeasureSpec);
        if (specMode == MeasureSpec.EXACTLY)
        {
            width = specize;
        }
        else
        {
            int widthByImage = 0;
            int widthByText = 0;
            // 由图片确定的宽度
            widthByImage = getPaddingLeft() + getPaddingRight()
                    + mImage.getWidth();
            // 由文本确定的宽度
            widthByText = getPaddingLeft() + getPaddingRight()
                    + textRect.width();


            int w = Math.max(widthByImage, widthByText);// 哪个大由哪个决定
            width = Math.min(w, specize);// 和屏幕尺寸比 哪个小用哪个
        }


        // 计算高度
        specMode = MeasureSpec.getMode(heightMeasureSpec);
        specize = MeasureSpec.getSize(heightMeasureSpec);
        if (specMode == MeasureSpec.EXACTLY)
        {
            height = specize;
        }
        else
        {
            int h = getPaddingBottom() + getPaddingTop() + mImage.getHeight()
                    + textRect.height() + SPACING;
            height = Math.min(h, specize);


        }
        setMeasuredDimension(width, height);
    }


    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);


        int mWidth = getWidth();
        int mHeight = getHeight();


        // 文本
        mPaint.setColor(mTextColor);
        mPaint.setTextSize(mTextSize);
        mPaint.setStyle(Style.FILL);
        canvas.drawText(mText, mWidth / 2 - textRect.width() / 2, mHeight
                - getPaddingBottom() - SPACING / 2, mPaint);


        // 图片
        // 计算居中的矩形范围
        rect.left = mWidth / 2 - mImage.getWidth() / 2;
        rect.right = mWidth / 2 + mImage.getWidth() / 2;
        rect.top = (mHeight - textRect.height() - SPACING) / 2
                - mImage.getHeight() / 2;
        rect.bottom = (mHeight - textRect.height() - SPACING) / 2
                + mImage.getHeight() / 2;


        canvas.drawBitmap(mImage, null, rect, mPaint);
    }


    /**
     * 设置文本内容
     * 
     * @param text
     */
    public void setText(String text)
    {
        mText = text;
        mPaint.getTextBounds(mText, 0, mText.length(), textRect);// 重新计算文本尺寸
                                                                 // 有时会有三个字点击变成两个字的情况
        invalidate();
    }


    /**
     * 获取文本内容
     */
    public String getText()
    {


        return mText;
    }


//    /**
//     * 重写此方法用来设置图片的点击效果
//     */
//    @SuppressLint("ClickableViewAccessibility")
//    @Override
//    public boolean onTouchEvent(MotionEvent event)
//    {
//        // 如果设置的为不能点击 直接return
//        if (!isEnabled())
//        {
//            return super.onTouchEvent(event);
//        }
//
//        switch (event.getAction())
//        {
//        case MotionEvent.ACTION_DOWN:
//            Log.i("action", "action_down...");
//            mImage = BitmapFactory.decodeResource(getResources(),
//                    imageId_pressed);
//            Log.i("action", mImage.toString());
//            break;
//        case MotionEvent.ACTION_UP:
//            Log.i("action", "action_up...");
//            mImage = BitmapFactory.decodeResource(getResources(), imageId);
//            Log.i("action", mImage.toString());
//            break;
//        }
//        invalidate();
//        return super.onTouchEvent(event);
//    }


    /**
     * 切换是否可以点击时显示的图片 及 文本颜色
     */
    @Override
    public void setEnabled(boolean enabled)
    {
        super.setEnabled(enabled);


        if (enabled)
        {
            mImage = BitmapFactory.decodeResource(getResources(), imageId);
            mTextColor = Color.BLACK;
        }
        else
        {
            mImage = BitmapFactory.decodeResource(getResources(),
                    imageId_not_click);
            mTextColor = Color.GRAY;
        }


        invalidate();
    }


    /**
     * 重写状态变化方法,根据控件状态改变其drawable 
     */
    @Override
    protected void drawableStateChanged()
    {
        // TODO Auto-generated method stub


        super.drawableStateChanged();
        if (isFocused())
        {
            mImage = BitmapFactory.decodeResource(getResources(),
                    imageId_selector);


        }
        else if (isPressed())
        {
            if (!isEnabled())
            {
                return;
            }
            mImage = BitmapFactory.decodeResource(getResources(),
                    imageId_pressed);
        }
        else
        {


            if (isEnabled())
            {
                mImage = BitmapFactory.decodeResource(getResources(), imageId);
                mTextColor = Color.BLACK;
            }
            else
            {
                mImage = BitmapFactory.decodeResource(getResources(),
                        imageId_not_click);
                mTextColor = Color.GRAY;
            }
        }
        invalidate();
    }

}



最主要的是重写drawableStateChanged()方法,不明白的去搜索下selector的实现原理,看下View和Drawable及selector的联系

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值