手機螢幕尺寸


想取得手機螢幕尺寸可以用 DisplayMetrics 搭配 WindowManager 取得, 而 WindowManager 也能從 Display 取得手機旋轉方向,螢幕更新頻率等等,如下

GetDisplaySize.java

   1:  package com.example.helloworld;
   2:   
   3:  import android.app.Activity;
   4:  import android.os.Bundle;
   5:  import android.util.DisplayMetrics;
   6:  import android.view.Display;
   7:  import android.widget.TextView;
   8:   
   9:  public class GetDisplaySize extends Activity {
  10:   
  11:      final String tLog = "Trace Log";
  12:   
  13:      TextView tv1;
  14:   
  15:      @Override
  16:      public void onCreate(Bundle savedInstanceState) {
  17:   
  18:          super.onCreate(savedInstanceState);
  19:   
  20:          setContentView(R.layout.activity_main);
  21:   
  22:          tv1 = (TextView) findViewById(R.id.textView1);
  23:   
  24:          DisplayMetrics metr = new DisplayMetrics();
  25:          getWindowManager().getDefaultDisplay().getMetrics(metr);
  26:   
  27:          Display dplay = getWindowManager().getDefaultDisplay();
  28:   
  29:          tv1.setText("Width: " + metr.widthPixels + " Height: " //get width , height
  30:                  + metr.heightPixels + "\n" + "Rotation: " + dplay.getRotation() //get rotation 
  31:                  + " RefreshRate: " + dplay.getRefreshRate()); // get refreshrate
  32:   
  33:      }
  34:  }


第 24 行建立 DisplayMetrics 物件 metr
第 25 行藉由 WindowManager 傳入 metr 物件
第 27 行建立 Display 物件 dplay
第 29 行顯示 width 和 height
第 30 ~ 31 行顯示畫面旋轉方向和更新率(每秒)

為了方便範例的使用,把 GetDisplaySize.java 放入 和 HelloWorld.java 相同的套件目錄,並修改 AndroidManifest.xml如下


   1:  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
   2:      package="com.example.helloworld"
   3:      android:versionCode="1"
   4:      android:versionName="1.0" >
   5:   
   6:      <uses-sdk
   7:          android:minSdkVersion="8"
   8:          android:targetSdkVersion="15" />
   9:   
  10:      <application
  11:          android:icon="@drawable/ic_launcher"
  12:          android:label="@string/app_name"
  13:          android:theme="@style/AppTheme" >
  14:          <activity
  15:              android:name=".MainActivity"
  16:              android:label="@string/title_activity_main" >
  17:   
  18:              <!--
  19:              <intent-filter>
  20:                  <action android:name="android.intent.action.MAIN" />
  21:  
  22:                  <category android:name="android.intent.category.LAUNCHER" />
  23:              </intent-filter>
  24:              -->
  25:          </activity>
  26:          <activity
  27:              android:name=".GetDisplaySize"
  28:              android:label="@string/title_activity_main2" >
  29:              <intent-filter>
  30:                  <action android:name="android.intent.action.MAIN" />
  31:   
  32:                  <category android:name="android.intent.category.LAUNCHER" />
  33:              </intent-filter>
  34:          </activity>
  35:      </application>
  36:   
  37:  </manifest>


第 14 ~ 25 行為舊的 HelloWorld , 把 19 ~ 23 行註解掉,代表開始執行的 Activity 不是在此
第 26 ~ 34 行為新的 GetDisplaySize ,加入 30 ~32 行 ,代表開始執行的 Activity 在此

結果為
第 1 種旋轉畫面


















第 2 種旋轉畫面












當手機有設定自動旋轉畫面時,旋轉手機, onCreate( ) 會重新執行,所以在裡面的資料都會重新讀取,

觸碰偵測


本篇我們來看看在 Android 上的觸碰偵測,觸碰偵測的方法主要是由 onTouchEvent( Motion event) 來觸發,只要你使用的類別有這個方法,就能很簡單的使用,以上篇的 HelloWorld 為例,加以修改

