標籤:
上一章講述了Android介面設計時,一些基本控制項的使用,本章主要講述自訂控制項,Fragment和Headler線程機制。
1.自訂控制項
(1)基本知識
dp、sp和dx
px:像素點
dp:與像素密度密切相關
sp:相當於dp,修飾文字專用
dip:相當於dp
用法:
文字尺寸一律用sp
非文字尺寸一律用dp
偶爾需要用px 例如:在螢幕上畫細的分割線 1px
當一個控制項不在右側預覽視圖裡面顯示的時候是因為控制項沒有明確的位置,需要設定一個位置之後才能正常顯示
構造器初始化 :
- onMesure() 定大小
- onLayout() 定位置
- onDraw() 繪製
- invalidate() 重新整理
自訂控制項的三種主要建立形式:
- 繼承已有的控制項來實現自訂控制項,如 Button、 CheckedTextView;
- 通過繼承一個布局檔案實現自訂控制項,如RelativeLayout;
- 通過繼承view類來實現自訂控制項。
(2)提取布局屬性 theme & style
- Theme是針對表單層級的,改變表單樣式;Style 是針對表單元素層級的,改變指定控制項或者Layout的樣式;
- 抽象view的共同屬性;
- 可繼承
對於定製一個自訂控制項,可通過如下步驟:
(1)基本屬性定義在一個設定檔中attrs.xml :
<?xml version="1.0" encoding="utf-8"?> <resources> //類 <declare-styleable name="ViewTest"> //每一個attr都是一個屬性,每個屬性都有一個format <attr name="backgroundColor" format="color"/> <attr name="textColor" format="color"/> <attr name="textSize" format="dimension"/> </declare-styleable></resources>
(2)定義一個控制項View類:
1 package com.example.chenjinhua.redcircle; 2 3 import android.content.Context; 4 import android.graphics.Canvas; 5 import android.graphics.Color; 6 import android.graphics.Paint; 7 import android.graphics.Rect; 8 import android.util.AttributeSet; 9 import android.view.View;10 11 public class DrawRedCircleView extends View implements View.OnClickListener{12 private Paint mPaint;13 private Rect mRect;14 private int mNumber = 20;15 16 public DrawRedCircleView(Context context) {17 this(context, null);18 }19 20 public DrawRedCircleView(Context context, AttributeSet attrs) {21 this(context, attrs, 0);22 }23 24 public DrawRedCircleView(Context context, AttributeSet attrs, int defStyleAttr) {25 super(context, attrs, defStyleAttr);26 init();27 }28 29 private void init() {30 mPaint = new Paint();31 mRect = new Rect();32 }33 34 @Override35 protected void onDraw(Canvas canvas) {36 super.onDraw(canvas);37 mPaint.setColor(Color.RED);38 canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, mPaint);39 40 mPaint.setColor(Color.WHITE);41 mPaint.setTextSize(100);42 String textNumber = String.valueOf(mNumber);43 mPaint.getTextBounds(textNumber,0,textNumber.length(),mRect);44 int textWidth = mRect.width();45 int textHight = mRect.height();46 canvas.drawText(textNumber,getWidth()/2 - textWidth/2,getWidth()/2 + textHight/2,mPaint);47 48 View view = findViewById(R.id.redCircle_view);49 view.setOnClickListener(this);50 51 }52 53 @Override54 public void onClick(View view) {55 if ( mNumber > 0 ){56 mNumber --;57 }else{58 mNumber = 20;59 }60 invalidate();61 }62 }自訂控制項類
(3)視圖頁面引用:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"//添加自訂命名空間xmlns:jinhua="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!--引用自訂的控制項--> <com.example.chenjinhua.thirdweek.ViewTest android:layout_width="300dp" android:layout_height="300dp" jinhua:backgroundColor="@color/colorAccent" jinhua:textSize="18dp"/> <!--attrs檔案中定義的屬性--> </LinearLayout>
(4)Activity類中定義和使用
2.Fragment
(1)什麼是Fragment
Fragment是activity介面中的一部分,多個Fragment組合到一個activity中。多個activity中可重用一個Fragment。
Fragment相當於模組化一個activity具有自己的生命週期,接收自己的事件,在activity運行時被添加或刪除。
(2)為什麼要使用Fragment
支援更動態更靈活的介面設計,在平板上的應用(左邊列表,右邊新聞)Activity的layout分成Fragment。
(3)Fragmet應用
getSupportFragmentManager().beginTransaction().
setCustomAnimations(R.anim.slide_in_from_right, R.anim.slide_out_to_left).
replace(R.id.fl_content, new ReadCardFragment(), "latest").
commit();
//setCustomAnimations:指定Fragment切換的動畫效果
3.Headler多線程與非同步
(1)Handler用來做什嗎?
- 定時執行Message和MessageQueue;
- 在不同線程中執行Runnable。
(2)Handler怎麼使用?
- obtainMessage() //取得訊息
- sendMessage() //發送訊息
- handlerMessage() //處理訊息
(3)Handler基本使用方法:
Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case TestHandler.GUIUPDATEIDENTIFIER:
myBounceView.invalidate();
break;
}
super.handleMessage(msg);
}
};
class myThread implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
Message message = new Message();
message.what = TestHandler.GUIUPDATEIDENTIFIER;
TestHandler.this.myHandler.sendMessage(message);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
在android中提供了一種非同步回調機制Handler,使用它,我們可以在完成一個很長時間的任務後做出相應的通知。
在主線程中,使用handler很簡單,new一個Handler對象實現其handleMessage方法,在handleMessage中提供收到訊息後相應的處理方法即可。
使用myThreadHandler.sendEmptyMessage(0);發送一個message對象,那麼Handler是如何接收該message對象並處理的呢?如下資料結構圖:
從這個圖中我們很清楚可以看到調用sendEmptyMessage後,會把 Message對象放入一個MessageQueue隊列,該隊列屬於某個Looper對象,每個Looper對象通過 ThreadLocal.set(new Looper())跟一個Thread綁定了,Looper對象所屬的線程在Looper.Loop方法中迴圈執行從MessageQueue隊列讀取 Message對象,並把Message對象交由Handler處理,調用Handler的dispatchMessage方法。
android開發-介面設計基本知識Ⅱ