2015-08-20 62 views
0

我正在学习android和我的代码工作正常。它从网站提取数据并将其显示在列表中。但是当subcat==1它有9个项目要获取。它显示7个不同的项目并重复两个项目。首先它只显示了四个是NullPointerException第五个图像没有名称,所以它重复4次图像直到9次,但现在一切都很好,但它仍然只显示7,然后重复2次。这里是我的代码:listview在customadapter中重复项目

public class JSONAsyncTask extends AsyncTask<String, Void, Void> { 
    ProgressDialog pd; 
    Context context; 


    JSONAsyncTask(Context context) { 
     this.context = context; 
    } 

    @Override 
    protected void onPreExecute() { 

     super.onPreExecute(); 
     pd = new ProgressDialog(context); 
     pd.setIndeterminate(true); 
     pd.setCancelable(false); 
     pd.setCanceledOnTouchOutside(false); 
     pd.setMessage("Please wait..\nLoading data"); 
     pd.show(); 
    } 

    @Override 
    protected Void doInBackground(String... strings) { 
     ArrayList<item> jsonArrayList = new ArrayList<item>(); 
     try { 
      HttpClient client = new DefaultHttpClient(); 
      HttpGet httpget = new HttpGet("http://avdeal.in/get_all_products.php"); 
      HttpResponse response = client.execute(httpget); 
      HttpEntity entity = response.getEntity(); 
      String data = EntityUtils.toString(entity); 
      JSONObject jsonObject = new JSONObject(data); 
      if (jsonObject != null) { 
       String posts = jsonObject.getString("products"); 
       JSONArray postsArray = new JSONArray(posts); 
       if (postsArray != null) { 
        if (postsArray.length() > 0) { 
         for (int i = 0; i < postsArray.length(); i++) { 
          JSONObject postsObject = postsArray 
            .getJSONObject(i); 
          int subcat = postsObject.getInt("subcat_id"); 

          if (subcats == subcat) { 
           int id=postsObject.getInt("id"); 
           String title = postsObject.getString("product_title"); 
           String price = postsObject.getString("product_price"); 
           String url = "http://avdeal.in/seller/upload_images/" + postsObject.getString("product_url"); 


           list1.add(new item(id, title, price, url)); 
          } 

         } 
        } 


       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 

     super.onPostExecute(result); 
     if (list1 != null) { 
      pd.dismiss(); 
      adp = new actorAdapter(context, R.layout.listview, list1); 
      lv.setAdapter(adp); 
      adp.notifyDataSetChanged(); 
     } 
     else { 
      pd.setMessage("No internet access"); 
     } 
     lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
       Toast.makeText(itemView.this, "Please Wait " + i + 1, Toast.LENGTH_SHORT).show(); 
       int id1 = list1.get(i).getId(); 
       String name = list1.get(i).getName(); 
       String price = list1.get(i).getPrice(); 
       Bitmap bitmap = list1.get(i).getImage(); 

       if (bitmap == null) { 
        Intent intent = new Intent(context, productDetail.class); 
        intent.putExtra("name", name); 
        intent.putExtra("price", price); 
        intent.putExtra("id", id1); 
        intent.putExtra("imagena", 1); 
        startActivity(intent); 
       } else { 
        ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); 
        byte[] byteArray = stream.toByteArray(); 
        Intent intent = new Intent(context, productDetail.class); 
        intent.putExtra("name", name); 
        intent.putExtra("price", price); 
        intent.putExtra("image", byteArray); 
        intent.putExtra("id", id1); 
        startActivity(intent); 
       } 
      } 
     }); 
    } 
} 

