編輯:關於Android編程
public class MyView extends View { private static final String TAG = "MyView"; public MyView(Context context, AttributeSet attrs) { super(context, attrs); } /** * measure - > onMeasure ,view的源碼中,measure會調用onMeasure */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //測量, 表示這個view的大小, 在View的源碼中, Measure是final修飾的, 我們只能重寫onMeasure方法 // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); Log.d(TAG, "measure"); } /** * layout - > setFrame 和 onLayout */ @Override public void layout(int l, int t, int r, int b) { //布局,決定了擺放在父容器中的哪個位置 // TODO Auto-generated method stub super.layout(l, t, r, b); Log.d(TAG, "layout"); } /** * draw - > onDraw */ @Override public void draw(Canvas canvas) { //繪制 // TODO Auto-generated method stub super.draw(canvas); Log.d(TAG, "draw"); } }以上就是View繪制顯示在屏幕上必定會調用的三個方法, 可能你還不太理解, 不過沒關系, 先混個臉熟, 有個印象先, 下面我們一個個分析.
public class MyView extends View { private static final String TAG = "MyView"; public MyView(Context context, AttributeSet attrs) { super(context, attrs); } /** * measure -> onMeasure * * 1.父容器拿到孩子的申請的寬高layout_width, layout_height封裝成寬高的期望widthMeasureSpec和heightMeasureSpec * 父容器Relativelayout(或者其他Linearlyout) * 調用MyView的 measure(int widthMeasureSpec, int heightMeasureSpec)傳入對孩子寬高的期望 * measure -> onMeasure(widthMeasureSpec, heightMeasureSpec) * * @param widthMeasureSpec 父容器(RelativeLaoyut)對孩子MyView的寬度期望, 跟layout_width相關 * @param heightMeasureSpec 父容器(RelativeLaoyut)對孩子MyView的高度期望, 跟layout_height相關 * 這是我們為什麼一定要指定layout_width和layout_height的原因. */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { /** * int widthMeasureSpec * 32位二進制 * 前兩位 是測量模式 mode * public static final int UNSPECIFIED = 0 << MODE_SHIFT; 父容器對孩子沒有任何的限制,孩子想多大多大 * public static final int EXACTLY = 1 << MODE_SHIFT; 父容器對孩子有確切的大小要求,大小就會後30位 * public static final int AT_MOST = 2 << MODE_SHIFT; 父容器對孩子的最大值有要求,大小就會後30位 * 後30位表示大小 */ int mode = MeasureSpec.getMode(widthMeasureSpec); int size = MeasureSpec.getSize(widthMeasureSpec); Log.d(TAG, "onMeasure mode " + (mode>>30) + " " + size); //super方法默認使用父容器對我的期望的寬高 super.onMeasure(widthMeasureSpec, heightMeasureSpec); //我們也可以不調用super直接調用setMeasuredDimension(50, 50)來指定寬高 } }注釋裡的setMeasuredDimension(int measuredWidth, int measuredHeight)是一個重要的方法, 它是整個測量結束的標志, 只有這個方法調用了, 我們才能調用getMeasuredWidth()或者getMeasuredHeight()方法獲得測量寬高(注意, 不是實際寬高, 實際寬高要在布局完成之後)。 自定義View如果要使用wrap_content屬性的話,則需重寫onMeasure方法。
view的繪制分為6步:
對視圖的背景進行繪制 If necessary, save the canvas’ layers to prepare for fading (暫時忽略它) 對視圖的內容進行繪制, 在onDraw(canvas)方法中完成 對當前視圖的所有子視圖進行繪制 ,調用dispatchDraw。 If necessary, draw the fading edges and restore layers (暫時忽略它) 繪制裝飾品(如滾動條)任何一個視圖都是有滾動條的,只是一般情況下我們都沒有讓它顯示出來而已.即我們關心四個步驟:
繪制背景 繪制內容 繪制孩子 繪制裝飾繪制需要兩個類, 畫布(Canvas)和畫筆(Paint), 通過以下Demo通過onDraw方法利用畫筆在畫布上繪制我們的圖案吧.
public class MyView extends View { private Paint mPaint; private Bitmap mBitmap; private Path mPath; private RectF mOval; public MyView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); //設置去鋸齒 mPaint.setAntiAlias(true); //配置畫筆,畫空心圓 mPaint.setStyle(Style.STROKE); //設置畫筆寬度 mPaint.setStrokeWidth(3); //設置畫筆顏色 mPaint.setColor(Color.BLUE); //畫圖片時需要設置圖片 mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.haha); //設置扇形的大小 mOval = new RectF(5, 5, 195, 195); initPath(); } private void initPath() { mPath = new Path(); //確定三個點 int x1 = 100, y1 = 5; int x2 = 195, y2 = 195; int x3 = 5, y3 = 195; //移動到第一個點 mPath.moveTo(x1, y1); //鏈接第一個點和第二個點 mPath.lineTo(x2, y2); //鏈接第二個點和第三個點 mPath.lineTo(x3, y3); mPath.lineTo(x1, y1); } /** * 不要在onDraw方法裡面創建新的對象,因為onDraw方法可能會頻繁調用 */ @Override protected void onDraw(Canvas canvas) { // 6. 裁剪 // canvas.clipPath(mPath); // 1. 畫直線 // int startX =5, startY = 100; // int stopX = 195, stopY = 100; // canvas.drawLine(startX, startY, stopX, stopY, mPaint); // 2. 畫圓 // int cx = 100, cy = 100; // int radius = 80; // canvas.drawCircle(cx, cy, radius, mPaint); // 3. 畫空心圓 // 4. 畫圖片 // canvas.drawBitmap(mBitmap, 0, 0, mPaint); // 5. 畫三角形 // canvas.drawPath(mPath, mPaint); //7.畫扇形 int startAngle = -90; //開始的角度 int sweepAngle = 45; //掃過的角度 boolean useCenter = false;//是否畫出扇形的兩邊 canvas.drawArc(mOval, startAngle, sweepAngle, useCenter, mPaint); } }
自Android x86出來後,很多人開始在虛擬機上安裝繼續體驗,但是安裝並不是很簡單,隨之網上各種安裝教程就出現了,Virtualbox虛擬機下Andro
1.准備工作 安裝django框架 安裝django-rsetful 框架 pip install djangorestframework 2.一個小d
前言給自己的APP增加相機是一個不錯的功能,在我們打開相機時,如果能動態給我們的臉上貼上標簽,或者是貼上一個卡通的眼睛,最後點擊拍照,一張合成的圖片就產生了,這是不是一個
Android 開機自啟動示例程序。使用廣播方式接受,采用Android自帶存儲SharedPreferences存儲開機自啟動的設置。本文源碼:點擊1、先加上權限&nb