MainActivity.java

   1:  package com.example.helloworld;
   2:   
   3:  import android.app.Activity;
   4:  import android.content.Context;
   5:  import android.graphics.Color;
   6:  import android.graphics.Typeface;
   7:  import android.os.Bundle;
   8:  import android.util.Log;
   9:  import android.view.Gravity;
  10:  import android.view.MotionEvent;
  11:  import android.widget.TextView;
  12:   
  13:  public class MainActivity extends Activity {
  14:      
  15:      static final String tLog = "Trace Log";
  16:      
  17:      TestTextView ttv;
  18:      
  19:      int dx;// get touch down x position
  20:      int dy;// get touch down y position
  21:      int mx;// get touch move x position
  22:      int my;// get touch move y position 
  23:      
  24:      @Override
  25:      public void onCreate(Bundle savedInstanceState) {
  26:          
  27:          super.onCreate(savedInstanceState);
  28:  //        setContentView(R.layout.activity_main);
  29:          
  30:          ttv = new TestTextView(this);
  31:          
  32:          ttv.setTextColor(0xff888888); // set color
  33:          ttv.setTextSize(18.0f); // set size
  34:          ttv.setTypeface(Typeface.SERIF);// set typeface 
  35:          ttv.setText(R.string.copy_right);// change text
  36:          ttv.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
  37:          setContentView(ttv);
  38:   
  39:          
  40:      }
  41:      
  42:      public boolean onTouchEvent(MotionEvent event){
  43:          
  44:          int touchCount = event.getPointerCount(); // get touchcount
  45:          Log.v(MainActivity.tLog, ""+touchCount);
  46:          
  47:          switch(event.getAction()){
  48:          
  49:              case MotionEvent.ACTION_DOWN://touch down
  50:                  ttv.setTextColor(Color.RED);
  51:                  dx = (int) event.getX();// get x position
  52:                  dy = (int) event.getY();// get y position
  53:                  break;
  54:              case MotionEvent.ACTION_UP://touch leave
  55:                  ttv.setTextColor(0xff888888);
  56:                  break;
  57:              case MotionEvent.ACTION_MOVE://touch move
  58:                  
  59:                  mx = (int) event.getX();// get x position
  60:                  my = (int) event.getY();// get y position
  61:                  
  62:                  if(Math.abs(dx-mx)>20 || Math.abs(dy-my)>20)
  63:                  {
  64:                      ttv.setTextColor(Color.GREEN);
  65:                  }
  66:                  
  67:                  break;
  68:          }
  69:          
  70:          return true;
  71:      }
  72:    
  73:  }
  74:   
  75:   
  76:  class TestTextView extends TextView{
  77:   
  78:      public TestTextView(Context context) {
  79:          super(context);
  80:          // TODO Auto-generated constructor stub
  81:      }
  82:      
  83:  }


第 17 行把 ttv 做為 MainActivity 的物件,這樣可以讓我在 onTouchEvent() 方便改變顏色
第 19 ~ 22 行用來儲存按下以及移動的座標,這是為了讓移動不這麼靈敏
第 42 ~ 71 行就是偵測觸碰點的方法
第 44 行取得觸碰的總數,不過後面沒用到
第 47 行取得觸碰點的行為,行為種類相當多,後面只示範比較基本的方法(按下移動離開),詳細請參考這裡
第 49 行為按下的行為,我把 ttv 改為紅色(第 50 行)
第 51 ~ 52 行取得按下時的座標
第 54 行為離開的行為, ttv 恢復顏色
第 57 行為移動的行為
第 59 ~ 60 行取得移動時的座標,
第 62 ~ 65 行當移動時的座標變動不太大時才改變顏色, 事實上你也可以直接使用第 64 行,它非常靈敏

結果為
正常狀態                              

















按下狀態

















移動狀態
























TextView (顯示文字內容)


想要顯示一些文字內容可以使用 TextView ,這個類別提供相當多的方法讓你可以自由改變顯示的格式,如顏色,尺寸,位置,字型等等,相關的方法請參考 Android API ,範例如下

MainActivity.java

   1:  package com.example.helloworld;
   2:   
   3:  import android.app.Activity;
   4:  import android.os.Bundle;
   5:  import android.widget.TextView;
   6:   
   7:  public class MainActivity extends Activity {
   8:      
   9:      TextView tv1 = null;// make a TextView reference
  10:      
  11:      @Override
  12:      public void onCreate(Bundle savedInstanceState) {
  13:          
  14:          super.onCreate(savedInstanceState);
  15:          setContentView(R.layout.activity_main);
  16:          
  17:          tv1 = (TextView)findViewById(R.id.textView1); // get xml resource (R.id.textView1)
  18:          tv1.setText("測試文字  Vulpes Z.G.H");// change text
  19:          
  20:      }
  21:      
  22:  }


第 9 行為了方便修改文字內容,建立 tv1 物件
第 17 行取得在 xml 定義的 TextView,注意 findViewById(R.id.textView1) 回傳為 View 物件, 由於 TextView 為 View 的子類別,所以必須強制轉型
第 18 行修改文字內容為 測試文字 Vulpes Z.G.H



















