5

我正在使用列表视图的自定义适配器来显示图像和标题。在我的应用程序中,我添加和删除列表中的项目,我必须在界面上显示更改。在数据发生任何变化时,我从数据库中获取所有列表并将其存储在适配器列表中,然后调用 adapter.notifyDataSetChanged(); 但界面没有显示任何变化。另一方面,当我直接从适配器添加或删除项目时,它会正确响应。我使用了简单的适配器,并为此适配器.notifyDataSetChanged(); 工作正常,但对于定制它没有响应。我还在stackoverflow上尝试了许多解决方案,但没有一个有效。比如 当适配器数据改变时更新列表视图

Android 列表视图刷新

Adapter.notifyDataSetChanged() 不工作

notifyDataSetChange 不适用于自定义适配器

我在 oncreate 这样做

enter code here

            product_data = new ArrayList<Product>();
    Bundle extras = getIntent().getExtras();
    if (extras != null) {
        value = extras.getInt("list_id");
    }
    product_data = db.getAllProductsstatus(value, 1);
    Collections.reverse(product_data);

    adapter = new ProductAdopter(this, 
            R.layout.listview_item_row, product_data, 2);
    ListView listView1 = (ListView)findViewById(R.id.listView1);
    listView1.setAdapter(adapter);
    registerForContextMenu(listView1);

并在 onMenuItemSelected

enter code here
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();

      int menuItemIndex = item.getItemId();
      String listItemName = adapter.getItem(info.position)._name;
      int id = adapter.getItem(info.position)._id;

         if(menuItemIndex == 0)
        {

            db.deleteProduct(adapter.getItem(info.position));

            product_data = db.getAllProducts(value);
            Collections.reverse(product_data);
            //adapter.remove(adapter.getItem(info.position));
            adapter.notifyDataSetChanged();
        }
        else if(menuItemIndex == 1){
            String name ;
            if (adapter.getItem(info.position)._status == 0){
                popall("bar code", "no bar code entered");                  
            }
            else {
            popall("bar code", adapter.getItem(info.position)._bar_code);
            }
        }
        else if (menuItemIndex == 2){
            adapter.getItem(info.position)._status = 0;
            adapter.getItem(info.position)._bar_code = "0";
            db.updateProduct(adapter.getItem(info.position));
                product_data = db.getAllProductsstatus(value, 1);
            adapter.notifyDataSetChanged();

            popall("alert", "successfully done");
        }
      return true;
}

我的自定义适配器类如下

public class ProductAdopter extends ArrayAdapter<Product> {
    Context context; 
    int layoutResourceId;    
    List<Product> data = null;
    int source;
    public ProductAdopter(Context context, int layoutResourceId, List<Product> product_data, int source) {
        // TODO Auto-generated constructor stub
        super(context, layoutResourceId, product_data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = product_data;
        this.source = source;
    }
   // public ProductAdopter(MainActivity context2, int listviewItemRow, List<Product> product_data) {
        // TODO Auto-generated constructor stub
    //}
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        ProductHolder holder = null;

        if(row == null && source == 1)
        {
            LayoutInflater inflater = ((MainActivity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new ProductHolder();
            holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
            holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);

            row.setTag(holder);
        }
        if(row == null && source == 2)
        {
            LayoutInflater inflater = ((purchased)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new ProductHolder();
            holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
            holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);

            row.setTag(holder);
        }
        if(row == null && source == 3)
        {
            LayoutInflater inflater = ((Skiped)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new ProductHolder();
            holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
            holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);

            row.setTag(holder);
        }


        else
        {
            holder = (ProductHolder)row.getTag();
        }

        Product product = data.get(position);
        holder.txtTitle.setText(product.getName());
        if(product.icon.equals("no")){
            holder.imgIcon.setImageResource(R.drawable.blank);
        }
        else{
            File imgFile = new  File(product.icon);
            if(imgFile.exists()){

                Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
                Bitmap resized = Bitmap.createScaledBitmap(myBitmap, 70, 70, true);

                holder.imgIcon.setImageBitmap(resized); 
                myBitmap.recycle();
            }           
        }

        return row;
    }
    static class ProductHolder
    {
        ImageView imgIcon;
        TextView txtTitle;
    }

}
4

2 回答 2

10

问题是在你的onMenuItemSelected()你有这条线:

product_data = db.getAllProducts(value);

当您在 中创建适配器时onCreate(),您给了它一个对product_data. 那时您的更改product_data将传播到适配器中,因为它引用了您的列表。

但是,一旦您将一个新列表分配给您的product_data变量(就像您在 中所做的那样onMenuItemSelected()),适配器现在就会引用旧列表,而您的product_datanow 指向一个新列表。因此,您的适配器不知道您在新列表中所做的更改。

不要重新分配变量,而是尝试清除它并复制您的项目,如下所示:

product_data.clear();
product_data.addAll(db.getAllProducts(value));

另一方面,如果您从数据库中读取数据,则应考虑使用 aCursorAdapter代替。

这是一个简单的教程: http: //blog.cluepusher.dk/2009/11/16/creating-a-custom-cursoradapter-for-android/

于 2013-04-29T17:15:30.827 回答
0

您的代码中的问题是,您正在通知您的适配器刷新列表,但您没有向 (I.e after add/remove items.)它提供新数据。

执行以下操作:

    if(menuItemIndex == 0) { db.deleteProduct(adapter . Get item(info.position)); product_data = db.getAllProducts(value); 
    Collections.reverse(product_data);


    adapter = new ProductAdopter(this, R.layout.listview_item_row, product_data, 2); ListView listView1 = (ListView)findViewById(R.id.listView1); 
    listView1.setAdapter(adapter);

 //adapter.remove(adapter.getItem(info.position)); 
//adapter.notifyDataSetChanged(); 

}

这样做你正在向适配器提供新数据所以即使没有调用它也会刷新列表视图以显示新的更改数据 adapter.notifyDataSetChanged();

您还需要将列表视图对象设为全局对象,以便在 onMenuItemSelected () 中设置新适配器时使用它

我希望这能解决你的问题。

于 2013-04-29T18:20:04.410 回答