Отслеживайте впечатления пользователей от элементов представления в Android ListView

У меня есть ListView с набором дочерних элементов, перечисленных вертикально (просмотр объектов), которые будут просматриваться пользователями. Я должен отслеживать просмотры пользователей, скажем, a. Если пользователь просматривает набор элементов около 1 секунды, я должен отслеживать показы. б. Если тот же пользователь прокручивает элементы из области просмотра и возвращается обратно, я должен снова отслеживать, просматривал ли он 1 секунду.

Я попробовал несколько вариантов, таких как getGlobalVisibleRect(), getLocalVisibleRect(), getLocationOnScreen(), и они в первую очередь сбивают с толку и не помогли мне получить правильные координаты и видимость дочерних элементов listView.

Я проверил Отслеживать показ элементов в Android ListView, который немного похоже на мое требование, но я подумал проверить, есть ли лучшее решение. Я новичок в Android и приношу свои извинения, если я не понимаю некоторых объяснений.


person Community    schedule 13.12.2017    source источник


Ответы (1)


Чтобы получить желаемый результат, я думаю, у нас есть два разных решения. Во-первых, создайте обработчик для каждого элемента и вызовите/удалите его в режиме прокрутки, если он виден. Но это очень глупо, так как создание такого количества обработчиков превратит жизнь вашего приложения в ад.

Второй и лучший способ — использовать вызов/удаление одного обработчика для всех видимых элементов. Если это сохраняется в течение времени «Секунда» (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
        }
    });
}

Я предполагаю, что вы свяжете свой ListView с идентификатором в своем методе onCreate. Также вы можете вызвать слушателя в своем onCreate после привязки представления к переменной.

Я надеюсь, что это будет работать для вашего требования.

Дайте мне знать ваши отзывы.

person Hari N Jha    schedule 13.12.2017
comment
Спасибо Хари за ответ. Да, я привязываю ListView и добавляю к нему onScrollListener. В решении, что, если пользователь остается на одном экране более 1 секунды, например, 2 или 4 секунды, прокручивая очень медленно. Тот же набор индексов будет отправлен обратному вызову. Это приведет к дублированию показов, даже если элементы находятся в одном и том же окне просмотра. У вас есть какие-нибудь мысли? - person ; 13.12.2017
comment
Да, @KarthikeyanAlagarswamy, я упомянул обработчик в приведенном выше коде и запустил его. как только пользователь прокручивает скорость, последний обработчик будет удален для вызова и будет сброшен, как только он будет в идеальном состоянии. Вы можете настроить время по своему усмотрению, для меня я оставил 1000 мс. Тщательно просмотрите мой код, и вы увидите свое решение. Также проверьте закомментированные строки. Открываю комментарий, который понадобится для вашего кода. Дайте мне знать, если у вас есть какие-либо проблемы. - person Hari N Jha; 14.12.2017
comment
Спасибо. Я добавил фрагмент кода внутрь onScrollListener и попробовал решение. Я вижу, что после медленной прокрутки вызывается метод обратного вызова, и я могу видеть правильные индексы внутри обратного вызова. Итак, чтобы избежать дублирования, мне придется сравнивать текущий и предыдущий набор индексов и отслеживать уникальные показы, верно? - person ; 15.12.2017
comment
да, вы можете провести сравнение здесь, что если в текущем и предыдущем общем количестве индексов есть общие индексы (значение пересечения), вы можете избежать дублирования показов. - person Hari N Jha; 15.12.2017
comment
Спасибо, Хари. Проблема, которую я вижу, заключается в том, что обратный вызов вызывается только тогда, когда прокрутка останавливается, а не через 1 секунду (во время прокрутки). - person ; 18.12.2017
comment
Да это должно быть. Обработчик будет вызываться после того, как прокрутка будет остановлена, но, поскольку есть задержка, поэтому runnable будет вызываться после временного интервала (1 секунда). Вы можете поделиться своим обновленным кодом, если у вас возникли проблемы. - person Hari N Jha; 20.12.2017