嘿伙计们我正在尝试使用文本和图像创建自定义列表视图,其中图像来自网址。我试图与我的列表项异步显示它们。但是当我向下滚动列表时,列表项中的图像会发生变化,而错误的图像会显示在列表项中。以下是我的代码段:
CustomList.java 下, 这是我的基础适配器
public class CustomList extends BaseAdapter {
//private ArrayList listData;
private LayoutInflater layoutInflater;
private ArrayList<ListItem> listData;
public CustomList(Context context,ArrayList<ListItem> listData)
{
//Toast.makeText(History.this,"hey",Toast.LENGTH_LONG).show();
this.listData = listData;
layoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
Log.e("mysize",String.valueOf(listData.size()));
return listData.size();
}
@Override
public Object getItem(int position) {
return listData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView,ViewGroup parent)
{
ViewHolder holder;
if(convertView == null)
{
convertView = layoutInflater.inflate(R.layout.history_row,null);
holder = new ViewHolder();
holder.so = (TextView)convertView.findViewById(R.id.SO);
holder.name = (TextView)convertView.findViewById(R.id.Name);
holder.process = (ImageView)convertView.findViewById(R.id.Process);
holder.cloth = (ImageView)convertView.findViewById(R.id.Cloth);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
ListItem data = (ListItem)listData.get(position);
holder.so.setText(data.getSo());
if(data.getProcess().equals("0"))
{
holder.process.setImageResource(R.drawable.tick);
}
else
holder.process.setImageResource(android.R.drawable.ic_delete);
if(holder.cloth !=null)
{
holder.name.setText(data.getName());
Log.e("urlsss",data.getUrl()+ data.getName());
new ImageDownload(holder.cloth).execute(data.getUrl());
}
return convertView;
}
static class ViewHolder
{
TextView so;
TextView name;
ImageView process;
ImageView cloth;
}
}
用于下载图片的ImageDownload.class
public class ImageDownload extends AsyncTask<String,Void,Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public ImageDownload(ImageView imageView)
{
imageViewReference = new WeakReference<ImageView>(imageView);
}
protected Bitmap doInBackground(String... params)
{
RequestHandler rh = new RequestHandler();
return rh.downloadBitmap(params[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
Drawable placeholder = imageView.getContext().getResources().getDrawable(android.R.drawable.star_on);
imageView.setImageDrawable(placeholder);
}
}
}
}
}
为listView中的每一行生成数据的ListItem.java
public class ListItem {
private String so,name,process,imgUrl;
public void setSo(String so)
{
this.so = so;
}
public void setName(String name)
{
this.name = name;
}
public void setProcess(String process)
{
this.process = process;
}
public void setUrl(String url)
{
this.imgUrl = url;
}
public String getSo()
{
return so;
}
public String getName()
{
return name;
}
public String getProcess()
{
return process;
}
public String getUrl()
{
return imgUrl; }
}
这是我调用自定义适配器的主要活动
public class History extends AppCompatActivity {
//url to fetch data from
public static final String URL_HISTORY = "http://192.168.1.233/vendor/history.php";
//Json tags
public static final String TAG_JSON_ARRAY="result";
public static final String TAG_SO = "SO";
public static final String TAG_NAME = "CustomerName";
public static final String TAG_DESC = "ClothDescription";
public static final String TAG_DATE = "DeliveryDate";
public static final String TAG_PRODUCT_TYPE = "ProductType";
public static final String TAG_PRODUCT_DESC = "ProductDescription";
public static final String TAG_IMAGE_URL = "ImageUrl";
public static final String TAG_PROCESS = "Process";
HashMap<String,String> data = new HashMap<>();
ArrayList<ListItem> detail_list;
ListView listView;
//key to put in hashmap
public static final String VENDOR_NAME = "Username";
//to store fetched data
String[] so;
String[] customerName;
String[] clothesDesc;
String[] delivDate;
String[] prodType;
String[] prodDesc;
String[] imgUrl;
String[] process;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
listView =(ListView)findViewById(R.id.listView);
detail_list = new ArrayList<ListItem>();
//to get vendorname
SharedPreferences sharedPref = getSharedPreferences("vendorInfo", Context.MODE_PRIVATE);
String vendor_name =sharedPref.getString("username", "");
data.put(VENDOR_NAME, vendor_name);
fetchHistory();
}
public void fetchHistory()
{
class FetchHistory extends AsyncTask<Void,Void,String>
{
ProgressDialog loading;
protected void onPreExecute()
{
super.onPreExecute();
loading = ProgressDialog.show(History.this,"Fetching...","Wait",false,false);
}
protected String doInBackground(Void...params)
{
RequestHandler rh = new RequestHandler();
String result = rh.sendPostRequest(URL_HISTORY, data);
return result;
}
protected void onPostExecute(String s)
{
super.onPostExecute(s);
loading.dismiss();
Log.e("myjson",s);
showHistory(s);
}
}
FetchHistory fh = new FetchHistory();
fh.execute();
}
public void showHistory(String json)
{
try {
JSONObject jsonObject = new JSONObject(json);
JSONArray result = jsonObject.getJSONArray(TAG_JSON_ARRAY);
int length = result.length();
so = new String[length];
customerName = new String[length];
clothesDesc = new String[length];
delivDate = new String[length];
prodType = new String[length];
prodDesc = new String[length];
imgUrl = new String[length];
process = new String[length];
for (int i = 0; i < result.length(); i++) {
JSONObject c = result.getJSONObject(i);
so[i] = c.getString(TAG_SO);
customerName[i] = c.getString(TAG_NAME);
clothesDesc[i] = c.getString(TAG_DESC);
delivDate[i] = c.getString(TAG_DATE);
prodType[i] = c.getString(TAG_PRODUCT_TYPE);
prodDesc[i] = c.getString(TAG_PRODUCT_DESC);
imgUrl[i] = c.getString(TAG_IMAGE_URL);
process[i] = c.getString(TAG_PROCESS);
}
}
catch(JSONException e)
{
Log.e("myexception",e.toString());
}
for(int i =0;i<customerName.length;i++)
{
//storing all value in hashmap
ListItem values = new ListItem();
values.setSo(so[i]);
values.setName(customerName[i]);
values.setUrl(imgUrl[i]);
Log.e("myurl", imgUrl[i]);
values.setProcess(process[i]);
detail_list.add(values);
}
Toast.makeText(this,"hey",Toast.LENGTH_LONG).show();
Log.e("hey", "hey00");
CustomList customList = new CustomList(this,detail_list);
listView.setAdapter(customList);
Toast.makeText(this,"you",Toast.LENGTH_LONG).show();
Log.e("you", "you00");
}
}
每行的布局文件是
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/linear">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/SO"
android:layout_marginRight="10dp"
android:layout_weight="2" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/Name"
android:layout_marginRight="10dp"
android:layout_weight="2" />
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/Process"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/Cloth"
android:layout_weight="1"
android:scaleType="fitXY" />
</LinearLayout>
</LinearLayout>
答案 0 :(得分:0)
这是一个常见的错误。您的listView会回收视图,因此不会为listView中的100个项目创建视图,而是创建足够的视图来填充屏幕。
向下滚动时,用于位置#1的ImageView现在与用于位置#11和#21的ImageView相同,依此类推......
此修复程序需要跟踪当前正在向用户显示的位置,并且仅设置这些位置的图像,并在其从屏幕上掉落时清除关联的图像视图(或取消挂起的下载)。
你可以弄清楚你的imageView何时被重新分配,因为它将再次在getView中被调用,你可以从中找出是否有需要取消的待处理下载。
考虑使用其中一个现有解决方案,或者只是查看其他人如何完成它的完整示例。 https://github.com/nostra13/Android-Universal-Image-Loader