在Listview中加载。将最后一个条目中的数据加载到所有行中

时间:2015-01-27 09:51:25

标签: android json listview android-asynctask

我试图制作歌曲列表。每个列表项应包含标题,艺术家,歌曲开始的时间和一些专辑封面。 我似乎无法让它正常工作,每次我尝试它只会将最后一个条目中的数据加载到所有行中。 我已经阅读了有关ViewHolders和图片加载库的内容,并试图实现我发现的没有运气的东西。

这是我的代码:

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            
}

 }            

请帮我StackOverflow,你是我唯一的希望。

1 个答案:

答案 0 :(得分:1)

在片段中,您将数据保存在静态变量中。在这种情况下,执行for循环后,最后的条目将保存在所有这些静态变量中。因此,只有一个条目是最后一个存储的。在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;
}

另外我建议你在getView()中使用ViewHolder模式,这是在Listview中扩充数据的标准方法。

更新:

title.setText(data.get(position).get("Title"));
artist.setText(data.get(position).get("Artist"));
timeInfo.setText(data.get(position).get("Start"));

上面的内容可以帮助您从散列图列表中获取数据。

希望你明白并希望这会有所帮助。