-3

I have a screen with a list of products implemented using a recyclerview. I am looking for a way to check how much time the user spends looking at a certain item in the list. In this way I can know in which items is he interested so I can build him an "maybe interested in" list. More exactly..if a user stays on that item more than x seconds I retain that item id and do the rest... Any kind of ideea or help helps me alot. Thanks

Stef_ro89
  • 81
  • 1
  • 10
  • Are you opening a new view for each item? If so, you could start a timer on opening and check the value on closing this view. Else, you could play with the "onScrollStateListener" for RecyclerView. – yennsarah Oct 20 '15 at 12:31
  • I use the ViewHolder pattern to display the views. I was thinking to use the OnBindViewHolder to get the position of the adapter (and this way the item) that is currentlly viewed. But for this approach I need to have an item covering the whole screen which can bring responsiveness issues. – Stef_ro89 Oct 20 '15 at 13:12

2 Answers2

1

One option is to do something similar to Android: how to check if a View inside of ScrollView is visible? to determine which view is actually within the visible screen. It can be modified slightly to detect if the entire view is visible rather than only a portion.

You're probably also going to have to track the time started/stopped viewing in the recycle view's adapter.

Community
  • 1
  • 1
Bill Mote
  • 12,644
  • 7
  • 58
  • 82
1

I don't like idea to display user something like "maybe interested in" based on your logic. Because user has seen it already. It can be super annoying if I buy computer mouse and then I see it on every Activity I visit... I'd rather see some items from same category as most seen items but not the most seen items themself. That's why I highly suggest you to count time inside item details Activities (onStart/onStop methods)

But Answer can be something like this: See following methods:

RecyclerView.Adapter.onBindViewHolder (View created because it is most likely going to be visible to user)

RecyclerView.Adapter.onViewRecycled (View will be recycled - 100% not visible on screen)

You can create some Map or another database column (don't know your project structure) to store item id's and timestamps from

private class MyHolder extends RecyclerView.ViewHolder {
    long itemId;
    long start;

    public MyHolder(View itemView) {
        super(itemView);
    }
}

@Override
public void onBindViewHolder(BindingHolder holder, int position) {
    holder.itemId = ...;
    holder.start = System.currentTimeMillis();
}

@Override
public void onViewRecycled(BindingHolder holder) {
    super.onViewRecycled(holder);
    long currentTime = System.currentTimeMillis();
    long difference = currentTime - holder.start;
    // store result
    map.put(holder.itemId, difference);
    // to better match your needs update map item and do not overwrite it
}

This is not 100% solution, but is the simplest one.

To implement it inside Activities use same System.currentTimeMillis() method inside onStart and onStop methods (or onResume/onPause). See Acticity lifecycle so that you know where you need it.

VizGhar
  • 3,036
  • 1
  • 25
  • 38
  • Never implemented nor tested so it may contain some errors :) – VizGhar Oct 20 '15 at 13:15
  • As you can see in the comment i made just 1 min before your answer this was the way I wanted to do it, but currently I have a problem because my item is not covering the whole screen so OnBindViewHolder will get 2 items even if one is barely visible. But onViewRecycled may help me... – Stef_ro89 Oct 20 '15 at 13:25
  • Or pick just first one if they are that large... users tends to look on top of the page not bottom – VizGhar Oct 20 '15 at 13:28
  • And how do I know which one is the first if onBind is called on every item the same way? – Stef_ro89 Oct 20 '15 at 13:40
  • `holder.getAdapterPosition()` returns you position in adapter... smallest available is first... – VizGhar Oct 20 '15 at 14:03
  • hmm on second though... the first visible item might be the item with only 1px visible displayed on top. You have to rethink this – VizGhar Oct 20 '15 at 14:05
  • The thing is that if I call holder.getAdapterPosition() inside onBindViewHolder it will get me the next item that is drawn (next than the one i'm interested if i scroll down and previous if I scroll up). I need the already visible one. – Stef_ro89 Oct 20 '15 at 14:19