Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 自定義View

Android 自定義View

編輯:關於Android編程

直接繼承 View 重寫 onDraw 方法.

這種方法主要用於實現一些不規則的效果.一般需要重寫onDraw方法.
自定義View注意點 :
1. 需要自己支持 wrap_content 屬性.
2. 需要自己支持 padding 屬性.
3. 添加自定義屬性 .

1. 重寫onMeasure處理wrap_content .

處理wrap_content代碼

    // 默認尺寸.
    private int mWidht = 200;
    private int mHeight = 200;
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 默認設置View尺寸但是wrap_content會失效 
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 獲取尺寸.
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        // 對於使用wrap_content 使用默認尺寸.
        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(mWidht,mHeight);
        }else if (widthSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(mWidht,heightSpecSize);
        }else if (heightSpecSize == MeasureSpec.AT_MOST){
            setMeasuredDimension(widthSpecSize,mHeight);
        }
    }

2. 在onDraw方法中處理失效Padding問題.

處理代碼 :

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 處理padding.
        final int paddingLeft = getPaddingLeft();
        final int paddingRight = getPaddingRight();
        final int paddingTop = getPaddingTop();
        final int paddingBottom = getPaddingBottom();
        // 可用尺寸需要在總尺寸中減去padding值
        int w = getWidth() - paddingLeft - paddingRight;
        int h = getHeight() - paddingTop - paddingBottom;
        int radius = Math.min(w,h)/2;
        canvas.drawCircle(getWidth() / 2, getHeight() / 2,radius,mPaint);
    }

3. 添加自定義屬性.

3.1 在 values 目錄下創建自定義屬性XML文件.比如 : attrs.circle_view.xml



    
        
        
    

3.2 在View的構造方法中解析自定義屬性值並做相應處理

   public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 解析自定義屬性值.
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CircleView);
        mColor = a.getColor(R.styleable.CircleView_circle_color,Color.RED);
        a.recycle();

        init();
    }

3.3 在布局文件中使用自定義屬性.

使用自定義文件注意點 :
需要在布局文件中添加 schemeas 聲明 :
xmlns:app=”http://schemas.android.com/apk/res-auto”在這個聲明中app是自定義屬性前綴,自定義屬性前綴必須和這裡的一樣.



    

4. CircleView.java 完整代碼

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

/**
 * 自定義View 繪制圓形.
 * Created by WSJ on 2016/12/15.
 */

public class CircleView extends View {

    private int mColor = Color.RED;
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);


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

    public CircleView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 解析自定義屬性值.
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CircleView);
        mColor = a.getColor(R.styleable.CircleView_circle_color,Color.RED);
        a.recycle();
        init();
    }

    private void init() {
        mPaint.setColor(mColor);
    }

    /**
     * 在這個方法中處理padding失效問題.
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 處理padding.
        final int paddingLeft = getPaddingLeft();
        final int paddingRight = getPaddingRight();
        final int paddingTop = getPaddingTop();
        final int paddingBottom = getPaddingBottom();
        int w = getWidth() - paddingLeft - paddingRight;
        int h = getHeight() - paddingTop - paddingBottom;
        int radius = Math.min(w,h)/2;
        canvas.drawCircle(getWidth() / 2, getHeight() / 2,radius,mPaint);
    }
    // 默認尺寸.
    private int mWidht = 200;
    private int mHeight = 200;

    /**
     * 在這個方法中處理wrap_content失效問題.
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 處理Wrap_content 方式.
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(mWidht,mHeight);
        }else if (widthSpecMode == MeasureSpec.AT_MOST){
            setMeasuredDimension(mWidht,heightSpecSize);
        }else if (heightSpecSize == MeasureSpec.AT_MOST){
            setMeasuredDimension(widthSpecSize,mHeight);
        }
    }
}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved