我是android的新手,我花了最近2天尝试过前面的例子和在线解决方案,但我似乎无法理解它:(
我能够显示列表视图,从在线解析一些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文件答案 0 :(得分:8)
基本上你需要学习ListAdapter的概念。
以下是短篇小说:图片中包含要在列表中显示的数据的对象,以及单独显示每一行的方式。这是你的ListAdapter。现在拿出每一行:它是一本带有标题和OnClickListener的书。它在带有TextView(用于标题)和Button(用于OnClickListener)的View中呈现。您需要做的就是将一个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;
}
}
为了传递List,而不是将数据放在你的hashmaps列表中,你可以这样做(小心,我也根据你的需要更新了MyItemModel和MyListAdapter,添加了id和description属性): / p>
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);
答案 1 :(得分: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>
和ArrayAdapter中的getView方法
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");
}
不需要使用Map,您可以使用您喜欢的任何对象。
在活动课
CustomAdapter listAdapter = new CustomAdapter(this, android.R.layout.simple_list_item_single_choice, jsonMapList);
setListAdapter(listAdapter);