【问题标题】:Keep the correct value item in a listview using AsyncTask使用 AsyncTask 在列表视图中保留正确的值项
【发布时间】:2014-10-10 13:52:46
【问题描述】:

我是使用 android 的新手,当我尝试显示图像列表以及每个图像的按钮时遇到了问题。按下按钮时的事件是显示图像的 url。因此,当我在屏幕上滚动时,显示的新图像在按下按钮时具有不同的 url。这些值与在屏幕上滚动之前显示的第一张图像匹配。

我的主要代码如下:

public class ImagenesAdapter extends BaseAdapter{
private Context mContext;
private Map<String,?> mListImagenes;

static class ViewHolder{
    public Button buttonHolder;
    public ImageView imageviewHolder;
    int position;
}

public ImagenesAdapter(Context c, Map<String,?> list) {
    mContext = c;
    mListImagenes = list;
}

@Override
public int getCount() {
    return mListImagenes.size();
}

@Override
public Object getItem(int position) {
    return mListImagenes.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // reference to convertView
    View v = convertView;
    ViewHolder viewHolder=null;
    final int posicion=position;

    // inflate new layout if null
    if(v == null) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        v = inflater.inflate(R.layout.activity_listado_imagenes_subidas, null);

        //configure view holder
        viewHolder = new ViewHolder();
        viewHolder.buttonHolder = (Button)v.findViewById(R.id.btnCopiarImagenUrl);
        viewHolder.imageviewHolder = (ImageView)v.findViewById(R.id.imagen);
        viewHolder.buttonHolder.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                CopiarImagenListado(posicion);
                Toast.makeText(mContext, "Imagen copiada", Toast.LENGTH_SHORT).show();
            }
        });
        v.setTag(viewHolder);
    }
    else {
        viewHolder = (ViewHolder)v.getTag();
    }

    SharedPreferences prefsTH = mContext.getSharedPreferences("PrefsTH", ListadoImagenesSubidasMain.MODE_PRIVATE);

    String cadenaURL="";
    String sp = prefsTH.getString("urlTH"+position, "");
    if (sp != "")
    {
        cadenaURL = sp;

        if ((viewHolder.imageviewHolder != null) && (cadenaURL != "")){
            viewHolder.position = position;
            new DownloadAsyncTask(viewHolder, position).execute(cadenaURL);
        }
    }
    return v;
}

private class DownloadAsyncTask extends AsyncTask<String, Void, String>{
    private ProgressDialog dialog = new ProgressDialog(mContext);
    private ViewHolder mHolder;
    private int mPosition;

    public DownloadAsyncTask(ViewHolder holder, int position){
        this.mHolder = holder;
        this.mPosition = position;
    }

    protected void onPreExecute(){
        dialog.setMessage("Cargando imágenes...");
        dialog.show();
    }

    @Override
    protected String doInBackground(String... params) {
        String url = params[0];

        return url;
    }

    protected void onPostExecute(String result) {
        if (dialog.isShowing()) {
            dialog.dismiss();
        }

        if (result != null && mPosition == mHolder.position){
            mHolder.buttonHolder.setText("Copiar");

            Picasso.with(mContext)
            .load(result)
            .into(mHolder.imageviewHolder);
        }

    }

private void CopiarImagenListado(int position){
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
    prefs = PreferenceManager.getDefaultSharedPreferences(mContext);

    String cadenaURL="";
    String sp = prefs.getString("url"+position, "");
    if (sp != "")
    {
        cadenaURL = sp;
        ClipboardManager clipboard = (ClipboardManager)mContext.getSystemService(mContext.CLIPBOARD_SERVICE); 
        ClipData clip = ClipData.newPlainText("Imagen copiada", sp);
        clipboard.setPrimaryClip(clip);
    }
}

在列表视图中显示新图像时,我必须怎么做才能不丢失新数据?

先谢谢你了。

【问题讨论】:

    标签: android listview android-asynctask picasso


    【解决方案1】:

    你可以试试这个:

    // inflate new layout if null
    if(v == null)
    {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        v = inflater.inflate(R.layout.activity_listado_imagenes_subidas, null);
    
        //configure view holder
        viewHolder = new ViewHolder();
        viewHolder.buttonHolder = (Button)v.findViewById(R.id.btnCopiarImagenUrl);
        viewHolder.imageviewHolder = (ImageView)v.findViewById(R.id.imagen);
        v.setTag(viewHolder);
    }
    else
    {
        viewHolder = (ViewHolder)v.getTag();
    }
    
    viewHolder.buttonHolder.setOnClickListener(new OnClickListener()
    {
        @Override
        public void onClick(View v) {
            CopiarImagenListado(posicion);
            Toast.makeText(mContext, "Imagen copiada", Toast.LENGTH_SHORT).show();
        }
    });
    

    即使视图被回收,你也必须重新定义onClick,因为涉及到posicion。

    【讨论】:

      【解决方案2】:

      可以将位置添加为按钮的标签,然后在onClickListener中读取:

      viewHolder.buttonHolder.setTag(posicion);
      viewHolder.buttonHolder.setOnClickListener(new OnClickListener() {
      
                  @Override
                  public void onClick(View v) {
                      CopiarImagenListado((Integer)v.getTag());
                      Toast.makeText(mContext, "Imagen copiada", Toast.LENGTH_SHORT).show();
                  }
              });
      

      【讨论】:

      • 就是这样。为什么使用 setTag 来分配项目在列表视图中的位置是一个不错的选择?我的意思是程序如何知道在 Asyntask 类的 postexecute 中必须解决什么位置?
      • 这样,当您滚动按钮时,始终知道它与列表中的哪个项目相关联。否则,您之前使用的方式会导致图像 URL 不匹配。
      • 使用此代码时,有时当我按下图像的按钮时,URL 是错误的。有时该值是正确的,但随机地,有时当我在屏幕上滚动时,我得到一个错误的 url。
      • 您能否也发布此方法的代码:CopiarImagenListado
      猜你喜欢
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2013-03-01
      • 2013-07-17
      • 2014-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多