使用asynctask更改单项listview android

时间:2013-10-19 12:53:34

标签: android listview android-listview android-asynctask

我正在学习如何使用AsyncTask更改单项自定义listview android,我已经关注this tutorial

但它在我的列表视图中看起来不起作用。

这是我的代码

private class ViewHolder {
    public ImageButton favorite;
    public TextView jmlh_favorite;
    protected int position;
}

public View getView(final int position, View convertView, ViewGroup parent) {
    View vi = convertView;
    final ViewHolder holder;

    if (convertView == null) {
        vi = inflater.inflate(R.layout.laporan_list_item, null);
        holder = new ViewHolder();
        holder.jmlh_favorite = (TextView)vi.findViewById(R.id.jmlh_favorite);
        holder.favorite = (ImageButton)vi.findViewById(R.id.favorite);
        vi.setTag(holder);
    } else {
        holder = (ViewHolder) vi.getTag();
    }

    holder.favorite.setOnClickListener(new android.view.View.OnClickListener() {
        @Override
        public void onClick(View v) {
            holder.position = position;
            position_change=position;
            String varid_laporan = holder.id_laporan.getText().toString();
            String var_kat_favorite = holder.kat_favorite.getText().toString();
            url = "http://xxxx.com/android/upload_image/favorite_laporan.php?kat="+var_kat_favorite+"&id_laporan="+varid_laporan+"&uid="+URLEncoder.encode(uid);
            grabURL(url,position,holder); 
        } 
    });

    return vi;
}

public void grabURL(String url, int position,ViewHolder holder) {
    Log.v("Android Spinner JSON Data Activity", url);
    mTask = new GrabURL(position, holder).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
}

private class GrabURL extends AsyncTask<String, Void, String> {
    private static final int REGISTRATION_TIMEOUT = 3 * 1000;
    private static final int WAIT_TIMEOUT = 30 * 1000;
    private final HttpClient httpclient = new DefaultHttpClient();
    final HttpParams params = httpclient.getParams();
    HttpResponse response;
    private String content = null;
    private boolean error = false;
    private ProgressDialog dialog = new ProgressDialog(activity);

    private int mPosition;
    private ViewHolder mHolder;

    public GrabURL(int position, ViewHolder holder) {
        mPosition = position;
        mHolder = holder;
    }

    protected void onPreExecute() {
        dialog.setMessage("Getting your data... Please wait...");
    }

    protected String doInBackground(String... urls) {
        String URL = null;

        try {
            URL = urls[0];
            HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT);
            HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT);
            ConnManagerParams.setTimeout(params, WAIT_TIMEOUT);

            HttpPost httpPost = new HttpPost(URL);
            response = httpclient.execute(httpPost);

            StatusLine statusLine = response.getStatusLine();

            if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                response.getEntity().writeTo(out);
                out.close();
                content = out.toString();
            } else {
                //Closes the connection.
                Log.w("HTTP1:",statusLine.getReasonPhrase());
                response.getEntity().getContent().close();
                throw new IOException(statusLine.getReasonPhrase());
            }
        } catch (ClientProtocolException e) {
            Log.w("HTTP2:",e );
            content = e.getMessage();
            error = true;
            cancel(true);
        } catch (IOException e) {
            Log.w("HTTP3:",e );
            content = e.getMessage();
            error = true;
            cancel(true);
        } catch (Exception e) {
            Log.w("HTTP4:",e );
            content = e.getMessage();
            error = true;
            cancel(true);
        }

        return content;
    }

    protected void onCancelled() {
        mTask.cancel(true);
        statusKoneksi();
    }

    protected void onPostExecute(String content) {
        if (error) {
            mTask.cancel(true);

            statusKoneksi();
        } else {
            displaylaporanList(content,mPosition,mHolder);
            mTask.cancel(true);
        }
    }
}

private void displaylaporanList(String response, int mPosition, ViewHolder mHolder){

    JSONObject json = null; 

    try {
        json = new JSONObject(response); 
        laporanListObj = json.getJSONArray(ContentLaporanActivity.TAG_FAVORITE_LAPORAN);
        int Jumlah_list_Data = laporanListObj.length();

        if (Jumlah_list_Data== 0) {
        } else {
            JSONObject c = laporanListObj.getJSONObject(0);
            String jumlah_favorite = c.getString(ContentLaporanActivity.TAG_BANYAK_FAVORITE_LAPORAN);
            String status_favorite = c.getString(ContentLaporanActivity.TAG_STATUS_FAVORITE);

            if (mHolder.position == mPosition) {
                mHolder.jmlh_favorite.setText(status_favorite);
            }
        }

        notifyDataSetChanged();
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

void statusKoneksi(){
    Toast.makeText(activity, "gagal", Toast.LENGTH_SHORT).show();
}

这个部分我想在方法displaylaporanList()中的结果asynctask时setText,但它没有设置Text。

if (mHolder.position == mPosition) {
    mHolder.jmlh_favorite.setText(status_favorite);
}

如何更新文字?

1 个答案:

答案 0 :(得分:0)

您的代码存在以下逻辑问题:您不应在getView()之外更新ViewHolder。 ViewHolder只是提高列表性能,不应该在任何时候用作列表项的参考。

在您的情况下,要解决问题,您应该在holder.jmlh_favorite.setText(status_favorite)内拨打getView()(例如,在某处存储位置和文字)。从displaylaporanList()您只需要调用notifyDataSetChanged()来通知适配器数据已被更改,列表项应该更新。另外,有关ListViews的详细信息,请参阅this session from Google I/O