[英]listview is repeating items in customadapter
我正在學習android,我的代碼運行正常。 它從網站獲取數據並將其顯示在列表中。 但是當subcat==1
它有9個要提取的項目。 它顯示7個不同的項目並重復兩個項目。 首先,它只顯示四個,即NullPointerException,第5張圖像沒有名稱,因此它重復了4張圖像,直到9次,但現在一切都很好,它只顯示了7張,然后重復了2張。 這是我的代碼:
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
?
請幫忙。 我自己想不通。 這兩個問題使我無法學習更多。
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);
holder.name.setText(list1.get(position).getName());
holder.price.setText((CharSequence) list1.get(position).getPrice());
holder.img.setImageBitmap(list1.get(position).getImage());
}
else {
holder = (ViewHolder) v.getTag();
}
return v;
}
對於懶惰的圖像加載,你需要創建AsyncTask
為每個圖像不是AsyncTask
對所有圖像(dwonload逐一分離狀態AsyncTasks
)。
我建議您使用這些庫之一:
這是4個庫之間的基於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)。
是的,它會等待,因為圖像加載器異步任務遍歷所有位圖並下載它們,然后通知列表視圖進行繪制,您可以使異步任務一次僅加載一個圖像。 但我建議您使用像Picasso或Glide這樣的圖像加載器。
如果您不使用適配器,請在適配器中也使用其設計模式。
即使在創建列表后在后台加載圖像並在加載時刷新它,從用戶體驗角度來看,這也不是您要面對的問題,但效果更好。
我認為問題出在自定義適配器中的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。要么更改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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.