情况:我从服务器获得了包含用户播放列表的JSONObject
。我想在ListView
中显示这些数据,在我的测试用例中有288个音频文件。 JSON被正确解析,大小等于288.我创建了一个帮助类,并使用其对象对ArrayList
进行参数化。问题:我的ListView
中只有288个项目但是正确的条目艺术家 - 标题上升到索引13(不知道原因)然后他们得到重复。所以我在列表中没有288个不同的条目,但我只有14个条目重复到列表结尾。
更新:我删除了if语句并解决了问题,但RAM消耗增加了3MB。有什么优化建议吗?
public class AudioList extends ListActivity {
private ListView lv;
private JSONObject usersPlaylist, singleJSONItem;
private JSONArray responseJSONArray;
private SharedPreferences prefs;
private PlaylistItem audioList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_list);
init();
ArrayList<PlaylistItem> playlist = new ArrayList<PlaylistItem>();
try {
usersPlaylist = Utils.retrieveJsonObjectFromUrl(new URL(
APP_CONSTANTS.REQUEST_AUDIO_LIST(prefs)), this);
responseJSONArray = usersPlaylist.getJSONArray("response");
for (int i = 0; i < responseJSONArray.length(); i++) {
singleJSONItem = responseJSONArray.getJSONObject(i);
audioList = new PlaylistItem(singleJSONItem);
playlist.add(audioList);
}
Toast.makeText(getApplicationContext(),
Integer.toString(playlist.size()), Toast.LENGTH_LONG)
.show(); //there are 288 entries, JSONArray parsed correctly
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
AudioListAdapter adapter = new AudioListAdapter(this,
R.layout.playlist_item, playlist);
lv.setAdapter(adapter);
}
private void init() {
lv = getListView();
lv.setTranscriptMode(0x00000000);
lv.setDividerHeight(1);
lv.setSmoothScrollbarEnabled(true);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
}
PlayListItem类:
public class PlaylistItem {
private String artist, title;
private JSONObject obj;
public PlaylistItem(JSONObject obj) {
this.obj = obj;
}
public PlaylistItem(){
}
public String getArtist() {
try {
artist = obj.getString("artist");
} catch (JSONException e) {
e.printStackTrace();
}
return artist;
}
public String getTitle() {
try {
title = obj.getString("title");
} catch (JSONException e) {
e.printStackTrace();
}
return title;
}
}
适配器:
public class AudioListAdapter extends ArrayAdapter<PlaylistItem> {
private Context context;
private int layoutResourceId;
private PlaylistItem aud;
private ArrayList<PlaylistItem> data = null;
public AudioListAdapter(Context context, int layoutResourceId,
ArrayList<PlaylistItem> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = new ViewHolder();
aud = data.get(position);
//it's giving a CORRECT position if I hardcode the index, like data.get(99);
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder.play = (Button) row.findViewById(R.id.btn_list_play);
holder.imgSaved = (ImageView) row
.findViewById(R.id.img_list_audio_saved);
holder.tvArtist = (TextView) row
.findViewById(R.id.tvListItemArtist);
holder.tvTitle = (TextView) row.findViewById(R.id.tvListItemSong);
holder.tvArtist.setText(aud.getArtist());
holder.tvTitle.setText(aud.getTitle());
}
return row;
}
static class ViewHolder {
Button play;
ImageView imgSaved;
TextView tvArtist, tvTitle;
}
}
答案 0 :(得分:2)
在getView方法中,如果它是循环使用的,则不会再次填充View。因此,一旦您在屏幕外滚动它将开始显示旧的。您也没有设置/检索ViewHolder。请尝试以下实施(未经测试)。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
aud = data.get(position);
//it's giving a CORRECT position if I hardcode the index, like data.get(99);
if (row == null) {
holder = new ViewHolder();
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder.play = (Button) row.findViewById(R.id.btn_list_play);
holder.imgSaved = (ImageView) row
.findViewById(R.id.img_list_audio_saved);
holder.tvArtist = (TextView) row
.findViewById(R.id.tvListItemArtist);
holder.tvTitle = (TextView) row.findViewById(R.id.tvListItemSong);
row.setTag(holder);
} else {
holder = (ViewHolder)row.getTag();
}
holder.tvArtist.setText(aud.getArtist());
holder.tvTitle.setText(aud.getTitle());
return row;
}
答案 1 :(得分:1)
如果您要删除此行:
View row = convertView;
每次都给视图充气,然后这个问题就会消失。 我这样做了很多次,如下所述:
How to save state of changed ImageView in Listview row, after it' has disappeared from screen?
实际上我不知道为什么会这样,因为建议使用convertView。
<强>更新强>
试试这个:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
ViewHolder holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(layoutResourceId, parent, false);
holder.play = (Button) row.findViewById(R.id.btn_list_play);
holder.imgSaved = (ImageView) row.findViewById(R.id.img_list_audio_saved);
holder.tvArtist = (TextView) row.findViewById(R.id.tvListItemArtist);
holder.tvTitle = (TextView) row.findViewById(R.id.tvListItemSong);
holder.tvArtist.setText(aud.getArtist());
holder.tvTitle.setText(aud.getTitle());
return row;
}
答案 2 :(得分:1)
我在你的getView方法中做了一些修改。放置并检查它。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
aud = data.get(position);
//it's giving a CORRECT position if I hardcode the index, like data.get(99);
if (row == null) {
holder = new ViewHolder();
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder.play = (Button) row.findViewById(R.id.btn_list_play);
holder.imgSaved = (ImageView) row.findViewById(R.id.img_list_audio_saved);
holder.tvArtist = (TextView) row .findViewById(R.id.tvListItemArtist);
holder.tvTitle = (TextView) row.findViewById(R.id.tvListItemSong);
row.setTag(holder);
}
else
{
holder = (ViewHolder ) row.getTag();
}
holder.tvArtist.setText(aud.getArtist());
holder.tvTitle.setText(aud.getTitle());
return row;
}
答案 3 :(得分:1)
if (convertView == null)// if null
{
convertView = mInflater.inflate(R.layout.list, null);//inflate view
} else
{
holder = (ViewHolder) convertView.getTag();// set tag to holder.
}
进行这些更改。