2017-12-13 4 views
0

사용자가 볼 수 있도록 세로로 나열된 일련의 하위 항목 (보기 개체)이있는 ListView이 있습니다. 예를 들어 과 같이 사용자보기를 추적해야합니다. 사용자가 약 1 초 동안 항목 집합을 보는 경우 노출을 추적해야합니다. b. 동일한 사용자가 항목을 뷰포트 밖으로 스크롤하고 뒤로 돌아 오면 1 초 동안 본 경우 다시 추적해야합니다. Android에서보기 항목의 사용자 노출을 추적합니다. ListView

나는 getGlobalVisibleRect(), getLocalVisibleRect(), getLocationOnScreen() 같은 몇 가지 옵션을 시도하고 그들은 처음에 혼동하고 나를 listView의 하위 항목의 오른쪽 좌표와 가시성을 얻을 도움이되지 않았다.

내 요구 사항과 약간 비슷한 Track impression of items in an android ListView을 확인했지만 더 나은 해결책이 있는지 확인하려고 생각했습니다. 나는 약간의 설명에 대해 명확하지 않다면 안드로이드와 사과에 처음이다.

답변

1

원하는 결과를 얻으려면 두 가지 해결책이 있다고 생각한다. 먼저 각 항목에 대해 Handler를 만들고 스크롤보기에서 호출/제거가 표시되면이를 호출합니다. 그러나 이것은 매우 많은 헨들러가 앱의 삶을 지옥으로 만드는 것처럼 매우 어리 석다.

두 번째로 가장 좋은 방법은 전체 보이는 항목에 대해 단일 처리기를 호출/제거하는 것입니다. "A second"(1 초) 동안 지속되면 각 항목의 모델 클래스에서 노출 수를 사용하고 ++ 연산자를 사용하여 인상하십시오.

목록에 스크롤 리스너를 추가 할 수 있습니다. 스크립트는 다음과 같습니다.

ListView listView = null; 
int firstVisibleItemIndex = 0; 
int visibleCount = 0; 

Handler handler = new Handler(); 
Runnable runnable = new Runnable() { 
    @Override 
    public void run() { 
     for (int i = firstVisibleItemIndex; i < firstVisibleItemIndex + visibleCount; i++) { 
      try { 
       //Get impression count from model for the visible item index i 
       int count = modelList.get(i).getImpressionCount(); 
       //Set impression count to the model for the visible item index i 
       modelList.get(i).setImpressionCount(++count); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
}; 

//Can call this method body in onCreate directly 
private void addListScrollListener() { 
    listView.setOnScrollListener(new AbsListView.OnScrollListener() { 
     @Override 
     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
      // You cat determine first and last visible items here 
      // final int lastVisibleItem = firstVisibleItem + visibleItemCount - 1; 

      handler.removeCallbacks(runnable); 
      firstVisibleItemIndex = firstVisibleItem; 
      visibleCount = visibleItemCount; 
      handler.postDelayed(runnable, 1000); 
     } 

     @Override 
     public void onScrollStateChanged(AbsListView arg0, int arg1) { 
      // TODO Auto-generated method stub 
     } 
    }); 
} 

onCreate 메서드의 ID로 ListView를 바인딩한다고 가정합니다. 또한 변수를 사용하여 뷰를 바인딩 한 후 onCreate에서 리스너를 호출 할 수 있습니다.

귀하의 요구 사항에 부합되기를 바랍니다.

귀하의 의견을 알려주십시오.

+1

답장을 보내 주셔서 감사합니다. 예, ListView를 바인딩하고 onScrollListener를 추가했습니다. 솔루션에서 사용자가 2 초 또는 4 초 스크롤하는 것과 같이 1 초 이상 같은 화면에 머문다면 어떻게 될까요? 동일한 색인 집합이 콜백에 전송됩니다. 동일한 뷰포트에 항목이 있어도 중복 노출이 생성됩니다. 너는 어떤 생각을 가지고 있니? –

+0

예 @KarthikeyanAlagarswamy, 위의 코드와 실행 파일에서 Handler를 언급했습니다. 일단 사용자가 스크롤을하면 마지막 핸들러는 호출을 위해 제거되고 이상 상태가되면 재설정됩니다. 너는 나 한테서 시간을 조절할 수있어, 나는 이것을 1000 밀리 초로 유지했다. 내 코드를 철저히 검토하면 솔루션이 표시됩니다. 주석 처리 된 행을 확인하십시오. 귀하의 코드에 필요한 주석을 엽니 다. 문제가 있으면 알려주세요. –

+0

고맙습니다. onScrollListener 안에 코드 스 니펫을 추가하고 솔루션을 사용해 보았습니다. 천천히 스크롤 한 후에 콜백 메서드가 호출되고 콜백 내부에서 올바른 인덱스를 볼 수 있음을 알 수 있습니다. 따라서 중복을 피하기 위해 현재 색인과 이전 색인을 비교하고 고유 노출 수를 추적해야합니다. –

관련 문제