編輯:中級開發
擴展學習在擴展學習裡,請加上兩個Button在其中,一個為回答,另一個為清除RadioButton的選擇狀態。程序有隨機設置的答案選項,當User點擊回答按鈕時,比較答案是否正確,若正確,則以AlertDialog對話窗口顯示答案結果。
answerButton.setOnClickListener(new Button.OnClickListener()
{
public void onClick(VIEw v)
{
new AlertDialog.Builder(TEST_56.this)
.setIcon(R.drawable.icon)
.setTitle(R.string.about_dialog_title)
.setPositiveButton(R.string.about_dialog_ok, null)
.setMessage(R.string.about_dialog_thanks)
.create();
{
}
}).show();
}
在清除Button.onClickListener的事件處理中,只需將被選擇的RadioButton取消掉,回到等待回答的狀態。
mRadioGroup1.clearCheck();
范例說明在設計此范例之前,必須先准備三張圖片(兩張外框圖、一張內框圖),將這三張圖片放在res/drawable下面,在此使用的圖片為PNG圖形文件,而圖案大小最好是調整成手機屏幕大小,或者依據手機的分辨率,動態調整ImageView的大小。稍後的范例將介紹如何調整ImageVIEw的大小,這裡就不贅述了。
准備好之後,開始做這個酷炫的專業相框應用程序,在Layout當中創建了兩個ImageVIEw,且以絕對坐標的方式“堆棧”在一起,在其下方放上兩個按鈕(Button),按鈕的目的是為了要用來切換圖片,創建完成後,要在Button事件裡處理置換圖片的動作。
程序目的為點擊Button1,ImageView1會出現right的圖片,點擊Button2,ImageView1會出現left的圖片,而ImageVIEw2皆為固定不動(文件名叫oa),這個范例並不難,很快就會知道葫蘆裡賣的是什麼藥了,先來看看范例運行結果。
運行結果
▲圖4-7 點擊按鈕後,會更換ImageVIEw(外框)圖片
范例程序src/irdc.ex04_07/EX04_07.Java此程序的關鍵地方在於getResources() 這個方法,這個方法負責訪問Resource ID,無論是訪問資源裡的圖文件、文字都要用到getResources();在此使用getResources().getDrawable() 來載入res/drawable裡的圖文件,並將圖片放置在ImageVIEw當中。
package irdc.ex04_07;
import android.app.Activity;
import android.os.Bundle;
import android.view.VIEw;
import android.widget.Button;
import android.widget.ImageVIEw;
public class EX04_07 extends Activity
{
/*聲明 Button、ImageVIEw對象*/
private ImageView mImageVIEw01;
private ImageView mImageVIEw02;
private Button mButton01;
private Button mButton02;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.main);
/*取得 Button、ImageVIEw對象*/
mImageView01 = (ImageView)findViewById(R.id.myImageVIEw1);
mImageView02 = (ImageView)findViewById(R.id.myImageVIEw2);
mButton01 = (Button) findVIEwById(R.id.myButton1);
mButton02 = (Button) findVIEwById(R.id.myButton2);
/*設置ImageVIEw背景圖*/
mImageVIEw01.setImageDrawable(getResources().
getDrawable(R.drawable.right));
mImageVIEw02.setImageDrawable(getResources().
getDrawable(R.drawable.oa));
/*用OnClickListener事件來啟動*/
mButton01.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(VIEw v)
{
/*當啟動後,ImageVIEw立刻換背景圖*/
mImageVIEw01.setImageDrawable(getResources().
getDrawable(R.drawable.right));
}
});
mButton02.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(VIEw v)
{
mImageVIEw01.setImageDrawable(getResources().
getDrawable(R.drawable.left));
}
});
}
}
res/layout/main.XML創建兩個ImageVIEw,一個為外框、另一個為內框,需注意的是,圖片需要做一個排序堆棧順序,將前景圖放在上方(以AbsoluteLayout),將背景圖放在前景圖的下方,這是最簡單的堆棧順序方法。
<?XML version="1.0" encoding="utf-8"?>
<AbsoluteLayout
android:id="@+id/widget34"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
XMLns:android="http://schemas.android.com/apk/res/android"
>
<!--創建第一個ImageVIEw (第二層圖片)-->
<ImageVIEw
android:id="@+id/myImageVIEw1"
android:layout_width="320px"
android:layout_height="280px"
android:layout_x="0px"
android:layout_y="36px"
/>
<!--創建第二個ImageVIEw (第一層圖片)-->
<ImageVIEw
android:id="@+id/myImageVIEw2"
android:layout_width="104px"
android:layout_height="157px"
android:layout_x="101px"
android:layout_y="119px"
/>
<!--創建第一個Button -->
<Button
android:id="@+id/myButton1"
android:layout_width="105px"
android:layout_height="66px"
android:text="pic1"
android:layout_x="9px"
android:layout_y="356px"
/>
<!--創建第二個Button -->
<Button
android:id="@+id/myButton2"
android:layout_width="105px"
android:layout_height="66px"
android:text="pic2"
android:layout_x="179px"
android:layout_y="356px"
/>
</AbsoluteLayout>
延伸學習學會ImageVIEw之後,在延伸學習裡,便可試著將兩個ImageButton Widget堆棧在一起,如此一來,不但有背景圖,還有按鈕事件。
<ImageButton
android:id="@+id/myImageButton1"
android:state_focused="true"
android:layout_width="320px"
android:layout_height="280px"
android:layout_x="0px"
android:layout_y="36px"
/>
接著,你就可以自由發揮了。ImageButton的使用方法已經介紹過,而堆棧的技巧可參考這個范例程序,比較不同的地方就是只要點擊圖片,即可直接做換圖的動作,不需要再點擊面的Button做更換,需要注意的是圖片大小要作調整,不然可能會與ImageButton不合喔!
范例說明Spinner就是下拉菜單,也等於swing的combo box、Html的 <select>,由於手機畫面有限,要在有限的范圍選擇項目,下拉菜單是唯一、也是較好的選擇。
android提供的Spinner Widget的下拉菜單已經非常好用了,樣式也還適用。但本范例的示范重點在於自定義下拉菜單裡的樣式,其關鍵在於調用setDropDownVIEwResource方法,以XML的方式定義下拉菜單要顯示的模樣。本范例除了自定義下拉菜單,還用程序設計了一段動畫,當User以觸控的方式點擊這個自定義的Spinner時,會以一段動畫提示User。
運行結果
▲圖4-8 自定義Spinner的下拉菜單模式,具有圓角的效果
范例程序src/irdc.ex04_08/EX04_08.Java在new ArrayAdapter中,我們使用ArrayAdapter(Context context, int textViewResourceId, T[] objects) 這個Constructor,textVIEwResourceId使用android提供的ResourceID,objects為必須傳遞的字符串數組(String Array)。
Adapter的setDropDownVIEwResource可以設置下拉菜單的顯示方式,將該XML定義在res/layout目錄下面,可針對下拉菜單中的TextView進行設置,如同本程序裡的R.layout.myspinner_dropdown即為自定義的下拉菜單TextVIEw樣式。除了改變下拉菜單樣式外,也對Spinner做了一點動態效果,點擊Spinner時,晃動Spinner再出現下拉菜單(myAnimation)。
package irdc.ex04_08;
import android.app.Activity;
import android.os.Bundle;
import android.vIEw.MotionEvent;
import android.view.VIEw;
import android.vIEw.animation.Animation;
import android.vIEw.animation.AnimationUtils;
import android.widget.AdapterVIEw;
import android.widget.ArrayAdapter;
import android.widget.TextVIEw;
import android.widget.ListVIEw;
import android.widget.Spinner;
public class EX04_08 extends Activity
{
private static final String[] countrIEsStr =
{ "北京市", "上海市", "天津市", "重慶市" };
private TextView myTextVIEw;
private Spinner mySpinner;
private ArrayAdapter<String> adapter;
Animation myAnimation;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* 載入main.XML Layout */
setContentVIEw(R.layout.main);
/* 以findVIEwById()取得對象 */
myTextView = (TextView) findViewById(R.id.myTextVIEw);
mySpinner = (Spinner) findVIEwById(R.id.mySpinner);
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, countrIEsStr);
/* myspinner_dropdown為自定義下拉菜單樣式定義在res/layout目錄下 */
adapter.setDropDownVIEwResource(R.layout.myspinner_dropdown);
/* 將ArrayAdapter添加Spinner對象中 */
mySpinner.setAdapter(adapter);
/* 將mySpinner添加OnItemSelectedListener */
mySpinner.setOnItemSelectedListener
(new Spinner.OnItemSelectedListener()
{
@Override
public void onItemSelected
(AdapterView<?> arg0, VIEw arg1, int arg2,
long arg3)
{
/* 將所選mySpinner的值帶入myTextVIEw中 */
myTextView.setText("選擇的是" + countrIEsStr[arg2]);
/* 將mySpinner顯示 */
arg0.setVisibility(VIEw.VISIBLE);
}
@Override
public void onNothingSelected(AdapterVIEw<?> arg0)
{
// TODO Auto-generated method stub
}
});
/* 取得Animation定義在res/anim目錄下 */
myAnimation = AnimationUtils.loadAnimation(this, R.anim.my_anim);
/* 將mySpinner添加OnTouchListener */
mySpinner.setOnTouchListener(new Spinner.OnTouchListener()
{
@Override
public boolean onTouch(VIEw v, MotionEvent event)
{
/* 將mySpinner運行Animation */
v.startAnimation(myAnimation);
/* 將mySpinner隱藏 */
v.setVisibility(VIEw.INVISIBLE);
return false;
}
});
mySpinner.setOnFocusChangeListener(new Spinner.OnFocusChangeListener()
{
@Override
public void onFocusChange(VIEw v, boolean hasFocus)
{
// TODO Auto-generated method stub
}
});
}
}
res/layout/myspinner_dropdown.xml改變下拉菜單樣子的XML,裡面所使用的組件為TextVIEw。
<?XML version="1.0" encoding="utf-8"?>
<TextVIEw
XMLns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="24sp"
android:singleLine="true"
style="?android:attr/spinnerDropDownItemStyle" />
res/anim/my_anim.XMLandroid的動畫(animation)由四種類型(type)所組成:alpha、scale、translate,以及rotate,以下的自定義動畫將使用當中的兩種。
<?XML version="1.0" encoding="utf-8"?>
<set
XMLns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:toXDelta="-100%p"
android:duration="300"
>
</translate>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="300">
</alpha>
</set>
擴展學習Animation主要有兩種動態方式,一種是tweened animation(漸變動畫),另一種是frame by frame animation(畫面轉換動畫)。tweened animation則有以下四種基本轉換方式:
l AlphaAnimation (transparency changes):透明度轉換
l RotateAnimation (rotations):旋轉轉換
l ScaleAnimation (growing or shrinking):縮放轉換
l TranslateAnimation (position changes):位置轉換
定義好你想要的動畫XML後,用AnimationUtils.loadAnimation將動畫加載,在想要加上動態效果的組件中使用startAnimation方法。
范例說明前面的范例對Spinner的自定義菜單、交互事件已大致掌握了設計方法,但在android的Spinner裡的元素,若要動態增減Spinner下拉菜單的選項,就必須利用ArrayList的依賴性來完成。
以下范例將設計一個EditText,當User輸入了新的文字,在點擊“添加”按鈕的同時,就會將輸入的值添加Spinner(至下拉菜單的最後一項),接著Spinner會停留在剛添加好的選項上;當點擊“刪除”按鈕,則刪除選擇的Spinner選項,常應用於未知Spinner選項數量的To-Do List、或添加維護市縣數據等等。
運行結果
▲圖4-9 隨User的輸入文字,可動態添加/刪除的Spinner菜單
范例程序src/irdc.ex04_09/EX04_09.JavaSpinner添加了OnItemSelectedListener事件,當點擊下拉菜單後,將值帶到上方的TextVIEw。上一個范例在new adapter時傳入String數組,這次因為要添加及刪除adapter,所以要傳入的是ArrayList,否則,在添加刪除時會出現錯誤。
package irdc.ex04_09;
import android.app.Activity;
import android.os.Bundle;
import android.view.VIEw;
import android.widget.AdapterVIEw;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextVIEw;
import Java.util.ArrayList;
import Java.util.List;
public class EX04_09 extends Activity
{
private static final String[] countrIEsStr =
{ "北京市", "上海市", "天津市", "重慶市" };
private TextView myTextVIEw;
private EditText myEditText;
private Button myButton_add;
private Button myButton_remove;
private Spinner mySpinner;
private ArrayAdapter<String> adapter;
private List<String> allCountrIEs;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* 載入main.XML Layout */
setContentVIEw(R.layout.main);
allCountrIEs = new ArrayList<String>();
for (int i = 0; i < countrIEsStr.length; i++)
{
allCountries.add(countrIEsStr);
}
/* new ArrayAdapter對象並將allCountrIEs傳入 */
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, allCountrIEs);
adapter
.setDropDownVIEwResource
(android.R.layout.simple_spinner_dropdown_item);
/* 以findVIEwById()取得對象 */
myTextView = (TextView) findViewById(R.id.myTextVIEw);
myEditText = (EditText) findVIEwById(R.id.myEditText);
myButton_add = (Button) findVIEwById(R.id.myButton_add);
myButton_remove = (Button) findVIEwById(R.id.myButton_remove);
mySpinner = (Spinner) findVIEwById(R.id.mySpinner);
/* 將ArrayAdapter添加Spinner對象中 */
mySpinner.setAdapter(adapter);
/* 將myButton_add添加OnClickListener */
myButton_add.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(VIEw arg0)
{
String newCountry = myEditText.getText().toString();
/* 先比較添加的值是否已存在,不存在才可添加 */
for (int i = 0; i < adapter.getCount(); i++)
{
if (newCountry.equals(adapter.getItem(i)))
{
return;
}
}
if (!newCountry.equals(""))
{
/* 將值添加至adapter */
adapter.add(newCountry);
/* 取得添加的值的位置 */
int position = adapter.getPosition(newCountry);
/* 將Spinner選擇在添加的值的位置 */
mySpinner.setSelection(position);
/* 將myEditText清空 */
myEditText.setText("");
}
}
});
/* 將myButton_remove添加OnClickListener */
myButton_remove.setOnClickListener(new Button.OnClickListener()
{
@Override
public void onClick(VIEw arg0)
{
if (mySpinner.getSelectedItem() != null)
{
/* 刪除mySpinner的值 */
adapter.remove(mySpinner.getSelectedItem().toString());
/* 將myEditText清空 */
myEditText.setText("");
if (adapter.getCount() == 0)
{
/* 將myTextVIEw清空 */
myTextVIEw.setText("");
}
}
}
});
/* 將mySpinner添加OnItemSelectedListener */
mySpinner.setOnItemSelectedListener
(new Spinner.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> arg0, VIEw arg1, int arg2,
long arg3)
{
/* 將所選mySpinner的值帶入myTextVIEw中 */
myTextVIEw.setText(arg0.getSelectedItem().toString());
}
@Override
public void onNothingSelected(AdapterVIEw<?> arg0)
{
}
});
}
}
擴展學習setDropDownViewResource主要是設置User點擊Spinner後出現的下拉菜單樣式,除了前一個范例使用自設方式改變TextVIEw內容之外,android亦提供兩種基本的樣式:
l android.R.layout.simple_spinner_item:TextVIEw的下拉菜單。
l android.R.layout.simple_spinner_dropdown_item:除了有TextVIEw,右邊有radio的下拉菜單。
查看android 源代碼中的simple_spinner_dropdown_item.XML,內容如下:
<?XML version="1.0" encoding="utf-8"?>
<TextVIEw
XMLns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:singleLine="true"
style="?android:attr/spinnerDropDownItemStyle"
/>
以下為自定義修改後,適用於spinner的Layout:
<?XML version="1.0" encoding="utf-8"?>
<TextVIEw
XMLns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="fill_parent"
android:layout_height="12sp"
android:singleLine="true"
style="?android:attr/spinnerDropDownItemStyle"
android:textSize="10sp"
/>
范例說明還記得在第三章“簡單的Gallery相片畫廊”范例,為了簡化問題,使用了android默認的Icon作為Gallery顯示的內容嗎?現在,將數張PNG圖片導入Drawable當中,並於onCreate的同時,載入於Gallery Widget中,試著再添加一個OnItemClick的事件,以取得圖片的ID編號來響應用戶點擊圖片時的狀態,完成Gallery的高級使用。本范例的另一個重點,就是如何設置Gallery圖片的寬高以及放置圖片Layout的大小,在此我們改寫一個繼承自BaseAdapter的ImageAdapter容器來存放圖片,通過ImageVIEw.setScaleType() 的方法來改變圖片的顯示,再通過setLayoutParams() 方法來改變Layout的寬高。
運行結果
▲圖4-10 程序啟動後會顯示res/drawable中的圖片,點擊任一圖片會Toast該圖片的編號
范例程序src/irdc.ex04_10/EX04_10.Java主程序有兩大重點,第一、是ImageAdapter繼承BaseAdapter class的未實現方法的重寫構造,第二、則是Gallery的OnItemClick() 方法與圖片及Layout寬高設置。
package irdc.EX04_10;
import android.app.Activity;
import android.os.Bundle;
/* 本范例需使用到的class */
import android.content.Context;
import android.content.res.TypedArray;
import android.view.VIEw;
import android.view.VIEwGroup;
import android.widget.AdapterVIEw;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageVIEw;
import android.widget.Toast;
import android.widget.AdapterVIEw.OnItemClickListener;
public class EX04_10 extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentVIEw(R.layout.main);
/*通過findVIEwById取得*/
Gallery g = (Gallery) findVIEwById(R.id.mygallery);
/* 添加一ImageAdapter並設置給Gallery對象 */
g.setAdapter(new ImageAdapter(this));
/* 設置一個itemclickListener並Toast被點擊圖片的位置 */
g.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick
(AdapterView<?> parent, VIEw v, int position, long id)
{
Toast.makeText
(EX04_10.this, getString(R.string.my_gallery_text_pre)
+ position+ getString(R.string.my_gallery_text_post),
Toast.LENGTH_SHORT).show();
}
});
}
/* 改寫BaseAdapter自定義一ImageAdapter class */
public class ImageAdapter extends BaseAdapter
{
/*聲明變量*/
int mGalleryItemBackground;
private Context mContext;
/*ImageAdapter的構造器*/
public ImageAdapter(Context c)
{
mContext = c;
/* 使用在res/values/attrs.XML中的<declare-styleable>定義
* 的Gallery屬性.*/
TypedArray a = obtainStyledAttributes(R.styleable.Gallery);
/*取得Gallery屬性的Index id*/
mGalleryItemBackground = a.getResourceId
(R.styleable.Gallery_android_galleryItemBackground, 0);
/*讓對象的styleable屬性能夠反復使用*/
a.recycle();
}
/* 重寫的方法getCount,返回圖片數目 */
public int getCount()
{
return myImageIds.length;
}
/* 重寫的方法getItemId,返回圖像的數組id */
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
/* 重寫的方法getView,返回一VIEw對象 */
public View getVIEw
(int position, View convertView, VIEwGroup parent)
{
/*產生ImageVIEw對象*/
ImageView i = new ImageVIEw(mContext);
/*設置圖片給imageVIEw對象*/
i.setImageResource(myImageIds[position]);
/*重新設置圖片的寬高*/
i.setScaleType(ImageVIEw.ScaleType.FIT_XY);
/*重新設置Layout的寬高*/
i.setLayoutParams(new Gallery.LayoutParams(136, 88));
/*設置Gallery背景圖*/
i.setBackgroundResource(mGalleryItemBackground);
/*返回imageVIEw對象*/
return i;
}
/*構建一Integer array並取得預加載Drawable的圖片id*/
private Integer[] myImageIds =
{
R.drawable.photo1,
R.drawable.photo2,
R.drawable.photo3,
R.drawable.photo4,
R.drawable.photo5,
R.drawable.photo6,
};
}
}
res/values/attrs.xml定義layout外部resource的XML文件,用來改變layout的背景圖。
<?XML version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Gallery">
<attr name="android:galleryItemBackground" />
</declare-styleable>
</resources>
擴展學習在android:ScaleType中定義了下列常數可供使用,通過“ObjectVIEw.ScaleType常數名稱”的方式,就可以改變圖片的顯示方式。
常數名稱
值
Matrix
0
fitXY
1
fitStart
2
fitCenter
3
fitEnd
4
center
5
centerCrop
6
centerInside
7
另外,在主程序中,我們使用了下面這一段寫法:
TypedArray a = obtainStyledAttributes(R.styleable.Gallery);
這是一個引用自制layout元素的用法,必須在res/values下面添加一個attrs.XML,並在其中定義 <declare-styleable> 標簽TAG,目的是自定義layout的背景風格,並且通過TypeArray的特性,讓相同的Layout元素可以重復用於每一張圖片。
范例說明大家都應該用過操作系統中的文件搜索功能吧!它可以快速幫我們找到想要的文件。如果要在手機制作一個文件搜索的功能,又該如何實現呢?其實這個功能並不困難,Java I/O的API中提供了Java.io.File對象,只要利用File對象的方法,再搭配android的EditText、TextVIEw等對象,就可以輕松做出一個手機的文件搜索引擎。
本范例中使用EditText、Button與TextView三種對象來實現此功能,用戶將要搜索的文件名稱或關鍵字輸入EditText中,點擊Button後,程序會在根目錄中尋找符合的文件,並將搜索結果顯示於TextVIEw中;如果找不到符合的文件,則顯示找不到文件。
簡介: 對於需要跨應用程序執行期間或生命期而維護重要信息的應用程序來說,能夠在移動設備上本地存儲數據是一種非常關鍵的功能。作為一名開發人員,您經常需要存儲諸如
<?XML version=1.0 encoding=utf-8?> 然後是主布局,一個水平滾動條,放入menu
簡介: 學習如何使用混合應用程序編程模型為 WebSphere® Commerce 構建移動應用程序。本文描述混合模型,它與其他移動應用程序編程模型的
對於Android 3.x honeycomb系統來說屏幕的兼容性很重要,這裡目前我們就主流的Android 1.5~2.3.4的軟件如何兼容android 3.0有關