[英]Loading in Listview. Loads data from last entry into all rows
I'm trying to make a list of songs. 我正在尝试列出歌曲。 Each list item should contain title, artist, time the song starts and some album art.
每个列表项应包含标题,艺术家,歌曲开始的时间和一些专辑封面。 I can't seem to get it to work properly, each time I try it only loads the data from the last entry into all the rows.
我似乎无法使其正常工作,每次尝试都只能将最后一个条目中的数据加载到所有行中。 I've read about ViewHolders and image loading libraries and tried implementing what I found with no luck.
我已经阅读了有关ViewHolders和图像加载库的信息,并尝试实现我发现的运气。
Here's my code: 这是我的代码:
public class MyAdapter extends SimpleAdapter {
private static LayoutInflater inflater = null;
List data;
public MyAdapter(Context context, List<? extends Map<String, ?>> data,
int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.data = data;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
String imgURL = SongListFragment.imgURL;
if(convertView == null){
vi = inflater.inflate(R.layout.custom_listitem, null);
TextView title = (TextView) vi.findViewById(R.id.title);
TextView artist = (TextView) vi.findViewById(R.id.artist);
TextView timeInfo = (TextView) vi.findViewById(R.id.timeInfo);
title.setText(SongListFragment.title);
artist.setText(SongListFragment.artist);
timeInfo.setText(SongListFragment.starttime);
Picasso.with(vi.getContext()).load(imgURL).into((ImageView)vi.findViewById(R.id.img));
Log.d("Image", imgURL);
}
return vi;
}
}
public class HttpGetTask extends AsyncTask<String, Void, String> {
interface OnHttpGetListener{
public void httpGetCompleted(String response);
public void httpGetFailed(String error);
}
private OnHttpGetListener mListener;
private boolean mGetFailed;
private AndroidHttpClient client;
public HttpGetTask(OnHttpGetListener listener) {
mListener = listener;
client = AndroidHttpClient.newInstance("Android");
}
@Override
protected String doInBackground(String... params) {
try {
HttpGet uri = new HttpGet(params[0]);
HttpResponse resp = client.execute(uri);
ByteArrayOutputStream out = new ByteArrayOutputStream();
resp.getEntity().writeTo(out);
resp.getEntity().consumeContent();
out.close();
client.close();
return out.toString();
} catch (Exception e) {
mGetFailed = true;
e.printStackTrace();
return e.getMessage();
}
}
@Override
protected void onPostExecute(String response) {
if(mGetFailed) {
mListener.httpGetFailed(response);
} else {
mListener.httpGetCompleted(response);
}
}
}
public class SongListFragment extends Fragment implements OnHttpGetListener {
ListView listview;
ArrayList<HashMap<String, String>> listEntries = new ArrayList<HashMap<String, String>>();
static String imgURL = null;
static String title = null;
static String artist = null;
static String starttime = null;
static String endtime = null;
public SongListFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.listview_fragment, container, false);
listview = (ListView) rootView.findViewById(R.id.songlist);
getJSON();
return rootView;
}
private void getJSON(){
HttpGetTask jsonGetter = new HttpGetTask(this); //registers to listen callbacks
final String jsonUrl = "http://stark-castle-5854.herokuapp.com/songlist"; //url to json
jsonGetter.execute(jsonUrl); //starts the async task
}
public void httpGetCompleted(String response) {
// this gets called when the background task
// to get json is completed without errors
try {
JSONArray newJArray = new JSONArray(response);
for(int i = 0; i < newJArray.length(); i++){
JSONObject json = newJArray.getJSONObject(i);
title = json.getString("title");
artist = json.getString("artist");
starttime = json.getString("starttimeutc");
endtime = json.getString("stoptimeutc");
//all entries do not have an img resource
if(json.has("img")){
imgURL = json.getString("img");
}else{
imgURL = null;
}
long sTime = Long.parseLong(starttime);
Date date = new Date(sTime);
SimpleDateFormat sdf = new SimpleDateFormat("E MMM dd, HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+1"));
String formattedDate = sdf.format(date);
Log.d("test", "Time: " + date);
//hashmap to store values for the listview in
HashMap<String, String> map = new HashMap<String, String>();
map.put("Title", title);
map.put("Artist", artist);
map.put("Start", "Starts: " + formattedDate);
map.put("End", endtime);
map.put("ImgURL", imgURL);
//add hashmap values to arraylist
listEntries.add(map);
Log.d("test", "Success! Artist: " + artist +
" Title: " + title +
" Start: " + starttime +
" End: " + endtime +
" ImgURL: " + imgURL);
}
//add arraylist to listview
ListAdapter adapter = new MyAdapter(getActivity(), listEntries,
R.layout.custom_listitem,
new String[] { "Title", "Artist", "Start"}, new int[] {
R.id.title, R.id.artist, R.id.timeInfo});
listview.setAdapter(adapter);
//Picasso.with(getActivity()).load("http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png").into((ImageView)getView().findViewById(R.id.img));
} catch (JSONException e) {
e.printStackTrace();
}
}
public void httpGetFailed(String error) {
// this gets called when the background task fails to get json
Log.e("GetFail", error); // printing to error
}
}
Please help me StackOverflow, you're my only hope. 请帮助我StackOverflow,您是我唯一的希望。
In your fragment, you are saving data in static variables. 在片段中,您将数据保存在静态变量中。 In this case after executing the for loop, the last entries will be saved in all those static variables.
在这种情况下,在执行for循环之后,最后一个条目将保存在所有这些静态变量中。 So there is only one entry which is last, stored.
因此,只有最后一个存储的条目。 And in getview view you are accessing those variables every time, which means you are accessing same values for all rows.
并且在getview视图中,您每次都访问那些变量,这意味着您正在为所有行访问相同的值。
To solve this, you need to access the data which you are passing as List(Maps). 为了解决这个问题,您需要访问作为List(Maps)传递的数据。 Do a get call on this and store it as object.
对此进行get调用并将其存储为对象。 Then get the properties of those objects.
然后获取那些对象的属性。
Something like this in your adapters getview()
适配器中的
getview()
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
String imgURL = SongListFragment.imgURL;
if(convertView == null){
vi = inflater.inflate(R.layout.custom_listitem, null);
TextView title = (TextView) vi.findViewById(R.id.title);
TextView artist = (TextView) vi.findViewById(R.id.artist);
TextView timeInfo = (TextView) vi.findViewById(R.id.timeInfo);
// NOTE THAT THIS PSEUDO CODE YOU NEED TO GET THE LIST POSITION AND MAP POSITION HERE TO ACCESS TITLE<ARTIST AND STARTTIME.
title.setText(data.get(position).title);
artist.setText(data.get(position).artist);
timeInfo.setText(data.get(position).starttime);
Picasso.with(vi.getContext()).load(imgURL).into((ImageView)vi.findViewById(R.id.img));
Log.d("Image", imgURL);
}
return vi;
}
Also I would suggest you to use ViewHolder pattern in getView()
which is a standard way of inflating data inside Listview. 我也建议您在
getView()
使用ViewHolder模式,这是在Listview中填充数据的标准方法。
UPDATE: 更新:
title.setText(data.get(position).get("Title"));
artist.setText(data.get(position).get("Artist"));
timeInfo.setText(data.get(position).get("Start"));
Something like above should help you to get the data from list of hashmaps. 上面类似的内容应该可以帮助您从哈希表列表中获取数据。
Hope you understood and hope this helps. 希望您理解并希望对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.