0

我在正确识别ListView.

有 4 个类很重要,代码很多,所以首先我将解释这些类的逻辑。

  • 输入ListActivity并初始化其ListView
  • 执行AsyncTask从服务器下载 JSON 响应,解析它,ListView用对象填充并设置适配器,同时显示ProgressDialog
  • PlaylistItem类包括简单地从单个 JSONObject 获取数据的方法。它用于参数化 ArrayList 及其对象
    • 完成后AsyncTask,列表中充满了项目,看起来像 |Button| 艺术家( TextView) - 标题( TextView)

更新

解决了第一个问题,但仍然无法弄清楚按钮有什么问题

2)。OnClickListener我在适配器的 getView() 方法中为我的按钮设置了一个。为了确定按钮是否被正确识别,我什么也没做,只是改变了它的背景。但是单击某个按钮会强制更改每 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);

}
    }

音频列表适配器

           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;
}
    }
4

2 回答 2

1

但是单击某个按钮会强制更改每 11 个或第 12 个按钮的背景。到现在还想不通。

您正在与 ListViews 回收行布局的方式作斗争。
可以这样想:如果你有一个有 10,000 行的 ListView,但屏幕上只能容纳其中的 9 个,那么创建 10,000 个独特的布局是没有意义的。这只是浪费资源,而 ListView 只创建约 10 个布局并重用它们。

解决方案:每行在重用时恢复到默认状态。补充getView()

} else {
    pl = (PlaylistItem) convertView.getTag();
    pl.btnPlay.setBackgroundResource(R.drawable.list_button_play);
    // I guessed at the resource's name         ^^^^^^^^^^^^^^^^
}

(你也可以做一些小的改变来加快你的代码。例如,你只需要一个 OnClickListener,因为它们都包含相同的代码,将其设为类变量并将其传递给每个播放按钮。还有更多。)

于 2013-03-01T19:41:11.057 回答
1

编辑

尝试这个

在可绘制的 button_play.xml 中使用自定义选择器

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/pause_button"
          android:state_selected="true" />
    <item android:drawable="@drawable/play_button" />
</selector>

像这样修改你的适配器

 public class AudioListAdapter extends ArrayAdapter<PlaylistItem> {
private PlaylistItem pl;
private Context context;
private int layoutResourceId;
private PlaylistItem aud;
private ArrayList<PlaylistItem> data = null;
Button previous;

public AudioListAdapter(Context context, int layoutResourceId,
        ArrayList<PlaylistItem> data) {
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    previous=new Button(context);
    this.context = context;
    this.data = data;

}

....
....

@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.btnPlay.setBackGroundResouce(R.drawable.button_play); //you can set here or in xml

        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.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());
            }
                //for some reason, the background gets changed for every 11th or 12th button in the list
             Button current=((Button)v);
              current.setSelected(true);
              previous.setSelected(false);
              previous=current;
        }
    });

    return convertView;
}

    }

你的按钮和列表项不可点击的原因是因为你的列表有一个焦点项目按钮,所以你需要为你的按钮设置 setFocusable=false 。尝试在 xml 中为您的按钮设置 focusable=false。如果它不适合你,那就这样做

在您的行 xml 文件中

1.为您的按钮设置 focusable=true。2.在您的父项的同一组android:descendantFocusability="blocksDescendants"中。(即您的视图所在的父布局)。

在为按钮设置onclickListener 后的getView() 方法中,为按钮设置focusable false。它肯定会起作用。我希望这能帮到您..

于 2013-03-01T15:39:45.310 回答