【问题标题】:Refreshing Fragment ListView using custom ListView adapter使用自定义 ListView 适配器刷新 Fragment ListView
【发布时间】:2017-08-08 13:13:55
【问题描述】:

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

我在 Fragment 中有一个 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 其他问题/答案处理类似但不同的问题。

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

【问题讨论】:

  • 您必须从 getView() 内的 starIconClickListener 内部调用 notifyDataSetChanged(),因此每次星形更改时,您都会告诉适配器它应该重新创建所有视图,因为其中的数据已更改。您在 setAdapter() 之后调用它,删除该调用是不必要的 :)
  • 你如何获得你在 if 循环中使用的 Favs 值..?
  • @marcos 谢谢,是的,我知道这个电话没用!我如何在 customListViewAdapter 中调用它?
  • 你真的在运行这段代码吗?我至少可以看到一个 NPE
  • @Stanislav,这是代码摘要。我没有得到任何 NPE。

标签: android listview android-fragments


【解决方案1】:

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

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

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

另一个机会,也许更清洁一点,可以在适配器中创建一个 setter 来覆盖您的集合,然后依赖 notifyDataSetChanged

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

【讨论】:

  • 谢谢。我想我理解你的建议,但显然还不够,因为我不知道如何编码。你能提供一些代码吗?
  • 我认为 notifyDataSetChanged 应该可以工作,但我不知道如何从 CustomListViewAdapter 中调用它......你知道我该怎么做吗?谢谢!
  • 我已经尝试过你所说的,notifyDataSetChanged 应该可以工作。我遇到的问题是我没有正确或从正确的地方调用它。我将添加我所做的作为答案,以防它帮助其他人,但非常感谢您的解释。他们帮助了
  • @user3079872 很高兴有帮助!干杯:)
【解决方案2】:

我通过 Marino 的回答想出了一个答案,所以将他们的答案标记为正确的答案。我只是想展示我添加的代码,以防它帮助其他人。 我将以下内容添加到 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,他给了我关于该做什么的线索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    相关资源
    最近更新 更多