Android 使用自定义ListView适配器刷新片段ListView

Android 使用自定义ListView适配器刷新片段ListView,android,listview,android-fragments,Android,Listview,Android Fragments,如果这是一个愚蠢的问题,请提前道歉。 我在网上搜索了我的问题的答案,但没有找到任何有用的答案 我在片段中有一个ListView和一个CustomViewAdapter。这个很好用。列表显示正确 我的问题是,如果列表中的一行发生了更改,尽管该行得到了更新,但实际的列表却没有。在上下文中,我有一个收藏夹列表,它们显示在收藏夹片段中。但是,如果用户“不喜欢”某个项目,即使显示该项目的图标是收藏夹更改,实际列表仍会显示该项目,而不是刷新列表并从列表中删除该项目 正如我所说,我已经尝试了所有与此问题相关的

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

我在片段中有一个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();
}
public void showFavorites(){
globalVariable=((GlobalClass)getActivity().getApplicationContext());
JCDatabaseHelper=新的JCDatabaseHelper(getActivity().getBaseContext());
ArrayList,但它不起作用。可能是因为我没有正确地调用它。
2.
其他问题/答案涉及类似但不相同的问题


任何帮助都将不胜感激。感谢查看代码,我认为在这种情况下,
notifyDataSetChanged
方法应该可以工作

关键的一点是,您应该在调用
notifyDataSetChanged
之前修改集合,因为此方法只会获取您的集合(
\u rowItems
),并再次将每个项目膨胀到ListView中。 因此,如果集合仍然包含该项,则该项将保留在列表中

由于在构造适配器时将
articleItems
设置为
\u rowItems
字段,因此我认为最快的方法可能是调用listView.getAdapter().removeItem(itemNotFavorite)。请注意,要做到这一点,您必须将适配器转换为
ArrayAdapter
之前:)

另一个可能更干净的方法是在适配器中创建一个setter来覆盖您的集合,然后依靠
notifyDataSetChanged


让我知道其中一些是否有效;)

我通过Marino的答案找到了答案,因此我将他们的答案标记为正确答案。我只是想展示我添加的代码,以防它对其他人有帮助。 我在CustomListViewAdapter中添加了以下内容(我只是发布了上面代码的一部分)


还要感谢@Marcos,他给了我一个如何做的线索。

你必须从starIconClickListener内的getView()调用notifyDataSetChanged(),因此每次星型更改时,你都告诉适配器它应该重新创建所有视图,因为其中的数据已经更改。你在setAdapter()之后调用它,删除该调用是不必要的:)您如何获得在if循环中使用的Favs值?@marcos谢谢,是的,我意识到该调用是无用的!我如何在customListViewAdapter中调用它?您真的在运行此代码吗?我至少可以看到一个NPE@Stanislav,这是代码的摘要。我没有得到任何NPE。谢谢。我很瘦k我理解你的建议,但显然还不够,因为我不知道如何对它们进行编码。你能提供一些代码吗?我认为
notifyDataSetChanged
应该可以工作,但我不知道如何从CustomListViewAdapter中调用它…你知道我怎么做吗?谢谢!我已经尝试了你说的,谢谢在NOTIFYDATASETCHETCHANGE应该是有效的。我的问题是,我没有正确地或从正确的地方调用它。我将添加我所做的作为一个答案,以防它帮助其他人,但非常感谢您的解释。他们helped@user3079872我很高兴这有帮助!干杯:)
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;
}
  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
        }
 }
});