多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > Android中初步自定義view

Android中初步自定義view

來源:程序員人生   發布時間:2017-02-03 14:52:14 閱讀次數:2953次

在研究了幾個星期的view以后,打算自定義個view鞏固檢驗1下最近學的知識,view知知趣關博文

Android6.0源碼分析之View(1)


Android6.0源碼分析之View(2)--measure


Android中View研究自學之路

Chapter One,自定義1個顯示文本的自定義view

首先,定義1個繼承自view的子類Customview

public class CustomView extends View {


    private String mCustomTitle;//標題文本
    private int mTitleTxtSize;//標題字體大小
    private int mTitleTxtColor;//標題文本色彩

    private String mCustomCont;//正文文本
    private int mContTxtSize;//正文字體大小
    private int mContTxtColor;//正文文本色彩
    private Rect mBounds;

    private TextPaint mPaint;
    public CustomView(Context context) {
        super(context);
    }

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


    }

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new TextPaint();
        mBounds = new Rect();
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CustomViewStyle);

        //從添加view的xml文件中獲得到view的相干屬性信息
        //標題相干屬性
        mCustomTitle = array.getString(R.styleable.CustomViewStyle_customTitle);
        mTitleTxtSize = array.getDimensionPixelSize(R.styleable.CustomViewStyle_titleTxtSize,
                (int) getResources().getDimension(R.dimen.title_default_size));
        mTitleTxtColor= array.getColor(R.styleable.CustomViewStyle_titleTxtColor,
                Color.BLACK);

        //正文文本相干屬性
        mCustomCont = array.getString(R.styleable.CustomViewStyle_customCont);
        mContTxtSize = array.getDimensionPixelSize(R.styleable.CustomViewStyle_contTxtSize,
                (int) getResources().getDimension(R.dimen.cont_default_size));
        mContTxtColor = array.getColor(R.styleable.CustomViewStyle_contTxtColor,Color.GRAY);

        array.recycle();

    }

對1個view在xml中相干的 屬性有限,我們需要添加自己想要的屬性,添加方式也很簡單,

第1步那就是在values目錄下創建1個resource為節點的資源文件,把想要的屬性添加進去

<?xml version="1.0" encoding="utf⑻"?>
<resources>
    <declare-styleable name="CustomViewStyle">
        <attr name="customTitle" format="string"/>
        <attr name="customCont" format="string"/>
        <attr name="titleTxtSize" format="dimension"/>
        <attr name="contTxtSize" format="dimension"/>
        <attr name="titleTxtColor" format="color"/>
        <attr name="contTxtColor" format="color"/>
    </declare-styleable>
</resources>

第2步,在添加屬性成功后,在構造方法中援用該styleable

第3步,現在,可以在xml文件中使用了

<com.fang.zrf.customview.widges.CustomView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        custom:customTitle="@string/custom_view_title"
        custom:customCont="@string/custom_view_cont"
        android:paddingLeft="50dp"/>

使用的時候是以custom開頭,1般開發工具會提示你添加命名空間

xmlns:custom="http://schemas.android.com/apk/res-auto"

把這句話添加在根節點下,到現在,你就能夠為你的view自定義屬性了


屬性添加成功后可以進行丈量,布局和繪制了。

即需要重寫onMeasure和onDraw方法。

這樣整體來看,其實自定義view也不是很麻煩??偨Y下來就是

第1,先定義自己的view類

第2,創建資源文件添加view的屬性

第3,在onMeasure方法中丈量view所需要顯示的大小

第4,在onDraw中借助畫筆和畫布把view繪制出來。


恩~看著確切挺簡單,實現起來真是問題層見疊出


Chapter Two,所遇到的問題

轉載請注明出處 

Android中初步自定義view

問題1 ,Paint畫筆對象為null的異常

 FATAL EXCEPTION: main
  Process: com.fang.zrf.mycustomview, PID: 12882
  java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
  at android.graphics.Canvas.drawText(Canvas.java:1656)
  at com.fang.zrf.mycustomview.widgets.CustomViewSec.onDraw(CustomViewSec.java:76)
  at android.view.View.draw(View.java:16207)

