ListView не показывает никаких данных

#android #listview #baseadapter

#Android #listview #baseadapter

Вопрос:

Я использую библиотеку EnhancedListView от Тима Роса и использую пользовательский адаптер, расширяющий BaseAdapter.

Моя проблема в том, что я не могу заставить ListView отображать какие-либо данные, и я считаю, что это связано с тем, что notifyDataSetChanged() не работает.

Вот как я инициализирую свой 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 работать.

Я надеюсь, что это поможет другим, сталкивающимся с подобными проблемами.