2011-05-21 92 views
3

我是新來的android,我花了最後2天嘗試以前的例子和在線解決方案,但我似乎無法讓我的頭在它:(Android的ListView動態按鈕爲每一行調用動態偵聽器

我能夠顯示列表視圖,從在線解析一些JSON並存儲書名,書籍描述和書籍ID,並將這些數據顯示在列表視圖中我希望能夠將「下載」按鈕在ListView的每一行中,每個按鈕將對應於Click()上的書本ID,並且動作偵聽器將通過將該ID附加到URL來下載該書。 例如www.books.com/download_book1或/ download_book2 ... 。

這裏是我的代碼。 Catalogue.java類

public class Catalogue extends ListActivity { 

private JSONObject json; 
private ListView lv; 

private ArrayList<Integer> alKey = new ArrayList<Integer>(); 

@Override 
    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); //icicle 
      setContentView(R.layout.shelflist); 
      ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>(); 


.... 
try{ 

       JSONArray entries = json.getJSONArray("entries"); 

       for(int i=0;i<entries.length();i++){       
        HashMap<String, String> map = new HashMap<String, String>();  
        JSONObject e = entries.getJSONObject(i); 

        alKey.add(e.getInt("key")); 
        map.put("id", String.valueOf(i)); 
        map.put("title", "Title:" + e.getString("title")); 
        map.put("description", "Description: " + e.getString("description")); 
        mylist.add(map); 


       }  
      }catch(JSONException e)  { 
       Log.e("log_tag", "Error parsing data "+e.toString()); 
      } 

      ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.shelfrow, 
          new String[] { "title", "description" }, 
          new int[] { R.id.item_title, R.id.item_subtitle }); 

      setListAdapter(adapter); 

        lv = getListView(); 
        lv.setTextFilterEnabled(true); 

.....

這是據我得到的。我不知道如何在List中每行添加1個按鈕,併爲每個按鈕分配一個動作偵聽器。 我也有一個shelfrow.xml文件(textView,textView for item_title和item_subtitle)和一個shelflist.xml文件(ListView)。 我有一個shelf.xml文件

回答

8

基本上你需要學習的ListAdapter概念。

下面是一個簡短的故事:描繪一個對象,該對象包含要在列表中顯示的數據以及單獨顯示每條線的方式。這是你的ListAdapter。現在採取每一行:這是一本書和一個標題和一個OnClickListener。它使用TextView(用於標題)和Button(用於OnClickListener)在視圖內呈現。您只需要爲將要用於每行的適配器添加一個View,並在列表中添加一份您想要的書籍列表。

下面是一些示例代碼。我希望它清除了一點東西

private class MyItemModel{ //that's our book 
    String title; // the book's title 
      String description; 
      long id; 
    OnClickListener listener = new OnClickListener(){ // the book's action 
     @Override 
     public void onClick(View v) { 
          // the default action for all lines 
      doSomethingWithTheBookTitleOrUniqueId(this); 
     } 
    }; 
} 

private class MyListAdapter extends BaseAdapter{ 
    View renderer; 
    List<MyItemModel> items; 

      // call this one and pass it layoutInflater.inflate(R.layout.my_list_item) 
    public MyListAdapter(View renderer) { 
     this.renderer = renderer; 
    } 

      // whenever you need to set the list of items just use this method. 
      // call it when you have the data ready and want to display it 
    public void setModel(List<MyItemModel> items){ 
     this.items = items; 
     notifyDataSetChanged(); 
    } 

    @Override 
    public int getCount() { 
     return items!=null?items.size():0; 
    } 
    @Override 
    public Object getItem(int position) { 
     return items!=null?items.get(position):null; 
    } 
    @Override 
    public long getItemId(int position) { 
     return items!=null?items.get(position).id:-1; 
    } 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     if(convertView==null){ 
      convertView = renderer; 
     } 
     MyItemModel item = items.get(position); 
      // replace those R.ids by the ones inside your custom list_item layout. 
     TextView label = (TextView)convertView.findViewById(R.id.item_title); 
     label.setText(item.label); 
     Button button = (Button)convertView.findViewById(R.id.item_button); 
     button.setOnClickListener(item.listener); 
     return convertView; 
    } 
} 

爲了通過而不是把數據的包含HashMap的列表裏,你可以爲實例(要小心這樣做的名單,我還更新了MyItemModel和MyListAdapter到您的需要,增加了標識和描述特性):

List<MyItemModel> myListModel = new ArrayList<MyItemModel>(); 
try{ 
    JSONArray entries = json.getJSONArray("entries"); 
    for(int i=0;i<entries.length();i++){       
     MyItemModel item = new MyItemModel();  
     JSONObject e = entries.getJSONObject(i); 
     alKey.add(e.getInt("key")); 
     item.id = i; 
     item.title = e.getString("title"); 
     item.description = e.getString("description"); 
     // you can change the button action at this point: 
     // item.onClickListener = new OnClickListener(){...}; 
     myListModel.add(item); 
    } 

}catch(JSONException e)  { 
    Log.e("log_tag", "Error parsing data "+e.toString()); 
} 
ListAdapter adapter = new MyListAdapter(getLayoutInflater().inflate(R.layout.shelfrow, this)); 
adapter.setModel(myListModel); 
setListAdapter(adapter); 
lv = getListView(); 
lv.setTextFilterEnabled(true); 
+0

我有種讓你在說什麼的那種故事,但我仍然有麻煩的編碼一切正常 – Plokoon 2011-05-21 15:12:02

+0

我正在改變ListAdapter適配器=新的SimpleAdapter到MyListAdapter – Plokoon 2011-05-21 15:39:10

+0

在我的活動(貨架類)如何將我的hashmap數據(標題和描述)我的適配器? – Plokoon 2011-05-21 15:46:03

1

您可以創建自己的類擴展ArrayAdapter,它將保存您的列表並將onClickListener設置爲每行中的Button。

但是在ArrayAdapter的getView方法中,您必須每次都創建一個新視圖。

例如 - 地圖的排佈置

<?xml version="1.0" encoding="utf-8"?> 

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_height="110dp" 
    android:background="#FFF" 
    android:layout_width="fill_parent"> 

<LinearLayout 
       android:layout_width="fill_parent" 
       android:background="#FFF" 
       android:orientation="vertical" 
       android:padding="2dp" 
       android:layout_height="110dp"> 
    <TextView android:id="@+id/list_item_title" 
       android:background="#FFF" 
       android:layout_width="fill_parent" 
       android:layout_height="40dp"/> 
    <Button android:id="@+id/download_button" 
      android:gravity="center" 
      android:text="Download" 
      android:layout_height="35dp"/> 
</LinearLayout> 

</RelativeLayout> 

和getView方法ArrayAdapter

private List<Map<String, String>> jsonMapList; 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View v = inflater.inflate(R.layout.list_item, null); 
    // here you set textview values (title and description) 
    // TextView title = (TextView) v.findViewById(R.id.list_item_title); 
    // title.setText('bla'); 

    // and set OnClickListener 
    Button button = (Button) v.findViewById(R.id.download_button);     
    button.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 
      downloadFile(getUrl(position)); 
     } 
    }); 

    return v; 
} 

// method that downloads file 
private void downloadFile(String url) {} 

// get url from your list by index 
private String getUrl(int index) { 
    return jsonMapList.get(index).get("url"); 
} 

用法是不必要的,你可以使用任何你喜歡的對象。

在活動課

CustomAdapter listAdapter = new CustomAdapter(this, android.R.layout.simple_list_item_single_choice, jsonMapList); 
    setListAdapter(listAdapter);