AndroidDev 板


LINE

※ 引述《bengohard (我的歌聲裡)》之銘言: : 問題:我有一個ListView,我想做到按一個Button後,把此ListView裡某item的屬性改變, : 請問該怎麼做(不使用onItemClick)? 此ListView使用了一個SimpleAdapter. : 我試過以下的方法無效,雖然取的到屬性值,但無法改變屬性值,為何? : View view = Adapter.getView(0, ListView.getChildAt(0), ListView); : ImageView img = (ImageView)view.findViewById(R.id.ID_Image); : int vis = img.getVisibility(); //值正確 : img.setVisibility(View.INVISIBLE); //改變此值但無作用 : Adapter.notifyDataSetChanged(); : //再抓一次值結果還是原本的值 >"< : View view = Adapter.getView(0, ListView.getChildAt(0), ListView); : ImageView img = (ImageView)view.findViewById(R.id.ID_Image); : int v = img.getVisibility(); BaseAdapter的特性就是可以重用View來節省資源, ListView的重用結構會長這樣, http://www.b2creativedesigns.com/Tutorials/CustomListView/recycle.png
這張圖可以很清楚看到 item 9 一開始在recycle pool, 當使用者手滑動, item 1被滑出去item 9就進來listview可視範圍 item 1進入recycle pool, 照這個邏輯, 如果使用者繼續往上滑, 那麼item 2, 3...就會進入回收區, item 9, 1, 2 ...就會出現在畫面上。 這代表什麼意思? 代表著就算你資料有一百筆, 一千筆, 畫面呈現的也只有9個item, 這邊代表著view也只生成9個, 就不會佔用太多的資源。 那我怎麼知道他是第幾筆資料? 這個不用擔心 BaseAdapter幫你處理好這件事情了。 只要你資料順序塞好, 不管你是丟在怎樣的資料結構, 不管是ArrayList, Array, HashMap...等等。 只要你資料設定好, 就可以開始使用這個有趣的設計了。 程式怎麼做呢? 一開始宣告一個MyAdapter繼承BaseAdapter public class MyAdapter extends BaseAdapter { @Override public int getCount() { // TODO Auto-generated method stub return 0; } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return 0; } @Override public View getView(int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub return null; } } 上面你會看到四個方法, 基本上只要處理兩個方法 getCount跟getView即可, 剩下的兩個方法暫時不會用到, 有興趣的可以研究看看。 getCount就是跟adapter說你有幾筆資料要呈現, 假設現在你有100筆資料, 塞在arraylist內, 那麼我們來模擬一下 private ArrayList<Integer> mList; public MyAdapter(){ mList = new ArrayList<Integer>(); for(int i = 0; i < 100; i++){ mList.add(i); } } 首先在建構子上建立一個arraylist並且塞值到這個陣列內, @Override public int getCount() { // TODO Auto-generated method stub return mList.size(); } 接著把資料結構的長度塞給getCount方法, 讓listview知道你的資料有多長。 接著到重頭戲getView 這個方法就是listView會不斷的來存取, 是一個callback function, 而不是由你自己去存取, 在看一次這個方法 我把參數改成英文名稱比較好認 @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub return null; } 第一個是我們的item到哪一個位置? 第二個是我們這個item所使用的view 第三個是我們item的parent 一開始會先把目前的view抓出來 判斷他是不是被初始化過 如果有被初始化過 代表著他之前就被使用過了 @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if(null == view){ } else{ } return view; } 這樣一來我們就可以把這個實體化過的view傳回去給listview了。 接著如果他是空的 則對他進行初始化 要初始化之前 先取得inflate 回到建構子補上 private LayoutInflater mLayoutInflater; public MyAdapter(Context mContext){ mLayoutInflater = LayoutInflater.from(mContext); ... } 再回到getView if(null == view){ view = mLayoutInflater.inflate(R.layout.listview_item, null); } else{ ... } 那個layout就是我們item view所裝的xml布局 透過LayoutInflater可以實體化成為一個view的物件 這樣一來就可以使用程式做很多靈活的操作了。 那layout裡面長怎樣呢? <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/item_text" /> </RelativeLayout> 因為是範例所以寫得很簡單 只放入一個textview 接著就要把這個textview存在holder裡面 什麼是holder? 就是幫我們記住item內所有元件的內容 先宣告一個類別來存放 class Holder{ TextView itemText; } 因為我們item layout很簡單 所以這樣就完成一個宣告 接著回到getView Holder holder; if(null == view){ view = mLayoutInflater.inflate(R.layout.listview_item, null); holder = new Holder(); holder.itemText = (TextView) view.findViewById(R.id.item_text); view.setTag(holder); } 由上面可以看到 當view是空的時候 就把holder new出來 然後把itemText裝進去 在透過view設定tag 裝進holder 那麼下次view不是空的條件下 就可以直接把holder拿出來用 就完成了reuse了功效了 else{ holder = (Holder) view.getTag(); } 這個adapter基本型態已經完成, 然後把資料結構內的資料塞進每一個item holder.itemText.setText(mList.get(position) + ""); 就會出現這樣的畫面 http://ppt.cc/qgYw 現在要來說明怎麼透過改變資料 來更新view 假設我們要改變某一列 假設是第2筆資料出現的地方背景就顯示紅色 那麼只要在retun view;之前加入 if(position == 2){ view.setBackgroundColor(Color.RED); } 就會出現第二列是紅色的 http://ppt.cc/9HSk 但是很奇怪 你往上滑動 居然第24列也是紅色的 http://ppt.cc/WD2r 這個就是reuse要注意的地方 因為listview就是把滑出去的item拿過來重用 所以那個重用的item背景還是紅色的 因此每一個item一開始都要先初始化 view.setBackgroundColor(Color.WHITE); if(position == 2){ view.setBackgroundColor(Color.RED); } 這樣就正常了 http://ppt.cc/PBHX 至於你的問題 想要讓一個Button按下去 某一個值進行變化 其實很簡單 只要開一個方法 public void setRowColor(int pos, int value){ mList.set(pos, value); notifyDataSetChanged(); } notifyDataSetChanged是用來刷新listview的畫面 也就是會再去讀取一圈getview 假設剛剛變化背景的判斷式改成 if(mList.get(position) == 200){ view.setBackgroundColor(Color.RED); } 外面設定一個button 按下的時候 將arraylist的值改變 那麼你就會看到listview有一列變紅色的 這就是用值去改變view 而不是用view去修正值 程式碼 http://uploadingit.com/file/ffokgjkq0kjer5tq/TestAndroid.zip -- posted from android bbs reader on my Nokia 3310 --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.231.138.193
※ 文章網址: http://webptt.com/m.aspx?n=bbs/AndroidDev/M.1413996267.A.CC8.html
1F:→ laiair: 想請問 simpleAdapter 和 baseAdapter 的差異是? 10/23 01:37
2F:→ givemepass: baseadapter比較彈性, 可操作的地方沒有限制, 假設現 10/23 08:53
3F:→ givemepass: 在每列背景顏色不同, 或者複雜一點的view就掛了, 例如 10/23 08:53
4F:→ givemepass: line的聊天室, fb的塗鴉牆 10/23 08:53
5F:→ laiair: ^^ 謝謝解惑 10/23 09:36
6F:推 JULONE780701: 太用心!可是這程式在我的Nikia 3310跑不起來 10/23 09:41
7F:推 bengohard: 詳細的講解+程式碼,馬上修改看看,太感謝你囉!!:D 10/23 11:41
8F:推 zerofinal: 推一個 10/24 10:07
9F:→ xisland: 我想每個item放不同背景圖耶,最好是由程式來畫,不用png檔 10/24 11:09
10F:→ xisland: 半夜12點起來試到現在還沒成功 10/24 11:10
11F:→ givemepass: 設條件就可以完成了, 還是你可以把程式碼貼上來看看 10/24 12:56
12F:推 xisland: OK了 10/24 14:20
13F:推 xisland: holder.bmp =Bitmap.createBitmap( //下略 10/24 14:23
14F:→ xisland: view.setImageBitmap(holder.bmp); 10/24 14:23
15F:→ xisland: 加這二行就可以了 10/24 14:24
16F:推 xisland: http://imgur.com/1Ajx1rd 10/25 11:50
17F:推 baobomb: 建議還是先弄懂oo 不然這類客製化的view你都會寫的很痛苦 10/27 16:01
18F:→ baobomb: 尤其是很容易不知道自己在寫什麼 10/27 16:01







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:BabyMother站內搜尋

TOP