2013-08-27 1 views
17

Для приложения Я работаю над, я пытаюсь получить детей ListView. Для этого у меня есть следующий фрагмент кода:Получить ListView детей, которые не отображаются

View listItem = mListView.getChildAt(i); 

Однако это работает только для детей, которые находятся в поле зрения. Мне нужно также охватить детей, которых нет в виду. Как мне это сделать?

EDIT:

Сравнивая предложенные методы к одному я уже использовал я нахожу следующее:

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: [email protected] 
08-27 14:16:56.628: D/Checks(15025): listItem2: [email protected] 
08-27 14:16:56.628: D/Checks(15025): listItem1: [email protected] 
08-27 14:16:56.628: D/Checks(15025): listItem2: [email protected] 
08-27 14:16:56.638: D/Checks(15025): listItem1: [email protected] 
08-27 14:16:56.638: D/Checks(15025): listItem2: [email protected] 
08-27 14:16:56.638: D/Checks(15025): listItem1: [email protected] 
08-27 14:16:56.638: D/Checks(15025): listItem2: [email protected] 
08-27 14:16:56.648: D/Checks(15025): listItem1: [email protected] 
08-27 14:16:56.648: D/Checks(15025): listItem2: [email protected] 
08-27 14:16:56.648: D/Checks(15025): listItem1: [email protected] 
08-27 14:16:56.648: D/Checks(15025): listItem2: [email protected] 

listItem2 указывает на фактическое View в ListView, который является то, что я хочу за исключением того, что он работает только для просмотров, которые находятся в поле зрения. Из файла журнала вы можете видеть, что listItem1 и listItem2 не соответствуют.

EDIT 2:

я придумал следующее:

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

Это возвращает Просмотров правильно для всех видимых элементов в списке. Однако он возвращает другой вид для тех, которые не отображаются.

EDIT 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); 
    } 
} 

ответ

33

Вам нужно метод Adapter.getView():

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

UPDATE:

Вам нужно создать свой метод. Что-то вроде этого:

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); 
    } 
} 
+2

Это действительно возвращает вид. Однако я думаю, что он возвращает новый вид вместо фактического, который я хочу. – Zero

+0

@Zero Какой вид вам нужно получить? Метод ListView.getChildAt (i) вернет ему дочерний элемент (это метод ViewGroup), который был ранним из адаптера. Adapter.getView (pos, oldView, parent) возвращает новое представление (если oldView == null) или oldView с данными, содержащимися в Adapter.getItem (pos) по позиции элемента в вашем списке данных. Вы хотите получать представления, которые также хранятся в ListView по индексу? – nfirex

+1

Я пытаюсь получить представление, которое я также получаю с помощью getChildAt (i), но для представлений, которые не отображаются (если у меня есть 8 элементов на экране, и я запрашиваю getChildAt (10), который будет там, если я прокручу вниз, я получаю исключение NullPointerException) – Zero

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().