美文网首页
Android-自定义View

Android-自定义View

作者: 喜欢书的女孩 | 来源:发表于2017-10-06 20:29 被阅读13次
    2017-10-6

    [1] Android如何绘制视图?

    当用户将Android视图引入焦点时,Android框架会引导视图进行绘制。这个绘图过程包括3个阶段:
    measure 测量
    测量 view 的宽和高。

      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
            setMeasuredDimension(getDefaultSize(
                    getSuggestedMinimumWidth(), widthMeasureSpec),
                    getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec));
        }
    

    layout 布局
    确定 view 在父容器中的放置位置。

     protected void onLayout(boolean changed, int l, int t, int r, int b){
            if (mOrientation == VERTICAL){
                layoutVertical(l, t, r, b);
            }
            else{
                layoutHorizontal(l, t, r, b);
            }
        }
    

    draw 绘制
    负责将 view 绘制到屏幕上。

    protected void onDraw(Canvas canvas) {
       super.onDraw(canvas);
    
       // Draw the shadow
       canvas.drawOval(
               mShadowBounds,
               mShadowPaint
       );
    
       // Draw the label text
       canvas.drawText(mData.get(mCurrentItem).mLabel, mTextX, mTextY, mTextPaint);
    
       // Draw the pie slices
       for (int i = 0; i < mData.size(); ++i) {
           Item it = mData.get(i);
           mPiePaint.setShader(it.mShader);
           canvas.drawArc(mBounds,
                   360 - it.mEndAngle,
                   it.mEndAngle - it.mStartAngle,
                   true, mPiePaint);
       }
    
       // Draw the pointer
       canvas.drawLine(mTextX, mPointerY, mPointerX, mPointerY, mTextPaint);
       canvas.drawCircle(mPointerX, mPointerY, mPointerSize, mTextPaint);
    }
    

    [2] View的位置参数

    View 的位置主要由它的四个顶点来决定,分别对应于 View 的四个属性:top、left、right、bottom。
    其中 top 是左上角纵坐标,left 是左上角横坐标,right是右下角横坐标,bottom是右下角纵坐标。

    图片来源于 Android 开发艺术探索
    mLeft = getLeft();
    mRight = getRight();
    mBootom = getBottom();
    mTop = getTop();
    public final int getWidth(){
            return mRight - mLeft;
        }
        
        public final int getHeight(){
            return mBootom - mTop;
        }
    

    [3] 自定义View

    先画一个简单的静态棋盘,如下图(好丑,莫笑,但是可以实现一直都是我赢,电脑输):


    2017-10-6

    代码实现:

    package com.example.sweetgirl.customizeview.chess;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.view.View;
    
    /**
     * 象棋
     * Created by sweetgirl on 2017/9/21
     */
    
    public class ChessView extends View{
    
        Paint paint;
        public ChessView(Context context) {
            super(context);
            paint = new Paint();
            paint.setColor(Color.BLACK);
            paint.setStrokeJoin(Paint.Join.ROUND);
            paint.setStrokeCap(Paint.Cap.ROUND);
            paint.setStrokeWidth(3);
            paint.setTextSize(40);
        }
    
        /**
         * 先画横线,top--bottom , 再画竖线 left--right
         * @param canvas
         */
        protected void onDraw(Canvas canvas) {
            //top
            paint.setColor(Color.BLACK);
            canvas.drawLine(30, 30, 450, 30, paint);
            canvas.drawLine(30, 100, 450, 100, paint);
            canvas.drawLine(30, 170, 450, 170, paint);
            canvas.drawLine(30, 240, 450, 240, paint);
            canvas.drawLine(30, 310, 450, 310, paint);
            // bottom
            canvas.drawText(" 楚   河 ", 65, 355, paint);
            canvas.drawText(" 汉  界  ", 320, 355, paint);
            canvas.drawLine(30, 380, 450, 380, paint);
            canvas.drawLine(30, 450, 450, 450, paint);
            canvas.drawLine(30, 520, 450, 520, paint);
            canvas.drawLine(30, 590, 450, 590, paint);
            canvas.drawLine(30, 660, 450, 660, paint);
            //left
            canvas.drawLine(30, 30, 30, 660, paint);
            canvas.drawLine(83, 30, 83, 310, paint);
            canvas.drawLine(136, 30, 136, 310, paint);
            canvas.drawLine(189, 30, 189, 310, paint);
            canvas.drawLine(242, 30, 242, 310, paint);
            canvas.drawLine(294, 30, 294, 310, paint);
            canvas.drawLine(347, 30, 347, 310, paint);
            canvas.drawLine(398, 30, 398, 310, paint);
            //right
            canvas.drawLine(83, 380, 83,660, paint);
            canvas.drawLine(136, 380, 136,660, paint);
            canvas.drawLine(189, 380, 189,660, paint);
            canvas.drawLine(242, 380, 242,660, paint);
            canvas.drawLine(294, 380, 294,660, paint);
            canvas.drawLine(347, 380, 347,660, paint);
            canvas.drawLine(398, 380, 398,660, paint);
            canvas.drawLine(450,30 ,450,660, paint);
            //大营
            canvas.drawLine(189, 30, 294,170, paint);
            canvas.drawLine(294, 30, 189,170, paint);
            canvas.drawLine(189,520, 294,660, paint);
            canvas.drawLine(294,520, 189,660, paint);
    
            //circle
            paint.setColor(Color.YELLOW);
            canvas.drawCircle(450, 240,20, paint);
            canvas.drawCircle(346, 240,20, paint);
            canvas.drawCircle(242, 240,20, paint);
    
            canvas.drawCircle(396, 170,20, paint);
            canvas.drawCircle(450, 30,20, paint);
            canvas.drawCircle(396, 30,20, paint);
            canvas.drawCircle(346, 30,20, paint);
            canvas.drawCircle(294, 30,20, paint);
            canvas.drawCircle(242, 30,20, paint);
            canvas.drawCircle(189, 30,20, paint);
            canvas.drawCircle(135, 30,20, paint);
            canvas.drawCircle(83, 30,20, paint);
            canvas.drawCircle(30, 30,20 , paint);
            canvas.drawCircle(83, 170,20, paint);
    
            canvas.drawCircle(135, 240,20, paint);
            canvas.drawCircle(30, 240,20, paint);
    
            canvas.drawCircle(450, 450,20, paint);
            canvas.drawCircle(346, 450,20, paint);
            canvas.drawCircle(242, 450,20, paint);
    
            canvas.drawCircle(396, 520,20, paint);
            canvas.drawCircle(450, 660,20, paint);
            canvas.drawCircle(396, 660,20, paint);
            canvas.drawCircle(346, 660,20, paint);
            canvas.drawCircle(294, 660,20, paint);
            canvas.drawCircle(242, 660,20, paint);
            canvas.drawCircle(189, 660,20, paint);
            canvas.drawCircle(135, 660,20, paint);
            canvas.drawCircle(83, 660,20, paint);
            canvas.drawCircle(30, 660,20, paint);
            canvas.drawCircle(83, 520,20, paint);
    
            canvas.drawCircle(135, 450,20, paint);
            canvas.drawCircle(30, 450,20, paint);
    
            //text
            paint.setColor(Color.RED);
            paint.setTextSize(20);
            
            canvas.drawText("兵", 21,458, paint);
            canvas.drawText("兵", 127,458, paint);
            canvas.drawText("兵", 232,458 , paint);
            canvas.drawText("炮", 388,527, paint);
            canvas.drawText("车", 440,668 , paint);
            canvas.drawText("馬", 388,668 , paint);
            canvas.drawText("象", 335,668 , paint);
            canvas.drawText("仕", 285,668 , paint);
            canvas.drawText("帥", 232,668 , paint);
            canvas.drawText("仕", 180,668 , paint);
            canvas.drawText("象", 127,668 , paint);
            canvas.drawText("馬", 72,668 , paint);
            canvas.drawText("车", 21,668 , paint);
            canvas.drawText("炮", 72, 527, paint);
            canvas.drawText("兵", 335,458 , paint);
            canvas.drawText("兵", 440,458, paint);
    
            paint.setColor(Color.BLACK);
            canvas.drawText("卒", 21,245, paint);
            canvas.drawText("卒", 127,245, paint);
            canvas.drawText("卒", 232,245 , paint);
            canvas.drawText("炮", 72, 177, paint);
            canvas.drawText("车", 21,35 , paint);
            canvas.drawText("馬", 72,35 , paint);
            canvas.drawText("象", 127,35 , paint);
            canvas.drawText("士", 180,35 , paint);
            canvas.drawText("将", 232,35 , paint);
            canvas.drawText("士", 285,35 , paint);
            canvas.drawText("象", 335,35 , paint);
            canvas.drawText("馬", 388,35 , paint);
            canvas.drawText("车", 440,35 , paint);
            canvas.drawText("炮", 388, 177, paint);
            canvas.drawText("卒", 335,247 , paint);
            canvas.drawText("卒", 440,247, paint);
    
        }
    
    }
    

    在 layout 中引用:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_chess_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.example.sweetgirl.customizeview.activity.ChessViewActivity">
    
        <com.example.sweetgirl.customizeview.chess.ChessView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/cv_chess"/>
    </RelativeLayout>
    

    在 Activity 中实现:

    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    
    import com.example.sweetgirl.customizeview.R;
    import com.example.sweetgirl.customizeview.chess.ChessView;
    
    public class ChessViewActivity extends AppCompatActivity {
    
        private ChessView chessView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_chess_view);
    
            chessView = (ChessView)findViewById(R.id.cv_chess);
        }
    }
    

    [4]总结

    后期再做一个小球沿着 sin(x) 曲线运动的 demo, 最近很喜欢郭霖大神微信公众号上推出的自定义的各种高逼格 view, 有模仿着做了一个贝塞尔曲线之类的。感谢大神的分享。

    相关文章

      网友评论

          本文标题:Android-自定义View

          本文链接:https://www.haomeiwen.com/subject/rjqvjxtx.html