private class ImageLoadTask extends AsyncTask<String, String, Bitmap>{ 
      Context context; 
     ImageLoadTask(Context context) { 
      this.context = context; 
     } 
     @Override 
     protected Bitmap doInBackground(String... strings) { 
      for(int i = 0 ; i < list1.size() ; i++) 
      { 
       if (list1.get(i).getImage()==null); 
       { 
        String url=list1.get(i).getUrl(); 
        InputStream is = null; 
        try { 
         is = (InputStream) new URL(url).getContent(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        Bitmap b = BitmapFactory.decodeStream(is); 
        list1.set(i, new item(list1.get(i).getId(), list1.get(i).getName(), list1.get(i).getPrice(), list1.get(i).getUrl() ,b)); 
       } 
      } 
       return null; 

    } 

     @Override 
     protected void onProgressUpdate(String... values) { 
      super.onProgressUpdate(values); 

     } 
     protected void onPostExecute(Bitmap result){ 
       super.onPostExecute(result); 
       adp = new actorAdapter(context, R.layout.listview, list1); 
       lv.setAdapter(adp); 
       adp.notifyDataSetChanged(); 
     } 
    } 

我可以做任何事情来延迟加载图像吗?我试图创建另一个AsyncTask,但它显示所有图像加载时的图像。

只要下载一张图像,我可以更新我的ListView吗?

请帮忙。无法自己弄清楚。这两个问题阻止我学习更多。

​​3210

回答

1

对于惰性图像加载,您需要为每张图像创建一个AsyncTask而不是所有图像的AsyncTask(在分开的AsyncTasks中逐个加载它们)。

我建议你使用这些库之一:

这是4个库(从here),它可以帮助你选择之间基于的opinon对比表:

编辑:

为了您的重复项目,变更你的getView方法是这样的:

public View getView(int position, View convertView, ViewGroup parent){ 
    inflater= (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE); 
    View v =convertView; 
    if (v == null) { 

     holder=new ViewHolder(); 
     v=inflater.inflate(Resource,null); 
     holder.name= (TextView) v.findViewById(R.id.titles); 
     holder.price= (TextView) v.findViewById(R.id.price); 
     holder.img= (ImageView) v.findViewById(R.id.itemimage); 
     v.setTag(holder); 
    } 
    else { 
     holder = (ViewHolder) v.getTag(); 
    } 

     holder.name.setText(list1.get(position).getName()); 
     holder.price.setText((CharSequence) list1.get(position).getPrice()); 
     holder.img.setImageBitmap(list1.get(position).getImage());  

    return v; 
} 

你忘了你当您使用回收视图(v!= null)时更新项目数据。

+0

重复列表? – Shashank

+0

您的AsyncTask代码看起来不错,发布您的适配器代码... – Rami

+0

是啊,现在工作。你可以告诉我如何为每个图像调用异步。当我从主线程调用它时。它强制停止,我试图保持主线程中的第一个异步并调用另一个中的每个图像异步它不加载任何东西,并捕获异常。告诉我如何实现,而不使用第三方库 – Shashank

0

是的,它会等待,因为你的图像加载器异步任务遍历所有的位图和下载然后他们通知列表视图中绘制,您可以在同一时间进行异步任务只加载一个图像。 但我建议你使用像毕加索或Glide的图像加载器。

另外,在您的适配器中,如果您不使用它,请使用视图设计模式。

+0

我使用viewholder和其工作正常。如果图像== null,我已经从布局设置了一个默认图像。首先我需要解决重复的图像,然后我将重点放在效率和延迟 – Shashank

0

即使在创建列表并在加载后刷新它时加载图像在后台加载图像更好,但在用户体验方面更好,这不是您所面临的问题。

我认为这个问题是在您的自定义适配器的getView方法,如果你提供给它,我们就能够知道。问题是,你可能检查某个位置上的某个物体的图像是否有图片,如果有的话 - 设置它。大概就像这样:

public View getView (int position, View convertView, ViewGroup parent) 
{ 
    //some code to create the views and view holder.. 

    YourItem currentItem = mItems.get(position); 
    if (currentItem.getBitmap() != null) 
    { 

     imageView.setImageBitmap(currentItem.getBitmap()); 
    } 

    //rest of code 
} 

你应该做的,因为从最后创建视角的图片也会增加一个else子句仍然是填充改变ImageView.Either的ImageView的可见性或它的位图。

编辑:
它应该是这个样子:

public View getView (int position, View convertView, ViewGroup parent) 
{ 
    //some code to create the views and view holder.. 

    YourItem currentItem = mItems.get(position); 
    if (currentItem.getBitmap() != null) 
    { 
     imageView.setVisibility(View.VISIBLE); 
     imageView.setImageBitmap(currentItem.getBitmap()); 
    } 
    else 
    { 
     imageView.setVisibility(View.INVISIBLE); 
    } 

    //rest of code 
} 
+0

这是困扰我的东西。代码是正确的,logcat只显示无用的日志。没有例外没有错误。 – Shashank

+0

我不认为你明白我的意思。您需要添加else子句并设置imageView可见性。看到我编辑的消息。 –