【问题标题】:Update CustomArrayAdapter after AsyncTask in Android在 Android 中的 AsyncTask 之后更新 CustomArrayAdapter
【发布时间】:2014-09-18 13:31:15
【问题描述】:

我有一个 CustomArrayAdapter,我用它来更新一个自定义 ListView。

这很好,但是当我尝试更新视图时 在使用 notifyDataSetChanged 在 AsyncView onPostExecute 中获得结果后,它没有更新,也没有返回任何异常。

onCreate 的代码 -

public class MainActivity extends ListActivity {
    String[] presidents = {"Dwight D. Eisenhower","John F. Kennedy","Lyndon B. Johnson","Richard Nixon","Gerald Ford","Jimmy Carter","Ronald Reagan","George H. W. Bush","Bill Clinton","George W. Bush","Barack Obama"};
    String[] pics = {"5237","5438", "184", "184", "184", "184", "184", "184", "184", "184", "184", "184"};
    private String[] names;
    private String[] pid;   
    ListActivity obj;   
    CustomArrayAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); 
        obj = this;     
        try {
            adapter =new CustomArrayAdapter(obj, presidents, pics);
            setListAdapter(adapter);            
            new DownloadTextTask().execute("http://nvoids.com/rest/hello/users/");          
        } catch(Exception e) {
            Log.d("Listview1", "Exception: " + e.getLocalizedMessage());
        }

    }

AsyncTask 的 onPostExecute -

protected void onPostExecute(String result) {

  Toast.makeText(getBaseContext(), result.substring(1, 10) ,Toast.LENGTH_SHORT).show();         
  try 
    {               
        JSONArray jarr = new JSONArray(result);
         names = new String[jarr.length() -1];
         pid = new String[jarr.length() -1];
         for (int i =0; i< jarr.length(); i++) {
                JSONObject jObj = new JSONObject(jarr.get(i).toString());
                names[i] = jObj.getString("value");                 
                pid[i] = jObj.getString("pid");                 
            }
            super.onPostExecute(result);
            adapter =new CustomArrayAdapter(obj, names, pid);
            adapter.notifyDataSetChanged();
        } catch(Exception e) {
            Log.d("ListView1", "after getting string: " + e.getLocalizedMessage());
        }
    } 

顺便说一句,如果需要的话,CustomArrayAdapter 类 -

public class CustomArrayAdapter extends ArrayAdapter<String> {
private final Activity context;    
private final String[] presidents;    
private final String[] imageIds;

 public CustomArrayAdapter(Activity context,String[] presidents, String[] imageIds) {
    super(context, R.layout.lvrowlayout, presidents);
     this.context = context;
     this.presidents = presidents;
     this.imageIds = imageIds;
 }

 @Override    
 public View getView(int position, View view, ViewGroup parent) {
     //---print the index of the row to examine---        
     Log.d("Listview1",String.valueOf(position));

    LayoutInflater inflater = context.getLayoutInflater();
    View rowView= inflater.inflate(R.layout.lvrowlayout, null, true);

    TextView txtTitle = (TextView) rowView.findViewById(R.id.txtPresidentName);
    ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);

    txtTitle.setText(presidents[position]);

    //imageView.setImageResource(imageIds[position]);

    new DownloadImageTask((ImageView)  imageView )
    .execute("http://nvoids.com/dir/image_" + imageIds[position] + ".jpeg");


    return rowView;

 }

 private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
        ImageView bmImage;

        public DownloadImageTask(ImageView bmImage) {
            this.bmImage = bmImage;
        }

        protected Bitmap doInBackground(String... urls) {
            String urldisplay = urls[0];
            Log.d("CustomArrayGetImage Error", urldisplay);
            Bitmap mIcon11 = null;
            try {
                InputStream in = new java.net.URL(urldisplay).openStream();
                mIcon11 = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                Log.d("CustomArrayGetImage Error", e.getMessage());
                e.printStackTrace();
            }
            return mIcon11;
        }

        protected void onPostExecute(Bitmap result) {
            bmImage.setImageBitmap(result);
        }
    }    
 }

编辑 -

正如在答案中传递参数也不起作用 -

  try {
        adapter =new CustomArrayAdapter(obj, presidents, pics);         
        setListAdapter(adapter);            
        new DownloadTextTask(adapter).execute( "http://nvoids.com/rest/hello/users/");          
    } catch(Exception e) {
        Log.d("Listview1", "Exception: " + e.getLocalizedMessage());
    }

在 DownloadAsyncTask 中 -

   private class DownloadTextTask extends AsyncTask<String, Void, String> {
    CustomArrayAdapter ca;

    public DownloadTextTask(CustomArrayAdapter ca) {
        this.ca = ca;
    }

 ......

  protected void onPostExecute(String result) {
        //Toast.makeText(getBaseContext(), result, Toast.LENGTH_LONG).show();
        Toast.makeText(getBaseContext(), result.substring(1, 10) ,Toast.LENGTH_SHORT).show();           
        try 
        {               
            JSONArray jarr = new JSONArray(result);
            names = new String[jarr.length() -1];
            pid = new String[jarr.length() -1];
            for (int i =0; i< jarr.length(); i++) {
                JSONObject jObj = new JSONObject(jarr.get(i).toString());
                names[i] = jObj.getString("value");                 
                pid[i] = jObj.getString("pid");
                ca.addAll(names[i] , pid[i]);
            }
            /*
            super.onPostExecute(result);                
            adapter =new CustomArrayAdapter(obj, names, pid);               
            lv.setAdapter(adapter);             
            obj.setListAdapter(adapter);
            */

            ca.notifyDataSetChanged();
        } catch(Exception e) {
            Log.d("ListView1", "after getting string: " + e.getLocalizedMessage());
        }
    }

【问题讨论】:

    标签: android android-listview android-asynctask


    【解决方案1】:

    因为,您正在 AsyncTask 的 onPostExecute() 中创建自定义适配器的新对象

    喜欢,

    adapter =new CustomArrayAdapter(obj, names, pid);
    adapter.notifyDataSetChanged();
    

    未设置为ListView。因此,要么将setListAdapter() 的语法写入onPostExecute() 中的ListView(为此,您需要AsyncTask 中的ListView 参考)或 使用您在onCreate() 中创建的ListActivity 中相同的对象,将该适配器对象传递给AsyncTask 的构造函数并使用onPostExecute() 中的对象。

    【讨论】:

    • 是的,正是我写的(你太快了:))。要完成您的答案,您可以使用适配器的 add、insert、addAll 和/或 remove 方法插入您在 onPostExecute 方法中获得的数据。
    • 与构造函数也没有响应我已经编辑了问题。
    【解决方案2】:
    adapter =new CustomArrayAdapter(obj, names, pid);
    adapter.notifyDataSetChanged();
    

    notifyDataSetChange通知观察者更新数据。

    因此,在您的示例中,您通知 new 适配器更新其数据,但您没有将适配器附加到您的列表中。

    但是每次都创建新适配器 - 这不是一个好习惯,您必须更新适配器中的数据(在您的情况下为总统列表),然后在现有适配器上调用 notifyDataSetChange。

    PSArrayAdapter下面已经有一个列表,你可以打电话给add,不需要存储总统列表。在您的情况下,我认为最好创建

    class PresidentsWrapper { String name, String photoUrl }

    还有create ArrayAdapter&lt;PresidentWrapper&gt;

    在这种情况下,您不需要任何底层结构,可以这样做:

    getItem(position);
    add(new PresidentWrapper(...));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 2017-06-01
      • 1970-01-01
      • 2019-06-05
      • 2021-07-10
      相关资源
      最近更新 更多