【发布时间】:2013-03-01 15:18:19
【问题描述】:
我在正确识别 ListView 中的项目时遇到了一些问题。
有 4 个类很重要,代码量很大,所以我先解释一下这些类的逻辑。
- 输入
ListActivity并初始化其ListView - 执行一个
AsyncTask,从服务器下载JSON响应,解析它,用对象填充ListView并设置适配器,同时显示ProgressDialog -
PlaylistItem 类包括简单地从单个 JSONObject 获取数据的方法。它用于参数化 ArrayList 及其对象
-
AsyncTask完成后,列表中充满了项目,看起来像 |Button|艺术家(TextView) - 标题(TextView)
-
更新
解决了第一个问题,但仍然无法弄清楚按钮出了什么问题
2)。我在适配器的 getView() 方法中为我的按钮设置了一个OnClickListener。为了确定按钮是否被正确识别,我什么也没做,只是改变了它的背景。但是单击某个按钮会强制更改每 11 个或第 12 个按钮的背景。目前还想不通。
在这些问题得到解决之前,我无法继续获取 url 和流式音频,因此非常感谢任何帮助。我的课在下面,如果有不清楚的地方请询问。
音频列表
public class AudioList extends ListActivity {
private ListView lv;
private PlaylistLoader loader;
private AudioListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_list);
init(); // initialize the ListView
/*--- populate the list with user's audio in case network connection is available ---*/
loader = new PlaylistLoader(this, lv, adapter);
if (Utils.isNetworkAvailable(this)) {
loader.execute();
} else {
APP_CONSTANTS.NO_DATA_CONNECTION(this);
}
}
@Override
protected void onResume() {
super.onResume();
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(getApplicationContext(), Integer.toString(arg2),
Toast.LENGTH_SHORT).show();
}
});
}
private void init() {
lv = getListView();
lv.setTranscriptMode(0x00000000);
lv.setDividerHeight(1);
lv.setSmoothScrollbarEnabled(true);
lv.setVerticalFadingEdgeEnabled(true);
}
播放列表加载器
public class PlaylistLoader extends AsyncTask<Void, Void, Void> {
private JSONObject usersPlaylist, singleJSONItem;
private JSONArray responseJSONArray;
private ListView lv;
private ArrayList<PlaylistItem> playlist;
private Activity a;
private PlaylistItem audioList;
private SharedPreferences prefs;
private ProgressDialog pd;
AudioListAdapter adapter;
public PlaylistLoader(Activity a, ListView lv, AudioListAdapter adapter) {
this.lv = lv;
this.a = a;
this.adapter = adapter;
}
@Override
protected Void doInBackground(Void... arg0) {
/*--- create new ArrayList of PlaylistItem Objects ---*/
playlist = new ArrayList<PlaylistItem>();
/*--- get the preferences using context of calling activity ---*/
prefs = PreferenceManager.getDefaultSharedPreferences(a);
try {
/*--- download the response JSONObject from server // access_token and
* user_id come from activity's defaultSharedPreferences ---*/
usersPlaylist = Utils.retrieveJsonObjectFromUrl(new URL(
APP_CONSTANTS.REQUEST_AUDIO_LIST(prefs)), a);
/*--- get the response array from received object ---*/
responseJSONArray = usersPlaylist.getJSONArray("response");
/*--- populate the ArrayList with Objects from the response array ---*/
for (int i = 0; i < responseJSONArray.length(); i++) {
singleJSONItem = responseJSONArray.getJSONObject(i);
audioList = new PlaylistItem(singleJSONItem);
playlist.add(audioList);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(a);
pd.setTitle("Please wait");
pd.setMessage("Retrieving audio list...");
pd.show();
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
lv.setVisibility(View.VISIBLE);
pd.dismiss();
/*--- set the adapter passed in constructor as an adapter for passed ListView ---*/
adapter = new AudioListAdapter(a, R.layout.playlist_item, playlist);
lv.setAdapter(adapter);
}
}
AudioListAdapter
public class AudioListAdapter extends ArrayAdapter<PlaylistItem> {
private PlaylistItem pl;
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 PlaylistItem getItem(int position) {
return super.getItem(position);
}
@Override
public int getCount() {
return data.size();
}
@Override
public int getPosition(PlaylistItem item) {
return super.getPosition(item);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
pl = new PlaylistItem();
aud = getItem(position);
if (convertView == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
convertView = inflater.inflate(layoutResourceId, parent, false);
pl.btnPlay = (Button) convertView.findViewById(R.id.btn_list_play);
pl.imgSaved = (ImageView) convertView
.findViewById(R.id.img_list_audio_saved);
pl.tvArtist = (TextView) convertView
.findViewById(R.id.tvListItemArtist);
pl.tvTitle = (TextView) convertView
.findViewById(R.id.tvListItemSong);
convertView.setTag(pl);
} else {
pl = (PlaylistItem) convertView.getTag();
pl.btnPlay.setBackgroundResource(R.drawable.list_button_play);
}
pl.tvArtist.setText(aud.getArtist() + " " + "-");
pl.tvTitle.setText(aud.getTitle());
pl.btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*--- vibrate if this option is enabled in the preferences ---*/
if (APP_CONSTANTS.isHapticFeedbackEnabled(getContext())) {
APP_CONSTANTS.doVibrate(getContext());
}
pl.btnPlay.setBackgroundResource(R.drawable.list_button_pause);
}
});
return convertView;
}
播放列表项
public class PlaylistItem {
private String artist, title;
private JSONObject obj;
public Button btnPlay;
public TextView tvArtist, tvTitle;
public ImageView imgSaved;
public int duration;
public int audio_id;
public String url;
/*--- the constructor takes a single JSONObject from the response array ---*/
public PlaylistItem(JSONObject obj) {
this.obj = obj;
}
public PlaylistItem() {
// default constructor
}
/*--- the methods below return values by key from the passed JSONObject ---*/
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 int getID() {
try {
audio_id = obj.getInt("aid");
} catch (JSONException e) {
e.printStackTrace();
}
return audio_id;
}
public String getURL() {
try {
url = obj.getString("url");
} catch (JSONException e) {
e.printStackTrace();
}
return url;
}
}
【问题讨论】:
-
1) 你有没有对此做过任何研究......它只是在 ListView 行中有 Clickable 元素时发生......问了很多次...... 2) 也问了很多次...... ListView是一个智能控制......你必须理解它......youtube.com/watch?v=wDBM6wVEO70(如果你在
getView中得到convertView- 你会有答案......)......无论如何......问题写得很好:) -
是的,我做到了。我看了这个视频。仍然找不到任何适合我的解决方案
-
heh 在 PlaylistItem 对象中存储播放列表状态(暂停/播放),然后根据 getView 中的此状态设置此可绘制对象 ...并且在 onClick 中仅在选定的 PlayListItem 中设置此状态
-
@Selvin 谢谢你的建议,我试试看
-
无论如何你确定你使用同一个类
PlaylistItem作为适配器数据和视图持有者?
标签: android android-listview android-asynctask