Порядок строк в Listview изменяется случайно при прокрутке списка в android
У меня есть один ListView и один BaseAdapter. Я загружаю продукты из webservice и показываю в listview.It отображается правильно в listview.
Но когда я просматриваю ListView, отображает строки в случайном положении, значит иногда отображается третий ряд в первой позиции, в средней строке строки отображается последняя позиция и т.д.
Это мой класс адаптера
public class ProductListAdapter extends BaseAdapter implements OnClickListener{
LayoutInflater inflater;
ArrayList<Product> arrProducts;
Context c;
public ProductListAdapter(Context c, ArrayList<Product> arrProducts) {
super();
inflater = LayoutInflater.from(c);
this.arrProducts = arrProducts;
this.c = c;
}
@Override
public int getCount() {
return arrProducts.size();
}
@Override
public Object getItem(int position) {
return arrProducts.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View v, ViewGroup parent) {
Product product = null;
if(v == null) {
v = inflater.inflate(R.layout.product_listview_row, null);
product = (Product) getItem(position);
v.setTag(product);
}else {
product = (Product)v.getTag();
}
v.setOnClickListener(this);
TextView tvProductname = (TextView)v.findViewById(R.id.tvProductname);
tvProductname.setText(product.getTitle());
String strReviewCount = product.getReviews();
TextView tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews);
if(strReviewCount != null) tvReviewsCounts.setText(strReviewCount +" Reviews");
Button btnPrice = (Button)v.findViewById(R.id.btnPrice);
btnPrice.setText(product.getSellingPrice());
return v;
}
@Override
public void onClick(View v) {
Product product = (Product) v.getTag();
Intent i = new Intent(c, ProductDetails.class);
i.putExtra(Product.PROD_ID, product.getId());
startActivity(i);
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
@Override
public int getViewTypeCount() {
return super.getViewTypeCount();
}
}
Это представление ListView в формате XML
<ListView android:id="@+id/lstProducts" style="@style/fill_parent"
android:dividerHeight="1dp" android:divider="#dbd3c5"
android:scrollbars="vertical" android:layout_below="@id/layLine"></ListView>
Также, когда я изменяю метод getView()
BaseAdapter, как это, он работает нормально
@Override
public View getView(int position, View v, ViewGroup parent) {
Product product = null;
v = inflater.inflate(R.layout.product_listview_row, null);
product = (Product) getItem(position);
v.setTag(product);
v.setOnClickListener(this);
TextView tvProductname = (TextView)v.findViewById(R.id.tvProductname);
tvProductname.setText(product.getTitle());
String strReviewCount = product.getReviews();
TextView tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews);
if(strReviewCount != null) tvReviewsCounts.setText(strReviewCount +" Reviews");
Button btnPrice = (Button)v.findViewById(R.id.btnPrice);
btnPrice.setText(product.getSellingPrice());
return v;
}
Но проблема в этом типе - я показываю изображение продукта в строке списка, которое я не рассматривал здесь. Используя этот тип кода getView()
, метод всегда создает новый вид, когда когда-либо прокручивается listView так что мне нужно загружать изображение снова и снова. Я использовал класс ImageLoader
, который использует cash memory
для загрузки изображений, но проблема в том, что когда я многократно устанавливал изображение в ImageView, это давало мне out of memory error
.
Пожалуйста, помогите мне решить эту проблему.
Спасибо
Ответы
Ответ 1
Я приземлился здесь из-за ссылки на правильное решение.
Проблема заключается в том, что вы связываете свой продукт один раз с представлением при создании нового представления. Вы должны вызывать это при каждом вызове getView
:
product = (Product) getItem(position);
v.setTag(product);
Но вы могли бы вызвать v.setOnClickListener(this)
после создания представления (оно все равно не изменится).
Это должно сделать трюк. Реализация типа вида просто неправильно используется здесь. Я рекомендую прочитать мой ответ здесь...
Ответ 2
Следовательно, согласно рекомендациям, сделанным Knickedi, метод getView()
должен выглядеть как:
public View getView(int position, View v, ViewGroup parent) {
TextView tvProductname;
TextView tvReviewsCounts;
Button btnPrice;
// Phase 1...
if (v == null) {
v = inflater.inflate(R.layout.product_listview_row, null);
v.setOnClickListener(this);
tvProductname = (TextView)v.findViewById(R.id.tvProductname);
tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews);
btnPrice = (Button)v.findViewById(R.id.btnPrice);
v.setTag(R.id.tvProductname, tvProductname);
v.setTag(R.id.tvReviews, tvReviewsCounts);
v.setTag(R.id.btnPrice, btnPrice);
}
else {
tvProductname = (TextView) v.getTag(R.id.tvProductname);
tvReviewsCounts = (TextView) v.getTag(R.id.tvReviews);
btnPrice = (Button) v.getTag(R.id.btnPrice);
}
// Phase 2...
Product product = (Product) getItem(position);
tvProductname.setText(product.getTitle());
btnPrice.setText(product.getSellingPrice());
String strReviewCount = product.getReviews();
if(strReviewCount != null)
tvReviewsCounts.setText(strReviewCount +" Reviews");
return v;
}