#android #listview #baseadapter
#Android #listview #baseadapter
Вопрос:
Я использую библиотеку EnhancedListView от Тима Роса и использую пользовательский адаптер, расширяющий BaseAdapter.
Вот как я инициализирую свой ListView и адаптер:
public class FragmentProducts extends Fragment implements View.OnClickListener,
AdapterView.OnItemClickListener,
EnhancedListView.OnDismissCallback,
SearchView.OnQueryTextListener,
SearchView.OnCloseListener,
AbsListView.OnScrollListener{
public static final int SECTION_NUMBER = 9;
public static boolean isScrolling;
Button scanButton;
SearchView searchProducts;
EnhancedListView productsList;
ProductsAdapter dataAdapter;
List<Product> list;
OnProductSelectedListener mCallback;
static Product pp;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_products, container, false);
if (view != null) {
searchProducts = (SearchView) view.findViewById(R.id.search_product);
scanButton = (Button) view.findViewById(R.id.scanButton);
productsList = (EnhancedListView) view.findViewById(R.id.products_list);
searchProducts.setOnQueryTextListener(this);
scanButton.setOnClickListener(this);
productsList.setOnScrollListener(this);
productsList.setOnItemClickListener(this);
productsList.setDismissCallback(this);
productsList.enableSwipeToDismiss();
productsList.setRequireTouchBeforeDismiss(false);
list = new ArrayList<Product>();
dataAdapter = new ProductsAdapter(getActivity(), list);
productsList.setAdapter(dataAdapter);
populateList();
}
return view;
}
public void populateList() {
list.addAll(Product.getAll(getActivity()));
//Load the items from DataBase
dataAdapter.notifyDataSetChanged();
LogUtil.addCheckpoint(list.size() " items on the product list");
//The size of the list here is correct, but the adapter is not updating
}
И вот моя реализация адаптера:
public class ProductsAdapter extends BaseAdapter {
private Context context;
private List<Product> products;
private List<Product> copyOfProducts;
public ProductsAdapter(Context context, List<Product> products) {
super();
this.context = context;
this.products = new ArrayList<Product>();
this.products.addAll(products);
this.copyOfProducts = new ArrayList<Product>();
this.copyOfProducts.addAll(products);
}
@Override
public Object getItem(int i) {
return products.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public int getCount() {
int count = products.size();
LogUtil.addCheckpoint(count " items on the products adapter");
//Item count is always 0 here
return count;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
Boolean isScrolling = FragmentProducts.isScrolling;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.item_products, parent, false);
holder = new ViewHolder();
holder.productName = (TextView) convertView.findViewById(R.id.product_name);
holder.productBrand = (TextView) convertView.findViewById(R.id.product_brand);
holder.productPrice = (TextView) convertView.findViewById(R.id.product_price);
holder.productStock = (TextView) convertView.findViewById(R.id.product_stock);
holder.productImage = (ImageView) convertView.findViewById(R.id.product_image);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
Product item = products.get(position);
holder.position = position;
holder.productId = item.getId();
holder.productName.setText(item.getName());
holder.productBrand.setText(item.getBrand());
DecimalFormat form = new DecimalFormat("0.00");
holder.productPrice.setText("$" form.format(item.getPrice()));
holder.productStock.setText(String.valueOf(item.getStock()));
new AsyncTask<ViewHolder, Void, Bitmap>() {
private ViewHolder viewHolder;
@Override
protected Bitmap doInBackground(ViewHolder... viewHolders) {
viewHolder = viewHolders[0];
return ProductPic.getMainForProduct(context, viewHolder.productId);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (viewHolder.position == position)
viewHolder.productImage.setImageBitmap(bitmap);
}
}.execute(holder);
Animation animation;
if (isScrolling) {
animation = AnimationUtils.loadAnimation(context, R.anim.slide_from_right);
animation.setDuration(400);
convertView.startAnimation(animation);
}
return convertView;
}
public void filterProducts(String query) {
query = query.toLowerCase();
products.clear();
if (query.isEmpty()) {
products.addAll(copyOfProducts);
} else {
for (Product item : copyOfProducts)
{
if (item.getName().toLowerCase().contains(query)
|| item.getBrand().toLowerCase().contains(query)
|| item.getCode().contains(query)) {
if (!products.contains(item))
products.add(item);
}
}
}
notifyDataSetChanged();
}
static class ViewHolder {
TextView productName;
TextView productBrand;
TextView productPrice;
TextView productStock;
ImageView productImage;
int position;
int productId;
}
}
Есть идеи о том, чего мне не хватает?
Ответ №1:
Проверьте значение высоты listview.
Комментарии:
1. если это wrap_content измените его на фиксированное значение или match_parent
2. Спасибо за предложение, но для него уже установлено значение match_parent
3. list = new ArrayList<Product>(); DataAdapter = new ProductsAdapter(getActivity(), список); на данный момент ваш список пуст, поэтому счетчик возвращается как 0. После list.addAll() снова назначьте свой адаптер.
4. Я знаю, что в начале список пуст, но именно поэтому я звоню
dataAdapter.notifyDataSetChanged();
, хотя ваше предложение может работать нормально для короткого набора данных, когда у меня много элементов, производительность просто ужасна. В любом случае спасибо
Ответ №2:
Наконец-то понял это!
В конструкторе адаптера у меня было это:
public ProductsAdapter(Context context, List<Product> products) {
super();
this.context = context;
this.products = new ArrayList<Product>();
this.products.addAll(products);
this.copyOfProducts = new ArrayList<Product>();
this.copyOfProducts.addAll(products);
}
И изменил его на:
public ProductsAdapter(Context context, List<Product> products) {
super();
this.context = context;
this.products = products; //<- This is where the error was
copyOfProducts = new ArrayList<Product>();
}
Я инициализировал список в начале, добавив свой исходный список, вместо того, чтобы ссылаться на него, конечно, когда я изменил свой исходный список, адаптер не заметил этого, потому что список, который я создал в конструкторе, никогда не менялся.
Изменив
this.products = new ArrayList<Product>();
this.products.addAll(products);
с
this.products = products;
Я заставил ListView работать.
Я надеюсь, что это поможет другим, сталкивающимся с подобными проблемами.