編輯:中級開發
范例程序src/irdc.ex04_11/EX04_11.java范例中以Java.io.File對象來取得根目錄下的文件,經過比較後,將符合結果的文件路徑寫入TextView中,若要在TextVIEw中換行,需使用 \n來作換行符號。
package irdc.ex04_11;
/* import相關class */
import Java.io.File;
import android.app.Activity;
import android.os.Bundle;
import android.view.VIEw;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextVIEw;
public class EX04_11 extends Activity
{
/*聲明對象變量*/
private Button mButton;
private EditText mKeyWord;
private TextVIEw mResult;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* 載入main.XML Layout */
setContentVIEw(R.layout.main);
/* 初始化對象 */
mKeyword=(EditText)findVIEwById(R.id.mKeyWord);
mButton=(Button)findVIEwById(R.id.mButton);
mResult=(TextView) findVIEwById(R.id.mResult);
/* 將mButton添加onClickListener */
mButton.setOnClickListener(new Button.OnClickListener()
{
public void onClick(VIEw v)
{
/*取得輸入的關鍵字*/
String keyword = mKeyWord.getText().toString();
if(keyWord.equals(""))
{
mResult.setText("請勿輸入空白的關鍵字!!");
}
else
{
mResult.setText(searchFile(keyWord));
}
}
});
}
/* 搜索文件的method */
private String searchFile(String keyWord)
{
String result="";
File[] files=new File("/").listFiles();
for( File f : files )
{
if(f.getName().indexOf(keyWord)>=0)
{
result+=f.getPath()+"\n";
}
}
if(result.equals("")) result="找不到文件!!";
return result;
}
}
擴展學習在本范例中,searchFile(String keyWord) 這個方法的功用為搜索根目錄下符合關鍵字的文件,在搜索文件的過程中,只搜索根目錄中的文件,並沒有再對子目錄下的文件作進一步的比較,如果要再強化這個文件搜索的功能,讓它也能搜索包含子目錄下的所有文件,可以在程序中利用File.isDirectory() 這個方法來判斷其是否為目錄。如果是的話,就繼續往下一層尋找;不是的話,就終止向下尋找的動作。這個做法在後面的范例中會有詳細的示范,要注意的是手機硬件環境是否能負荷程序做大規模的文件搜索,畢竟手機的硬件配備(處理器、內存)是比不上一般計算機的。
另外,在范例中僅針對關鍵字做了空白檢查,在比較文件名稱時也沒有忽略大小寫(要大小寫完全符合才搜索的出來),如果要讓這個搜索功能更完備,當然可以多做一點變化,例如,檢查關鍵字是否包含特殊的字符、可選擇比較文件時是否忽略大小寫、可選擇要搜索的文件類型,甚至是可自己指定要搜索的目錄等等,就看各位要如何運用了。
范例說明android默認的按鈕通常都是方方正正的,也許前面的范例已經看過如何通過ImageButton來置換按鈕背景圖片了,但本范例的練習則是在兩個按鈕之間的交互,點擊A按鈕,恢復B按鈕圖片;點擊B按鈕,恢復A按鈕的圖片。使用的方法為點擊的瞬間置換圖片,置換的圖片方式與先前介紹的相同(ImageButton.setImageDrawable)。
程序項目預先import了三張圖片:p1.png、p2.png以及p3.png,而在onCreate() 時,畫面Layout上的兩個ImageButton各自顯示p1.png以及p2.png,當點擊其一按鈕,則改變自己的圖片為p3.png,並還原另一按鈕的為默認的圖文件,以按鈕事件及圖文件置換的方式來提醒User現在所“選擇”的圖像按鈕為何。
運行結果
▲圖4-12 被點擊的ImageButton因變換圖片而被Hightlight出來
范例程序src/irdc.ex04_12/EX04_12.Java范例程序主要通過setImageDrawable方法來改變按鈕的圖片,圖片是放在res/drawable目錄下面。而ImageButton.setOnClickListener() 的角色則是本程序的關鍵,通過同時換兩個按鈕的圖片來表示被選擇的圖片,是一種類似被選擇的假象手法,常應用於切換開關(Turn On/Turn Off)之用。
package irdc.ex04_12;
import android.app.Activity;
import android.os.Bundle;
import android.view.VIEw;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextVIEw;
public class EX04_12 extends Activity
{
TextView myTextVIEw;
ImageButton myImageButton_1;
ImageButton myImageButton_2;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* 載入main.XML Layout */
setContentVIEw(R.layout.main);
/* 以findViewById()取得TextVIEw及ImageButton對象 */
myTextView = (TextView) findViewById(R.id.myTextVIEw);
myImageButton_1=(ImageButton)findVIEwById(R.id.myImageButton_1);
myImageButton_2=(ImageButton)findVIEwById(R.id.myImageButton_2);
/* myImageButton_1添加OnClickListener */
myImageButton_1.setOnClickListener(new Button.OnClickListener()
{
public void onClick(VIEw v)
{
myTextVIEw.setText("你點擊的是myImageButton_1");
/* 點擊myImageButton_1時將myImageButton_1圖片置換成p3圖片 */
myImageButton_1.setImageDrawable(getResources().getDrawable(
R.drawable.p3));
/* 點擊myImageButton_1時將myImageButton_2圖片置換成p2圖片 */
myImageButton_2.setImageDrawable(getResources().getDrawable(
R.drawable.p2));
}
});
/* myImageButton_2添加OnClickListener */
myImageButton_2.setOnClickListener(new Button.OnClickListener()
{
public void onClick(VIEw v)
{
myTextVIEw.setText("你點擊的是myImageButton_2");
/* 點擊myImageButton_2時將myImageButton_1圖片置換成p1圖片 */
myImageButton_1.setImageDrawable(getResources().getDrawable(
R.drawable.p1));
/* 點擊myImageButton_2時將myImageButton_2圖片置換成p3圖片 */
myImageButton_2.setImageDrawable(getResources().getDrawable(
R.drawable.p3));
}
});
}
}
擴展學習除了自己在res/drawable放置圖片方式外,也可以用系統android操作系統默認的圖片,如打電話、簡短提示的圖標等等,只要修改main.XML裡ImageButton的屬性:
android:src="@drawable/p1"
將其改成
android:src="@android:drawable/sym_action_call"
看到了嗎?標識“@android:”就表示是引用android所提供,而非自行導入的。
范例說明通過Google上網搜索時,只要輸入幾個文字,就會顯示可能的關鍵字讓你挑選,這種效果在Android中是非常容易達到的。事實上,android的AutoCompleteTextVIEw Widget,只要搭配ArrayAdapter就能設計出類似Google搜索提示的效果。
本范例先在Layout當中布局一個AutoCompleteTextView Widget,然後通過預先設置好的字符串數組,將此字符串數組放入ArrayAdapter,最後利用AutoCompleteTextView.setAdapter方法,就可以讓AutoCompleteTextVIEw Widget具有自動完成提示的功能。例如,只要輸入ab,就會自動帶出包含ab的所有字符串列表。
運行結果
▲圖4-13 只要輸入ab,就會自動帶出所有包含ab的字符串列表
范例程序src/irdc.ex04_13/EX04_13.Java本范例程序主要示范AutoCompleteTextView用法,再次使用到ArrayAdapter,只要是有下拉菜單的項目,都必須使用到ArrayAdapter對象。此外,將ArrayAdapter添加AutoCompleteTextVIEw對象中,所使用的方法為setAdapter,當中傳輸唯一的參數類型即為字符串類型的ArrayAdapter。
package irdc.ex04_13;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextVIEw;
public class EX04_13 extends Activity
{
private static final String[] autoStr = new String[]
{ "a", "abc", "abcd", "abcde" };
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* 載入main.XML Layout */
setContentVIEw(R.layout.main);
/* new ArrayAdapter對象並將autoStr字符串數組傳入 */
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, autoStr);
/* 以findViewById()取得AutoCompleteTextVIEw對象 */
AutoCompleteTextView myAutoCompleteTextVIEw =
(AutoCompleteTextView) findViewById(R.id.myAutoCompleteTextVIEw);
/* 將ArrayAdapter添加AutoCompleteTextVIEw對象中 */
myAutoCompleteTextVIEw.setAdapter(adapter);
}
}
擴展學習有個類似AutoCompleteTextView的對象,稱為MultiAutoCompleteTextView,它繼承了AutoCompleteTextVIEw,差別在於它可以在輸入框一直增加新的選擇值,其編寫方式也有些不同,一定要setTokenizer,否則會出現錯誤,以下范例是傳入CommaTokenizer類,結果會將原本選擇框裡的值往後加逗號及空白。
package irdc.ex04_13;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextVIEw;
import android.widget.MultiAutoCompleteTextVIEw;
public class EX04_13 extends Activity
{
private static final String[] autoStr = new String[]
{ "a", "abc", "abcd", "abcde" };
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* 載入main.XML Layout */
setContentVIEw(R.layout.main_1);
/* new ArrayAdapter對象並將autoStr字符串數組傳入 */
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, autoStr);
/* 以findViewById()取得MultiAutoCompleteTextVIEw對象 */
MultiAutoCompleteTextView myAutoCompleteTextVIEw =
(MultiAutoCompleteTextVIEw)
findViewById(R.id.myAutoCompleteTextVIEw);
/* 將ArrayAdapter添加AutoCompleteTextVIEw對象中 */
myAutoCompleteTextVIEw.setAdapter(adapter);
myAutoCompleteTextVIEw.setTokenizer
(new MultiAutoCompleteTextVIEw.CommaTokenizer());
}
}
范例說明android裡的AnalogClock Widget是一個時鐘對象,本范例將配置一個小時鐘,並在其下放置一個TextView,為了做對照,上面放置的為模擬時鐘,下面的TextVIEw則模擬電子時鐘,將AnalogClock的時間以數字鐘形式顯示。
本范例的重點,在在android.os.Handler、Java.lang.Thread以及android.os.Message三對象的整合應用,通過產生Thread對象,在進程內同步調用System.currentTimeMillis() 取得系統時間,並通過Message對象來通知Handler對象,Handler則扮演聯系Activity與Thread之間的橋梁,在收到Message對象後,將時間變量的值,顯示於TextVIEw當中,產生數字時鐘的外觀與功能。
運行結果
▲圖4-14 程序啟動後,除了AnalogClock會顯示目前系統時間外,下方會顯示數字鐘
范例程序src/irdc.ex04_14/EX04_14.java主程序需要另外加載Java的Calendar與Thread對象,在onCreate() 中構造Handler與Thread兩對象,並實現handelMessage() 與run() 兩個方法,如下所述:
package irdc.EX04_14;
import android.app.Activity;
import android.os.Bundle;
/*這裡我們需要使用Handler類與Message類來處理進程*/
import android.os.Handler;
import android.os.Message;
import android.widget.AnalogClock;
import android.widget.TextVIEw;
/*需要使用Java的Calendar與Thread類來取得系統時間*/
import Java.util.Calendar;
import Java.lang.Thread;
public class EX04_14 extends Activity
{
/*聲明一常數作為判別信息用*/
protected static final int GUINOTIFIER = 0x1234;
/*聲明兩個widget對象變量*/
private TextView mTextVIEw;
public AnalogClock mAnalogClock;
/*聲明與時間相關的變量*/
public Calendar mCalendar;
public int mMinutes;
public int mHour;
/*聲明關鍵Handler與Thread變量*/
public Handler mHandler;
private Thread mClockThread;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.main);
/*通過findVIEwById取得兩個widget對象*/
mTextView=(TextView)findViewById(R.id.myTextVIEw);
mAnalogClock=(AnalogClock)findVIEwById(R.id.myAnalogClock);
/*通過Handler來接收進程所傳遞的信息並更新TextVIEw*/
mHandler = new Handler()
{
public void handleMessage(Message msg)
{
/*這裡是處理信息的方法*/
switch (msg.what)
{
case EX04_14.GUINOTIFIER:
/* 在這處理要TextVIEw對象Show時間的事件 */
mTextVIEw.setText(mHour+" : "+mMinutes);
break;
}
super.handleMessage(msg);
}
};
/*通過進程來持續取得系統時間*/
mClockThread=new LooperThread();
mClockThread.start();
}
/*改寫一個Thread Class用來持續取得系統時間*/
class LooperThread extends Thread
{
public void run()
{
super.run();
try
{
do
{
/*取得系統時間*/
long time = System.currentTimeMillis();
/*通過Calendar對象來取得小時與分鐘*/
final Calendar mCalendar = Calendar.getInstance();
mCalendar.setTimeInMillis(time);
mHour = mCalendar.get(Calendar.HOUR);
mMinutes = mCalendar.get(Calendar.MINUTE);
/*讓進程休息一秒*/
Thread.sleep(1000);
/*重要關鍵程序:取得時間後發出信息給Handler*/
Message m = new Message();
m.what = EX04_14.GUINOTIFIER;
EX04_14.this.mHandler.sendMessage(m);
}while(EX04_14.LooperThread.interrupted()==false);
/*當系統發出中斷信息時停止本循環*/
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
擴展學習其實要達到本范例效果的代碼應該只有兩行,也就是將筆者對於TextVIEw與進程Thread的處理,改為使用widget.DigitalClock的方式,寫法如下:
import android.widget.AnalogClock
mDigitalClock =(DigitalClock)findVIEwById(R.id.myDigitalClock);
而本程序使用TextVIEw來模擬DigitalClock的做法,實際上,也是參考AnalogClock與DigitalClock 這兩個widget的程序代碼所做的練習,對於將來實現Timer相關的小對象,會有所幫助。
android提供了System.currentTimeMillis()、uptimeMillis()、elapsedRealtime()這三種不同特性的System Clock給開發者使用。本范例使用System.currentTimeMillis() 就是標准的Clock用法,需要搭配真實的日期與時間使用,另外兩者則是適用於interval與elapse time來控制程序與UI之用,讀者可以自己練習看看。
范例說明許多的網絡服務,例如網絡訂票、網絡訂房、網絡訂旅游行程、或在注冊會員輸入基本數據時,都會需要用戶輸入日期與時間格式的數據,有些網站會提供貼心的小功能:直接由萬年歷上來選擇日期與時間,選擇完畢,就會自動將日期與時間帶入需要填寫的字段中。
Android有沒有提供類似的組件可以實現這樣的功能呢?答案是肯定的!在這個范例中,將示范以android API中提供的DatePicker與TimePicker兩種對象來實現動態輸入日期與時間的功能。
范例中使用了DatePicker、TimePicker與TextView三種對象,以TextView來顯示日期與時間,默認帶入目前系統的日期與時間,DatePicker與TimePicker可讓用戶動態調整日期與時間,當用戶調整了DatePicker的日期或TimePicker時間時,則TextVIEw中所顯示的日期與時間亦會跟著改變。
運行結果
▲圖4-15 由手機屏幕上動態輸入日期與時間
范例程序src/irdc.ex04_15/EX04_15.java程序中以updateDisplay() 這個方法來設置TextVIEw中所顯示的日期時間,以Java.util.Calendar對象來取得目前的系統時間,並預先帶入TextVIEw中。
當用戶更改了DatePicker裡的年、月、日時,將觸發DatePicker的onDateChange() 事件,運行updateDisplay() 來重新設置TextView中顯示的日期;同樣的原理,當用戶更改了TimePicker裡的時間,會觸發TimePicker的onTimeChange() 事件,運行updateDisplay() 來重新設置TextVIEw中顯示的時間。
package irdc.ex04_15;
/* import相關class */
import Java.util.Calendar;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextVIEw;
import android.widget.DatePicker;
import android.widget.TimePicker;
public class EX04_15 extends Activity
{
/*聲明日期及時間變量*/
private int mYear;
private int mMonth;
private int mDay;
private int mHour;
private int mMinute;
/*聲明對象變量*/
TextVIEw tv;
TimePicker tp;
DatePicker dp;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
/*取得目前日期與時間*/
Calendar c=Calendar.getInstance();
mYear=c.get(Calendar.YEAR);
mMonth=c.get(Calendar.MONTH);
mDay=c.get(Calendar.DAY_OF_MONTH);
mHour=c.get(Calendar.HOUR_OF_DAY);
mMinute=c.get(Calendar.MINUTE);
super.onCreate(savedInstanceState);
/* 載入main.XML Layout */
setContentVIEw(R.layout.main);
/*取得TextVIEw對象,並調用updateDisplay()
來設置顯示的初始日期時間*/
tv= (TextView) findVIEwById(R.id.showTime);
updateDisplay();
/*取得DatePicker對象,以init()
設置初始值與onDateChangeListener() */
dp=(DatePicker)findVIEwById(R.id.dPicker);
dp.init(mYear,mMonth,mDay,new DatePicker.OnDateChangedListener()
{
@Override
public void onDateChanged(DatePicker vIEw,int year,
int monthOfYear,int dayOfMonth)
{
mYear=year;
mMonth= monthOfYear;
mDay=dayOfMonth;
/*調用updateDisplay()來改變顯示日期*/
updateDisplay();
}
});
/*取得TimePicker對象,並設置為24小時制顯示*/
tp=(TimePicker)findVIEwById(R.id.tPicker);
tp.setIs24HourVIEw(true);
/*setOnTimeChangedListener,並重寫onTimeChanged event*/
tp.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener()
{
@Override
public void onTimeChanged(TimePicker vIEw,
int hourOfDay,
int minute)
{
mHour=hourOfDay;
mMinute=minute;
/*調用updateDisplay()來改變顯示時間*/
updateDisplay();
}
});
}
/*設置顯示日期時間的方法*/
private void updateDisplay()
{
tv.setText(
new StringBuilder().append(mYear).append("/")
.append(format(mMonth + 1)).append("/")
.append(format(mDay)).append(" ")
.append(format(mHour)).append(":")
.append(format(mMinute))
);
}
/*日期時間顯示兩位數的方法*/
private String format(int x)
{
String s=""+x;
if(s.length()==1) s="0"+s;
return s;
}
}
擴展學習本范例的重點在於學習如何使用DatePicker與TimePicker對象來達成動態調整日期與時間的功能,眼尖的讀者應該發現,在范例中,DatePicker實現OnDateChangedListener() 的方法與TimePicker實現OnTimeChangedListener() 的方法是不太相同的。DatePicker對象以init() 這個方法來指定DatePicker初始的年、月、日及OnDateChangedListener() 的事件;而TimePicker對象則是直接以setOnTimeChangedListener() 事件來處理時間改變時程序要做的操作。
在舊版的android SDK(1.0r2版以前的SDK版本)中,DatePicker對象有提供setOnDateChangedListener() 這個方法,但是在新版的SDK(1.0r2),這個方法被刪除了,所以要實現OnDateChangedListener() 時,必須以init() 方式來重寫OnDateChangedListener();而TimePicker則直接以 setOnTimeChangedListener() 來實現即可。
android API另外提供了其它的對象來實現動態修改日期時間的功能:DatePickerDialog與TimePickerDialog。這兩種類型的對象最大的差別在於DatePicker與TimePicker是直接顯示在屏幕畫面上,而DatePickerDialog與TimePickerDialog對象則是以跳出Dialog的方式來顯示,如下圖所示。
▲圖4-16 DatePickerDialog與TimePickerDialog
DatePickerDialog與TimePickerDialog的實現方式又為何?以下提供簡單的范例供各位參考:
/* 取得更改日期的Button,添加onClickListener */
Button dButton=(Button)findVIEwById(R.id.dPicker);
dButton.setOnClickListener(new VIEw.OnClickListener()
{
public void onClick(VIEw v)
{
/* onClick時跳出DatePickerDialog */
new DatePickerDialog(EX04_15_1.this,
new DatePickerDialog.OnDateSetListener()
{
public void onDateSet(DatePicker vIEw,int year,
int monthOfYear,int dayOfMonth)
{
/* 這裡放更新日期的方法 */
}
},mYear,mMonth,mDay).show();
}
});
/* 取得更改時間的Button,添加onClickListener */
Button tButton=(Button)findVIEwById(R.id.tPicker);
tButton.setOnClickListener(new VIEw.OnClickListener()
{
public void onClick(VIEw v)
{
/* onClick時跳出TimePickerDialog */
new TimePickerDialog(EX04_15_1.this,
new TimePickerDialog.OnTimeSetListener()
{
public void onTimeSet(TimePicker vIEw,int hourOfDay,
int minute)
{
/* 這裡放更新時間的方法 */
}
},mHour,mMinute,true).show();
}
});
不論是DatePicker、TimePicker,或DatePickerDialog、TimePickerDialog,都可以實現動態更改日期時間的功能,要用哪一種方式來實現,端視各位的應用程序需要啰!
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.Net/lewutian/archive/2009/08/20/4467662.ASPx
兩位Google開發者演示了Android 3.0——該開源移動操作系統的首個支持平板設備的版本。Android 3.0也被稱為蜂巢(Honeycomb),這也是第一個
對於Android 3.x honeycomb系統來說屏幕的兼容性很重要,這裡目前我們就主流的Android 1.5~2.3.4的軟件如何兼容android 3.0有關
在Android 3.0中除了我們重點講解的Fragment外,Action Bar也是一個重要的內容,Action Bar主要是用於代替傳統的標題欄,對於androi
Android ANR這個錯誤大家並不陌生,但是從Android 2.2開始出錯的ANR信息會自動上傳給Google進行系統分析改進,當然了你的應用ANR錯誤其實保存在