【问题标题】:How to change or set subitems of a listview from AsyncTask?如何从 AsyncTask 更改或设置列表视图的子项?
【发布时间】:2015-01-04 15:38:56
【问题描述】:

在我的 MainActivity 中,我有一个列表视图,每行有两行文本。应用启动时只写第一行,第二行必须根据AsyncTask类处理的东西来写。当我尝试这样做时,列表视图的第一项会获取 AsyncTask 提供的所有值,因为我不明白如何为 each 更新 only 列表视图的第二行 item,无需重写整个列表视图。 每个 textView 在 xml 布局文件中都有自己的 id。如何在 onPostExecute() 中执行此操作? 代码如下:

在 MainActivity onCreate():

    final ListView listview = (ListView) findViewById(R.id.listview);

    final String[] values = new String[10];
    for(int i=0;i<10;i++){
        //do stuff to write the values[] elements

    }

    MySimpleArrayAdapter adapter = new MySimpleArrayAdapter(this, values);
    listview.setAdapter(adapter);

MySimpleArrayAdapter 类:

public class MySimpleArrayAdapter extends ArrayAdapter<String> {
  private final Context context;
  private final String[] values;
  int position=0;

  public MySimpleArrayAdapter(Context context, String[] values) {
    super(context, R.layout.list_layout, values);
    this.context = context;
    this.values = values;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.list_layout, parent, false);
    TextView firstLine = (TextView) rowView.findViewById(R.id.label);
    TextView secondLine = (TextView) rowView.findViewById(R.id.sublabel);

    firstLine.setText(values[position]);
    secondLine.setText(""); //I prefer to write an empty string for the secondLine

    return rowView;
  }
}

异步任务:

private class Process extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... params) {
        //do stuff
    }

    @Override
    protected void onPostExecute(String message) {
        TextView secondLine = (TextView) findViewById(R.id.sublabel);

        //This of course udpdates only the secondLine of the first item of listview
        secondLine.setText(processedValues);
    }
}

【问题讨论】:

  • 您需要执行AsyncTask 才能使其工作..
  • 是的,抱歉我忘了提。它以单击按钮的方法执行,但这不是我的问题的重点。

标签: java android listview android-listview android-asynctask


【解决方案1】:

将 TextView 作为参数传递给 AsyncTask,如下所示

private class Process extends AsyncTask<Void, Void, String> {
private WeakReference<TextView> weakTextView;
public Process(TextView textView){
       weakTextView = new WeakReference<TextView>(textView);
}
@Override
protected String doInBackground(Void... params) {
    //do stuff
}

@Override
protected void onPostExecute(String message) {
    TextView tv = weakTextView.get();
   if(tv!=null){
       tv.setText(message);
 }
}

}

您在getView 中将其称为

Process p = new Process(yourTextView);
p.execute();

//方法二

private class Process extends AsyncTask<TextView, Void, String> {

private WeakReference<TextView> weakTextView;

@Override
protected String doInBackground(TextView... params) {
    if(params == null||params.length=0){
         return null;
    }
    TextView tv = (TextView)params[0];
    weakTextView = new WeakReference<TextView>(tv);

    //do stuff
}

@Override
protected void onPostExecute(String message) {
    TextView tv = weakTextView.get();
   if(tv!=null){
       tv.setText(message);
 }
}

}

您在getView 中将其称为

Process p = new Process();
p.execute(yourTextView);  

//方法3

只需更新此列表适配器的下划线数据对象 并致电adapter.notifyDataSetChanged();
这将再次调用getView
在大多数情况下,此方法比上述其他 2 种方法更可取,除非您显示来自互联网的图像

【讨论】:

  • “更新下划线数据对象”是什么意思?我想我在一杯水中迷路了......
  • 我想问题是,为什么你需要一个异步任务来更新给定 textview 的内容?
  • 抱歉回复晚了,我一直很忙。我需要 AsyncTask 来做其他事情,最后它会更新列表视图的行。无论如何,经过几次尝试,我使用您的方法 3 解决了我的问题。关键是 adapter.notifyDataSetChanged() 确实非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多