最近我在學(xué)習(xí)安卓,有些人肯定覺得我瘋了,但是我覺得作為一個從java web轉(zhuǎn)作前端的人,如果沒有好好搞一下安卓確實說不過去曼验,而且前端和安卓的定位也是一樣的嘛,都是構(gòu)建用戶頁面和處理交互的粘姜,所以今天就帶大家走進(jìn)安卓的世界鬓照。
1 ListView
在布局文件中加入一個ListView控件。
<?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="
http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
android:layout_height="fill_parent"> <!-- 添加一個ListView控件 --> <ListView
android:id="@+id/lv" android:layout_width="fill_parent" android:layout_height="fill_parent"/>
</LinearLayout>
然后在Activity中初始化
public class listView extends Activity{
private static final String[] str = new String[] {
"first", "second", "third", "fourth", "fifth"
};//定義一個String數(shù)組用來顯示ListView的內(nèi)容private ListView lv;/** Called
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv = (ListView) findViewById(R.id.lv);//得到ListView對象的引用 /*為ListView設(shè)置Adapter來綁定數(shù)據(jù)*/
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, strs));
}
}
提供一下代碼 給大家選擇
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_checked, strs));
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_multiple_choice, strs));
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
在前面講到過孤紧,ListView的職責(zé)除了填充數(shù)據(jù)外豺裆,還要處理用戶的操作。通過如下的代碼就可以為ListView綁定一個點擊監(jiān)聽器号显,點擊后在標(biāo)題欄顯示點擊的行數(shù)臭猜。
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
//點擊后在標(biāo)題上顯示點擊了第幾行
setTitle("你點擊了第"+arg2+"行");
}
});
很多時候需要在列表中展示一些除了文字以外的東西,比如圖片等押蚤。這時候可以使用SimpleAdapter蔑歌。SimpleAdapter的使用也非常簡單,同時它的功能也非常強大揽碘〈瓮溃可以通過它自定義ListView中的item的內(nèi)容,比如圖片钾菊、多選框等帅矗≠怂啵看一個例子煞烫,實現(xiàn)一個每一行都有一個ImageView和TextView的ListView。
<?xmlversion="1.0"encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent" android:layout_width="fill_parent">
<ImageViewandroid:layout_alignParentRight="true" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/ItemImage"/>
<TextViewandroid:id="@+id/ItemTitle" android:layout_height="wrap_content"
android:layout_width="fill_parent" android:textSize="20sp"/>
<TextViewandroid:id="@+id/ItemText" android:layout_height="wrap_content"
android:layout_width="fill_parent" android:layout_below="@+id/ItemTitle"/> </RelativeLayout>
配置完畢累颂,就可以在Java代碼中為ListView綁定數(shù)據(jù)滞详。
publicclass MyListViewSimple extends Activity {
private ListView lv;
@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv = (ListView) findViewById(R.id.lv);
/*定義一個動態(tài)數(shù)組*/
ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String,Object>>();/*在數(shù)組中存放數(shù)據(jù)*/
for(int i=0;i<10;i++)
{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("ItemImage", R.drawable.icon);//加入圖片 map.put("ItemTitle", "第"+i+"行");
map.put("ItemText", "這是第"+i+"行");
listItem.add(map);
}
SimpleAdapter mSimpleAdapter = new SimpleAdapter(this,listItem,//需要綁定的數(shù)據(jù)
R.layout.item,//每一行的布局//動態(tài)數(shù)組中的數(shù)據(jù)源的鍵對應(yīng)到定義布局的View中new String[] {"ItemImage"
,"ItemTitle", "ItemText"},
newint[] {R.id.ItemImage,R.id.ItemTitle,R.id.ItemText}
);
lv.setAdapter(mSimpleAdapter);
lv.setOnItemClickListener(new
OnItemClickListener() {
@Override
publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
setTitle("你點擊了第"+arg2+"行");//設(shè)置標(biāo)題欄顯示點擊的行
}
});
}
}
當(dāng)系統(tǒng)開始繪制ListView的時候凛俱,首先調(diào)用getCount()方法。得到它的返回值料饥,即ListView的長度蒲犬。然后系統(tǒng)調(diào)用getView()方法,根據(jù)這個長度逐一繪制ListView的每一行岸啡。也就是說原叮,如果讓getCount()返回1,那么只顯示一行巡蘸。而getItem()和getItemId()則在需要處理和取得Adapter中的數(shù)據(jù)時調(diào)用奋隶。那么getView如何使用呢?如果有10000行數(shù)據(jù)悦荒,就繪制10000次唯欣?這肯定會極大的消耗資源,導(dǎo)致ListView滑動非常的慢搬味,那應(yīng)該怎么做呢境氢?通過一個例子來講解如何在使用BaseAdapter的時候優(yōu)化ListView的顯示。例子中將上一節(jié)中的ImageView換成Button碰纬,并且處理Button的點擊事件萍聊,其中對ListView的顯示做了優(yōu)化。
publicclass MyListViewBase extends Activity {
private ListView lv;
ArrayList<HashMap<String, Object>>listItem;
@Override
publicvoid onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv = (ListView) findViewById(R.id.lv);
MyAdapter mAdapter = new MyAdapter(this);
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
Log.v("MyListViewBase", "你點擊了ListView條目" + arg2);//在LogCat中輸出信息
}
});
}
private ArrayList<HashMap<String, Object>> getDate(){
ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();
for(int i=0;i<30;i++)
{
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("ItemTitle", "第"+i+"行");
map.put("ItemText", "這是第"+i+"行");
listItem.add(map);
}
return listItem;
}
private class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public MyAdapter(Context context) {
this.mInflater = LayoutInflater.from(context);
}
public View getView(finalint position, View convertView, ViewGroup parent) {
ViewHolder holder;
Log.v("MyListViewBase", "getView " + position + " " + convertView);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item,null);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.ItemTitle);
holder.text = (TextView) convertView.findViewById(R.id.ItemText);
holder.bt = (Button) convertView.findViewById(R.id.ItemButton);
convertView.setTag(holder);//綁定ViewHolder對象 }
else{
holder = (ViewHolder)convertView.getTag();
}
holder.title.setText(getDate().get(position).get("ItemTitle").toString());
holder.text.setText(getDate().get(position).get("ItemText").toString());
holder.bt.setOnClickListener(new OnClickListener() {
@Override
publicvoid onClick(View v) {
Log.v("MyListViewBase", "你點擊了按鈕" + position);
}
});
return convertView;
}
}
public final class ViewHolder{
public TextView title;
public TextView text;
public Button bt;
}
}
2 LayoutInflater
假設(shè)root 的xml文件為layout_root嘀趟,待infalte的xml文件為layout_child:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_root"
android:orientation="vertical"
android:layout_width="300dp"
android:layout_height="400dp"
android:background="@color/forestgreen"
>
<TextView
android:id="@+id/tv_root_ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LL and root"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
/>
</LinearLayout>
layout_child:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_child"
android:orientation="vertical"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@color/violet"
>
<TextView
android:id="@+id/tv_child_ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LL and child"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
/>
</LinearLayout>
private void caseOne(){
childView = inflater.inflate(R.layout.layout_child, null);
setContentView(childView);
}
這種情況脐区,渲染的child視圖,沒有view group, 所以他的layout height 和 width都不起作用她按,自動為match_parent.
private void caseTwo(){
rootView = (ViewGroup)inflater.inflate(R.layout.layout_root,null);
childView = inflater.inflate(R.layout.layout_child, rootView, false);
setContentView(childView);
}
這個時候有rootview牛隅,所以layout_width 和 height起作用。
private void caseThree(){
rootView = (ViewGroup)inflater.inflate(R.layout.layout_root,null);
childView = inflater.inflate(R.layout.layout_child, rootView, true);
setContentView(childView);
}