通常做為版權宣告流程也是相當方便的,以下範例我把版權聲明加入

MainActivity.java

   1:  package com.example.helloworld;
   2:   
   3:  import android.app.Activity;
   4:  import android.graphics.Typeface;
   5:  import android.os.Bundle;
   6:  import android.widget.TextView;
   7:   
   8:  public class MainActivity extends Activity {
   9:      
  10:      TextView tv1 = null;// make a TextView reference
  11:      
  12:      @Override
  13:      public void onCreate(Bundle savedInstanceState) {
  14:          
  15:          super.onCreate(savedInstanceState);
  16:          setContentView(R.layout.activity_main);
  17:          
  18:          tv1 = (TextView)findViewById(R.id.textView1); // get xml resource (R.id.textView1)
  19:  //        tv1.setTextColor(Color.RED); // set color
  20:          tv1.setTextColor(0xff888888); // set color
  21:          tv1.setTextSize(18.0f); // set size
  22:          tv1.setTypeface(Typeface.SERIF); // set typeface 
  23:          tv1.setText(R.string.copy_right);// change text
  24:          
  25:      }
  26:      
  27:  }


第 20 行設定 text 顏色,你可以使用 Color 類別中已經定義好的顏色,也可以自己指定色碼
第 21 行設定 text 尺寸,參數為 float
第 22 行設定 text 字型,有 3 種可選
第 23 行設定 text 內容,其中 R.string.copy_right 為 xml 已經定義好的字串,你也可以在程式碼中加入想要顯示的字串內容

結果為


















上面的範例是使用 xml 中已經定義好的 Layout 建立, 你也可以改為在程式碼中建立 TextView,如下

MainActivity.java

   1:  package com.example.helloworld;
   2:   
   3:  import android.app.Activity;
   4:  import android.content.Context;
   5:  import android.graphics.Typeface;
   6:  import android.os.Bundle;
   7:  import android.view.Gravity;
   8:  import android.widget.TextView;
   9:   
  10:  public class MainActivity extends Activity {
  11:      
  12:      @Override
  13:      public void onCreate(Bundle savedInstanceState) {
  14:          
  15:          super.onCreate(savedInstanceState);
  16:  //        setContentView(R.layout.activity_main);
  17:          
  18:          TestTextView ttv = new TestTextView(this);
  19:          
  20:          ttv.setTextColor(0xff888888); // set color
  21:          ttv.setTextSize(18.0f); // set size
  22:          ttv.setTypeface(Typeface.SERIF);// set typeface 
  23:          ttv.setText(R.string.copy_right);// change text
  24:          ttv.setGravity(Gravity.CENTER_VERTICAL);
  25:          setContentView(ttv);
  26:          
  27:      }
  28:      
  29:    
  30:  }
  31:   
  32:   
  33:  class TestTextView extends TextView{
  34:   
  35:      public TestTextView(Context context) {
  36:          super(context);
  37:          // TODO Auto-generated constructor stub
  38:      }
  39:      
  40:  }


為了方便說明我在第 33 ~ 40 行建立一個 TestTextView , 並在 18 行建立該類別的物件
第 16 行不用 xml 中的佈局,接著第 20 ~ 24 行就如同原本的程式碼內容一樣
第 25 行套用 ttv 物件


當然在 TextView 類別中還有 20~ 30 種方法,足夠處理大部分顯示文字的情況,比如說 length( )取得文字長度,由於 TextView 繼承 View ,所以你也能覆寫 onTouchEvent( ) 方法來偵測觸碰事件,以下範例,在用手指拖曳螢幕,版權畫面就會閃爍


  34:  class TestTextView extends TextView{
  35:   
  36:      public TestTextView(Context context) {
  37:          super(context);
  38:          // TODO Auto-generated constructor stub
  39:      }
  40:      
  41:      public boolean onTouchEvent(MotionEvent event){
  42:          
  43:          if(getAlpha()>0)
  44:              setAlpha(getAlpha()-0.1f);
  45:          else
  46:              setAlpha(1.0f);
  47:              
  48:          return true;
  49:      }
  50:      
  51:  }


第 40 行覆寫 onTouchEvent(MotionEvent event) 以取得觸碰螢幕事件,在裡面直接修改 Alpha 值,該值控制物件的顯示程度

結果就像這樣



















關於 TextView 的小技巧,
限制字數
android:maxEms="4"
單行顯示
android:singleLine="true"

HelloWorld 目錄結構之2(Activity生命週期和Trace Log方法)


