android 自定義view

1. 獲取屏幕

獲取屏幕高,寬,狀態欄高度,title高度

DisplayMetrics  dm = new DisplayMetrics(); 

      //取得窗口屬性 

     getWindowManager().getDefaultDisplay().getMetrics(dm); 

      

      //窗口的寬度 

      int screenWidth = dm.widthPixels; 

      

      //窗口高度 

      int screenHeight = dm.heightPixels; 

// 屏幕密度

      float density = dm.density;

      int densityDip = dm.densityDpi;

     

Rect frame = new Rect();

     getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);

      int statusBarHeight = frame.top;

     

      int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();

    //statusBarHeight是上面所求的狀態欄的高度

    int titleBarHeight = contentTop -statusBarHeight;

     textView =(TextView)findViewById(R.id.screen_message);        

      textView.setText("屏幕寬度: " + screenWidth + "\n屏幕高度: " + screenHeight + "\n 密度:" + density

                                  + "\n dip密度:" + densityDip + "\n 狀態欄:" );


2. 獲取view 相對於父View 的座標

mBounds = new RectF(getLeft(),getTop(),getRight(),getBottom());
 view 的width,height;
        width = mBounds.right - mBounds.left;
        height = mBounds.bottom - mBounds.top;
3. 重寫onMesure

    系統不會爲wrap_content 測量大小,如果是設置了明確的大小,或是match_parent 那麼就不用重寫onMesure 了

    

MeasureSpec的specMode,一共三種類型:

EXACTLY:一般是設置了明確的值或者是MATCH_PARENT

AT_MOST:表示子佈局限制在一個最大值內,一般爲WARP_CONTENT

UNSPECIFIED:表示子佈局想要多大就多大,很少使用,一般用在scroll view 中。

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
	{
		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		int heightSize = MeasureSpec.getSize(heightMeasureSpec);
		int width;
		int height ;
		if (widthMode == MeasureSpec.EXACTLY)
		{
			width = widthSize;
		} else
		{
			mPaint.setTextSize(mTitleTextSize);
			mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBounds);
			float textWidth = mBounds.width();
			int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
			width = desired;
		}

		if (heightMode == MeasureSpec.EXACTLY)
		{
			height = heightSize;
		} else
		{
			mPaint.setTextSize(mTitleTextSize);
			mPaint.getTextBounds(mTitle, 0, mTitle.length(), mBounds);
			float textHeight = mBounds.height();
			int desired = (int) (getPaddingTop() + textHeight + getPaddingBottom());
			height = desired;
		}
		setMeasuredDimension(width, height);
	}
4. onSizeChange() 重新設置高寬

5. 界面的更新

Invalidate和postInvalidate,invalidate 是在UI線程中更新,通過hanlder 更新, postInvalidate 是在非UI線程中執行



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章