使用自定义ListView适配器

时间:2017-08-08 13:13:56

标签: android listview android-fragments

如果这是一个愚蠢的问题,请提前道歉。 我在网上搜索了我的问题的答案,但没有找到任何有用的东西。

我在片段中有一个ListView和一个CustomViewAdapter。这很好用。列表显示正确。

我遇到的问题是,如果列中的行发生更改,但行更新后,实际列表不会更新。把它放在上下文中,我所拥有的是收藏夹列表,它们显示在收藏夹片段中。但是,如果用户“不喜欢”某个项目,即使显示该项目的图标是最喜欢的更改,实际列表仍会显示该项目,而不是刷新列表并从列表中删除该项目。

正如我所说,我已经尝试了所有与此问题相关的解决方案,例如使用适配器调用notifyDataSetChanged。

片段中的代码:

public void ShowFavourites(){
    globalVariable = ((GlobalClass) getActivity().getApplicationContext());
    JCDatabaseHelper helper = new JCDatabaseHelper(getActivity().getBaseContext());

    ArrayList<ArticleItem> rowItems = new ArrayList<>();
    ArticleItem myItem1;
    String[] columnNames = {"_id", "Column1", "Column2", "Column3",
            "Column4", "Column5", "Column6", "Column7"};
    MatrixCursor matrixCursor = new MatrixCursor(new String[]{"_id",
            "Column1", "Column2", "Column3", "Column4", "Column5", "Column6", "Column7" });
    int[] to = new int[]{R.id.id, R.id.imageButton, R.id.title, R.id.year, R.id.authors,
            R.id.favs, R.id.read, R.id.readOnLine};
    final ListView listView = (ListView) getActivity().findViewById(android.R.id.list);
    ArrayList<Favourites> favouritesArrayList = helper.GetFavourites();
     for (Favourites articleItem : favouritesArrayList) {
          // code to access items
          //then...
          matrixCursor.addRow(new Object[]{k, imgFile,Title, Year , Authors, favIcon , btn1.getText(), btn2.getText() });
          myItem1 = new ArticleItem(ID, Title, Year);
          rowItems.add(myItem1);
     }
    CustomListViewAdapter customAdapter;
    ListView yourListView;
    customAdapter = new CustomListViewAdapter(getActivity().getBaseContext(),
            R.layout.article_row, rowItems);
    yourListView.setAdapter(customAdapter);
    customAdapter.notifyDataSetChanged();
}

CustomListViewAdapter中的代码:

public class CustomListViewAdapter extends ArrayAdapter<ArticleItem> {

  ArrayList<ArticleItem> _rowItems;
  ArticleItem item;
  View row;

  public CustomListViewAdapter(Context context, int resourceId,
                             ArrayList<ArticleItem> articleItems) {
    super(context, resourceId,articleItems);
    this.context = context;
    _rowItems = articleItems;
    }

  @Override
  public View getView(final int position, View convertView, ViewGroup parent){
    row = convertView;
    item = _rowItems.get(position);
    if (row == null) {
       LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       row = mInflater.inflate(R.layout.article_row, parent, false);
    }

    // other code to set TextViews, etc ...
    final int FavYes = R.drawable.favourite;
    final int FavNo = R.drawable.favourite_outline;

    final ImageButton favBtn = (ImageButton) row.findViewById(R.id.favs);
    if (Favs.equals("Y")){
        favBtn.setImageResource(FavYes);
    }
    else favBtn.setImageResource(FavNo);

    favBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        JCDatabaseHelper helper = new JCDatabaseHelper(getContext());
            item = _rowItems.get(position);
            ID = item.getID();
            Title = item.getTitle();
            String NewFavs;
            if (Favs.equals("N")){
                NewFavs = "Y";
                favBtn.setImageResource(FavYes);
                helper.UpdateFavourite("FavouritesTable", ID, NewFavs);
            }
            else {
                NewFavs = "N";
                favBtn.setImageResource(FavNo);
                helper.UpdateFavourite("FavouritesTable", ID, NewFavs);
                // THIS ACTION SHOULD TAKE THIS ROW FROM THE LIST AND RESHOW THE LIST. 
            }
     }
    });

 return row;
}

我尝试过以下答案: 1. How to refresh Android listview?但它不起作用。也许是因为我没有正确地称它为正确。 2. notifyDataSetChanged() in Fragment is not refreshing listview 其他问题/答案涉及类似但不同的问题。

任何帮助将不胜感激。感谢

2 个答案:

答案 0 :(得分:1)

查看代码我认为view方法应该在这种情况下工作。

关键是你应该在调用notifyDataSetChanged之前修改集合,因为这个方法只会收集你的集合(notifyDataSetChanged)并将每个项目再次膨胀到ListView中。 因此,如果该集合仍然包含该项目,那么它将保留在列表中。

由于在构造适配器时将_rowItems设置为articleItems字段,我认为最快的方法可能是调用listView.getAdapter()。removeItem(itemNotFavorite)。请注意,要执行此操作,您必须将适配器转换为_rowItems之前:)

另一个机会,也许更清洁一点就是在适配器中创建一个setter来覆盖你的集合,然后依赖ArrayAdapter

如果其中一些有用,请告诉我;)

答案 1 :(得分:0)

我已经通过马里诺的答案得出答案,所以将他们的答案标记为正确答案。我只想展示我添加的代码,以防它帮助其他人。 我将以下内容添加到CustomListViewAdapter中,我只是发布了上面代码的一部分)

  favBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    JCDatabaseHelper helper = new JCDatabaseHelper(getContext());
        item = _rowItems.get(position);
        ID = item.getID();
        Title = item.getTitle();
        String NewFavs;
        if (Favs.equals("N")){
            NewFavs = "Y";
            favBtn.setImageResource(FavYes);
            helper.UpdateFavourite("FavouritesTable", ID, NewFavs);
        }
        else {
            NewFavs = "N";
            favBtn.setImageResource(FavNo);
            helper.UpdateFavourite("FavouritesTable", ID, NewFavs);
            // Here is what helped!
            _rowItems.remove(item); //this removes the item that has been set as no longer a favourite
            CustomListViewAdapter.this.notifyDataSetChanged(); // this I suppose refreshes the adapter
        }
 }
});

还要感谢@Marcos,他给了我一些关于该怎么做的线索。