剛開始怎樣也想不明白,明明創建了Paint的對象,為何還會為null。到最后發現真是自己的粗心大意??纯次业拇a,你能看出來問題嗎???

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

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

       
    }

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mPaint = new Paint();
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CustomViewStyle);

        //從添加view的xml文件中獲得到view的相干屬性信息
        //標題相干屬性
        mCustomTitle = array.getString(R.styleable.CustomViewStyle_customTitle);
        mTitleTxtSize = array.getDimensionPixelSize(R.styleable.CustomViewStyle_titleTxtSize,
                (int) getResources().getDimension(R.dimen.title_default_size));
        mTitleTxtColor= array.getColor(R.styleable.CustomViewStyle_titleTxtColor,
                Color.BLACK);

        //正文文本相干屬性
        mCustomCont = array.getString(R.styleable.CustomViewStyle_customCont);
        mContTxtSize = array.getDimensionPixelSize(R.styleable.CustomViewStyle_contTxtSize,
                (int) getResources().getDimension(R.dimen.cont_default_size));
        mContTxtColor = array.getColor(R.styleable.CustomViewStyle_contTxtColor,Color.GRAY);

        array.recycle();
    }


我自定義view時實現了3個構造方法,使用的是as中的快捷鍵創建的,以致于第3個構造方法根本就沒調用,所以做甚么都是錯的,解決方案很簡單,那就是把第2個構造方法的方法體改1下便可


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

利用this自己手動調用1下第3個構造方法便可。問題解決


問題2,繪制上發現所自定義的 view進行了全屏顯示,打開手機上顯示布局邊界的功能以后可以發現我所自定義的view進行了全屏顯示,占據了1個界面上父view所剩余的所有空間。





通過前幾篇對view的分析可以得出,這個draw繪制出來的大小跟onMeasure方法是分不開的,所以呢,重點是對所丈量的寬和高進行重新計算

利用paint畫筆對象可以直接對文本的寬高進行計算:

private Rect mBounds;

 mBounds = new Rect();


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

        int measuredWidth;
        int measuredHeight;
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);//獲得丈量規范,對這些不曉得可參考博文
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        mPaint.getTextBounds(mCustomTitle,0,mCustomTitle.length(),mBounds);


        if (widthMode != MeasureSpec.EXACTLY){
            measuredWidth = mBounds.width();

        }else{//在xml文件中規定了準確的值
            measuredWidth = width;
        }
        if (heightMode != MeasureSpec.EXACTLY){
            Log.i("fang","---");


            measuredHeight = mBounds.height();
        }else{
            measuredHeight = height;
        }

        setMeasuredDimension(measuredWidth + getPaddingLeft() + getPaddingRight(),
                measuredHeight + getPaddingTop() + getPaddingBottom());
    }


然落后行繪制:


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


        mPaint.setTextSize(mTitleTxtSize);
        mPaint.setColor(mTitleTxtColor);
        canvas.drawText(mCustomTitle,getPaddingLeft(),
                getHeight()/2 + mBounds.height()/2,mPaint);


    }


繪制時第2個和第3個參數決定了內容的x和y的坐標

繪制后結果以下圖



          


第1張圖是每次重新oncreate界面時的效果,(在此聲明1下設置的view是paddingleft為50dp)

第2張圖是每次onPause然后onResume以后的效果。

由以上這兩張圖可以發現兩個問題

第1,每次oncreate時view所繪制出的大小其實不正確

第2,view沒有自動換行,view的繪制已超越了父view的邊界

是否是發現問題層見疊出??漸漸來吧


問題3,在oncreate時view所繪制的大小不正確

問題4,view需要換行


問題3和問題4待解決中,估計需要點兒時間,有解決方案的請留言,謝謝,也歡迎各位分享你自定義view時所遇到的問題



生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 日韩一区国产二区欧美三区 | 亚洲乱码一二三四五六区 | 久草在线网址 | 欧美大尺寸 | 国产精品视频久久久久 | 日韩欧美一区黑人vs日本人 | 亚洲欧洲高清 | 久久国产精品亚洲一区二区 | 免费一区二区三区 | 国产a网 | 中日韩一区二区三区 | 最近免费中文字幕视频高清在线看 | 岛国福利视频 | 性欧美视频videos6一9 | freexxxhd性欧美 | 欧美一级特黄啪啪片免费看 | 伊人成伊人成综合网2222 | 激情校园春色小说 | 538亚洲欧美国产日韩在线精品 | 亚洲视频第二页 | 免费v片在线观看 | 图片区亚洲 | 国产成人精品天堂 | 亚洲精品伊人 | 亚洲精品福利网站 | 亚洲欧洲日本天天堂在线观看 | 国产a久久精品一区二区三区 | 亚洲黄色影视 | 亚州中文 | 欧美添下面视频免费观看 | 精品久久久久久国产 | free性video西欧极品 | 成人天堂在线 | 五月婷婷狠狠 | 免费在线h| 欧美日本高清一本二本三本 | 爱爱a| www国产视频 | 亚洲免费视频网 | 亚洲精品人成无码中文毛片 | 欧美日韩亚洲一区二区三区 |