【问题标题】:Get ListView children that are not in view获取不在视图中的 ListView 子项
【发布时间】:2013-08-30 01:30:23
【问题描述】:

对于我正在开发的应用程序,我正在尝试获取 ListView 的子项。为此,我有以下代码:

View listItem = mListView.getChildAt(i);

但是,这仅适用于视野范围内的儿童。我还需要接触到不在视线范围内的孩子。我该怎么做?

编辑:

将建议的方法与我已经使用的方法进行比较,我发现以下内容:

RelativeLayout listItem1 = (RelativeLayout) mListView.getAdapter().getView(i, null, mListView);
RelativeLayout listItem2 = (RelativeLayout) mListView.getChildAt(i);
Log.d("Checks", "listItem1: " + listItem1);
Log.d("Checks", "listItem2: " + listItem2);

08-27 14:16:56.628: D/Checks(15025): listItem1: android.widget.RelativeLayout@2c5f2920
08-27 14:16:56.628: D/Checks(15025): listItem2: android.widget.RelativeLayout@2c06d938
08-27 14:16:56.628: D/Checks(15025): listItem1: android.widget.RelativeLayout@2c72dfb0
08-27 14:16:56.628: D/Checks(15025): listItem2: android.widget.RelativeLayout@2bfabe50
08-27 14:16:56.638: D/Checks(15025): listItem1: android.widget.RelativeLayout@2c730c18
08-27 14:16:56.638: D/Checks(15025): listItem2: android.widget.RelativeLayout@2c0d3e38
08-27 14:16:56.638: D/Checks(15025): listItem1: android.widget.RelativeLayout@2c12ebc0
08-27 14:16:56.638: D/Checks(15025): listItem2: android.widget.RelativeLayout@2bddbf70
08-27 14:16:56.648: D/Checks(15025): listItem1: android.widget.RelativeLayout@2c131828
08-27 14:16:56.648: D/Checks(15025): listItem2: android.widget.RelativeLayout@2bdf3270
08-27 14:16:56.648: D/Checks(15025): listItem1: android.widget.RelativeLayout@2c140de0
08-27 14:16:56.648: D/Checks(15025): listItem2: android.widget.RelativeLayout@2c0c8d30

listItem2 指向 ListView 中的实际视图,这是我想要的,只是它只适用于可见的视图。从日志文件可以看出listItem1和listItem2不对应。

编辑 2:

我想出了以下几点:

for (int i = 0; i < mListView.getCount(); i++) {
    RelativeLayout listItem = (RelativeLayout) mListView.getAdapter().getView(i, mListView.getChildAt(i), mListView);
}

这将正确返回列表中所有可见项目的视图。但是,它会为看不见的视图返回不同的视图。

编辑 3:

感谢 nfirex,我有一个可行的答案。这将返回视图,即使它们不在视线范围内:

public View getViewByPosition(int position, ListView listView) {
    final int firstListItemPosition = listView.getFirstVisiblePosition();
    final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;

    if (position < firstListItemPosition || position > lastListItemPosition ) {
        return listView.getAdapter().getView(position, listView.getChildAt(position), listView);
    } else {
        final int childIndex = position - firstListItemPosition;
        return listView.getChildAt(childIndex);
    }
}

【问题讨论】:

    标签: android listview children


    【解决方案1】:

    你需要方法Adapter.getView():

    final View view = mListView.getAdapter().getView(position, null, mListView);
    

    更新:

    您需要创建您的方法。像这样的:

    public View getViewByPosition(int position, ListView listView) {
        final int firstListItemPosition = listView.getFirstVisiblePosition();
        final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;
    
        if (position < firstListItemPosition || position > lastListItemPosition ) {
            return listView.getAdapter().getView(position, null, listView);
        } else {
            final int childIndex = position - firstListItemPosition;
            return listView.getChildAt(childIndex);
        }
    }
    

    【讨论】:

    • 这确实返回了一个视图。但是,我认为它会返回一个新视图,而不是我想要的实际视图。
    • @Zero 您需要检索哪个视图?方法 ListView.getChildAt(i) 将返回它的孩子(它是 ViewGroup 的方法),这是早期从适配器获取的。 Adapter.getView(pos, oldView, parent) 将返回新视图(如果 oldView == null)或 oldView,其数据包含在 Adapter.getItem(pos) 中,按数据列表中元素的位置。您想接收也按索引保存在 ListView 中的视图?
    • 我正在尝试获取我也使用 getChildAt(i) 获得的视图,但是对于看不到的视图(如果我在屏幕上有 8 个项目并且我请求 getChildAt(10),如果我向下滚动,它将在那里,我得到一个 NullPointerException)
    • ListView 中的第 9 项将再次获得位置 1
    • @Zero 我正在更新答案。有一个问题 - 适配器本身不保留视图。 ListView 保留视图并将它们提供给适配器,仅用于用另一个孩子重新填充它们。适配器只能创建或重新填充视图。
    【解决方案2】:

    您可以使用此代码

    private static void initRecyclerBin(AbsListView view) {
            try {
                Field localField = AbsListView.class.getDeclaredField("mRecycler");
                localField.setAccessible(true);
                Object recyclerBin = localField.get(view);
                Class<?> clazz = Class.forName("android.widget.AbsListView$RecycleBin");
                Field scrapField = clazz.getDeclaredField("mScrapViews");
                scrapField.setAccessible(true);
                ArrayList<View>[] scrapViews;
                scrapViews = (ArrayList<View>[]) scrapField.get(recyclerBin);
                if (null != scrapViews) {
                    int length = scrapViews.length;
                    for (int i = 0, count = 0; i < length; i++) {
                        if (null != scrapViews[i] && !scrapViews[i].isEmpty()) {
                            for (int j = 0; j < scrapViews[i].size(); j++) {
                                scrapViews[i].get(j);//this is the scrapViews
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    和 ListView getChildViews()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-11
      • 2021-09-09
      • 1970-01-01
      • 2014-09-08
      相关资源
      最近更新 更多