上篇介紹 Android 4個基本模組以及目錄結構,本篇提供簡單的偵錯方式以及針對 Activity 再做更深入的研究,經過實機測試,可以證明程序的確是照著我們的寫法來運作,若是想進一步得到程序中的數值,就必須使用其他方法來測試,可以使用 Log 類別來達成, Log 提供 5 個簡單的方法來追蹤程序的進行,我們把上篇的 MainActivity.java 改為

MainActivity.java

   1:  package com.example.helloworld;
   2:   
   3:  import android.os.Bundle;
   4:  import android.util.Log;
   5:  import android.app.Activity;
   6:   
   7:  public class MainActivity extends Activity {
   8:      
   9:      @Override
  10:      public void onCreate(Bundle savedInstanceState) {
  11:          
  12:          Log.v("Trace Log", "Log1");
  13:          
  14:          super.onCreate(savedInstanceState);
  15:          setContentView(R.layout.activity_main);
  16:          
  17:          Log.i("Trace Log", "Log2");
  18:         
  19:      }
  20:      
  21:  }


第 4 行匯入 Log 類別,讓我們在後面的程式碼中可以使用
第 12 行 Log.v("Trace Log", "Log1"); 第 1 個參數為 Tag (標籤名稱), 第 2 個參數為顯示內容
第 17 行 Log.i("Trace Log", "Log2"); i 和 v 的差別為在 LogCat 中顯示的顏色不同

改完程式碼之後,執行程序吧,執行程序後點擊 Eclipse 中的 LogCat 視窗來查看顯示內容







可以看到顯示的 Text 相當多,因為預設的情況不會過濾顯示的 Text 內容,我們可以在左邊的 Save Filter 加入自訂的過濾器,可以命名過濾器的名稱以及過濾的項目等等,











設定完過濾器之後再執行,可以看到顯示的 Text 變為 2 個







這就是簡單的 Trace Log 的方式

接下來我們再對 Activity 進一步的研究,查看 Android API 可以發現 Activity 本身有 20 ~ 30 種方法可以使用, 其中重要的就是掌控其生命週期的方法, 分別有 onCreate( ) , onStart( ) , onResume( ) , onPause( ) , onStop( ) , onRestart( ) ,onDestroy( ), 對應不同的生命週期狀態,請參考 Android API 提供的生命週期圖,為了方便觀察其變化我們將 MainActivity.java 再次修改

MainActivity.java

   1:  package com.example.helloworld;
   2:   
   3:  import android.os.Bundle;
   4:  import android.util.Log;
   5:  import android.app.Activity;
   6:   
   7:  public class MainActivity extends Activity {
   8:      
   9:      final String tt= "Trace Log";
  10:      
  11:      @Override
  12:      public void onCreate(Bundle savedInstanceState) {
  13:          
  14:          super.onCreate(savedInstanceState);
  15:          setContentView(R.layout.activity_main);
  16:       
  17:          Log.i(tt, "onCreate");
  18:      }
  19:      
  20:      public void onStart(){
  21:          super.onStart();
  22:          
  23:          Log.i(tt, "onStart");
  24:      }
  25:      
  26:      public void onResume(){
  27:          super.onResume();
  28:          
  29:          Log.i(tt, "onResume");
  30:      }
  31:      
  32:      public void onPause(){
  33:          super.onPause();
  34:   
  35:          Log.i(tt, "onPause");
  36:      }
  37:      
  38:      public void onRestart(){
  39:          super.onRestart();
  40:          
  41:          Log.i(tt, "onRestart");
  42:      }
  43:      
  44:      public void onStop(){
  45:          super.onStop();
  46:          
  47:          Log.i(tt, "onStop");
  48:      }
  49:      
  50:      public void onDestroy(){
  51:          super.onDestroy();
  52:     
  53:          Log.i(tt, "onDestroy");
  54:      }
  55:      
  56:  }
  57:


在第 9 行我使用 tt 來代替 "Trace Log" ,這樣之後的追蹤 Log, 只要輸入 tt, 或是 Ctrl + v 就能完成,接著在 20 , 26 , 32 , 38 , 44 , 50 行分別覆寫方法,並加入追蹤,執行程序看看吧,執行程序後可以發現依序印出, onCreate -> onStart -> onResume

 接著點選手機的 Home 鍵跳離程序,會印出 onPause -> onStop -> onDestroy , 此時程序並沒有停止







手機上再點擊程序,會發現印出 onCreate -> onStart -> onResume, 和開始程序時相同,由此可知只要我們在在這些掌控生命週期的方法中寫入需要的功能,就可以加強整個程序完整性,如跳出程序之前儲存資料,程序運作中若有來電的處理等等





Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Affiliate Network Reviews