欢迎使用CSDN-markdown编辑器

关于Android自定义View使用画布的问题

Android自定义View,重写protected void onDraw(Canvas canvas)函数,但是却一直未有调用,百度一番后说是需要调用setWillNotDraw(false);我不仅在自定义View的构造函数里面调用这个函数,还尝试将它的父Layout重写在其中调用这个函数,却仍然未调用onDraw函数。

到底是什么原因呢?我发现在普通的layout里面直接调用自定义View是完全可以进入onDraw函数的,但是一旦被加入ListView中的item里,就完全没有作用了,经过大半天的努力总算找到了解决方法。

解决的方法就是重写protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)函数。因为高度为0,自然什么也看不到。

下面就看看我的自定义View的代码吧。

代码块

public class FollowDrawView extends View {
    public static class FollowParams {
        public boolean isFinished;//是否结束
        public boolean isCurrent;//是否当前
        public boolean isOnlyOne;//是否只有一个
        public boolean isFirst;//是否是第一个
        public float width = -1;
        public float height = -1;
    }

    private boolean mIsFinished = false;
    private boolean mIsCurrent = false;
    private boolean mIsOnlyOne = false;
    private boolean mIsFirst = false;

    private Context mContext;

    private float mWidth = -1;
    private float mHeight = -1;

    public FollowDrawView(Context context) {
        super(context);

        setWillNotDraw(false);
//        initView(context, isFinished, isCurrent);
    }

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

        setWillNotDraw(false);
//        initView(context, isFinished, isCurrent);
    }

    public FollowDrawView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
//        initView(context, isFinished, isCurrent);
    }

    public void updateView(Context context, FollowParams params){
        if (params == null) {
            return;
        }

        mIsFinished = params.isFinished;
        mIsCurrent = params.isCurrent;
        mIsOnlyOne = params.isOnlyOne;
        mIsFirst = params.isFirst;
        mWidth = params.width;
        mHeight = params.height;

        mContext = context;

        invalidate();
    }

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

        // 创建画笔
        Paint p = new Paint();
        p.setColor(Color.rgb(0xeb, 0xec, 0xf1));

        if (mHeight < 0 || mWidth < 0) {
            return;
        }

        Log.i("Ondraw", "mWidth = " + mWidth + " mHeight = " + mHeight);

        float lineLeft = 0;
        float lineTop = 0;
        float lineRight = 0;
        float lineBottom = 0;

        Bitmap bitmap;

        Bitmap maxBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.end_location_pic);

        //画圆圈图片
        if (mIsCurrent) {
            if (mIsFinished) {
                //绘制红色圆圈
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.end_location_pic);
            }
            else {
                //绘制绿色圆圈
                bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.current_location_pic);
            }
        }
        else {
            //绘制灰色圆圈
            bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.normal_location_pic);
        }

        float width = maxBitmap.getWidth();
        float rectWidth = 8;

        //画竖线
        if (mIsCurrent) {
            //竖线不画满
            lineLeft = mWidth - width;
            lineRight = lineLeft + rectWidth;
            lineTop = getPaddingTop();

            if (mIsFirst) {
                lineBottom = lineTop;
            }
            else {
                lineBottom = mHeight;
            }
        }
        else {
            //竖线画满
            lineLeft = mWidth - width;
            lineRight = lineLeft + rectWidth;
            lineTop = 0;

            if (mIsFirst) {
                lineBottom = getPaddingTop() + bitmap.getHeight() / 2;
            }
            else {
                lineBottom = mHeight;
            }
        }

        if (!mIsOnlyOne) {
            canvas.drawRect(lineLeft, lineTop, lineRight, lineBottom, p);
        }

        float left = 0;
        float top = 0;

        left = (float) (lineLeft + rectWidth / 2 - bitmap.getWidth() / 2);
        top = getPaddingTop();
        if (!mIsCurrent) {
            top += bitmap.getHeight() / 2;
        }

        canvas.drawBitmap(bitmap, left, top, p);

        if (mIsCurrent) {
            //写:当前
            p.setTextSize(CommonFun.dip2px(mContext, 15));
            p.setColor(Color.rgb(0xff, 0x73, 0x73));

            String curText = "当前";
            if (mIsFinished) {
                curText = "完成";
            }
            float offX = -20;
            float offY = 20;
            float x = lineLeft - maxBitmap.getWidth();
            float y = getPaddingTop();

            for (int i = 0; i < curText.length(); i++) {
                String txt = curText.substring(i, i + 1);
                Path path = new Path();
                path.moveTo(x, y);
                path.lineTo(x + 30, y);

                y += 48;
                canvas.drawTextOnPath(txt, path, offX, offY, p);
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mHeight < 0 || mWidth < 0) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }

        int measuredHeight = measureHeight(heightMeasureSpec);
        int measuredWidth = measureWidth(widthMeasureSpec);

        setMeasuredDimension(measuredWidth, measuredHeight);
    }

    private int measureHeight(int measureSpec) {

        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

// Default size if no limits are specified.

        int result = (int) mHeight;
        if (specMode == MeasureSpec.AT_MOST){//相当于我们设置为wrap_content

// Calculate the ideal size of your
// control within this maximum size.
// If your control fills the available
// space return the outer bound.

            result = specSize;
            mHeight = specSize;

            Log.i("measureHeight", "AT_MOST height = " + mHeight);
        }
        else if (specMode == MeasureSpec.EXACTLY){//相当于我们设置为match_parent或者为一个具体的值

// If your control can fit within these bounds return that value.
            result = specSize;
            mHeight = result;

            Log.i("measureHeight", "EXACTLY height = " + mHeight);
        }
        else {
            Log.i("measureHeight", "Other height = " + mHeight);
        }

        return result;
    }

    private int measureWidth(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

// Default size if no limits are specified.
        int result = (int) mWidth;
        if (specMode == MeasureSpec.AT_MOST){
// Calculate the ideal size of your control
// within this maximum size.
// If your control fills the available space
// return the outer bound.
            result = specSize;
            mWidth = result;

            Log.i("measureWidth", "AT_MOST width = " + mWidth);
        }

        else if (specMode == MeasureSpec.EXACTLY){
// If your control can fit within these bounds return that value.

            result = specSize;
            mWidth = result;

            Log.i("measureWidth", "EXACTLY width = " + mWidth);
        }
        else {
            Log.i("measureWidth", "Other width = " + mWidth);
        }

        return result;
    }
}

xml文件:

代码块

...
<com.rsp.programmerproject.ui.FollowDrawView
            android:id="@+id/fd_image_flag"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent"
            android:padding="@dimen/side_padding"/>

调用文件:

代码块

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
    ...
            FollowDrawView followDrawView = holder.followDrawView;
            TextView infoTextView = holder.infoTextView;
            TextView dateTimeTextView = holder.dateTimeTextView;

            FollowDrawView.FollowParams params = new FollowDrawView.FollowParams();
            params.isFinished = mBillFollowInfo.getBillFollowInfos().get(position - 1).isFinished();
            params.isCurrent = position == 1 ? true : false;
            params.isOnlyOne = mBillFollowInfo.getBillFollowInfos().size() < 2 ? true : false;
            params.isFirst = position == mBillFollowInfo.getBillFollowInfos().size() ? true : false;

            if (followDrawView != null) {
                params.width = followDrawView.getMeasuredWidth();
                params.height = view.getMeasuredHeight();
                followDrawView.updateView(view.getContext(), params);
            }
    }

    public class ViewHolder {
        public FollowDrawView followDrawView;
        public TextView infoTextView;
        public TextView dateTimeTextView;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值