12

I have implemented TapTargetView library to my app.

After passing a certain element, I need to focus on the next view which is outside the screen at this moment:

@Override
public void onSequenceStep(TapTarget lastTarget) {
  if (lastTarget.id() == 7) {
     flavorContainer.setFocusableInTouchMode(true);
     flavorContainer.requestFocus();
  }
}

Everything was fine, before I added the ad unit at the bottom of the screen. So now the necessary element is displayed behind the ads.

enter image description here

Method requestFocus() scrolls layout only to the necessary view was visible but not to the end of screen.

enter image description here

I need a method that scrolls the contents of the screen to the VERY END, not just what would the necessary view become visible on the screen. Is it possible?

enter image description here

Layout structure

<android.support.design.widget.CoordinatorLayout>
<LinearLayout>
<android.support.v4.widget.NestedScrollView> 
<LinearLayout> 
<android.support.v7.widget.CardView> 
<LinearLayout>

</LinearLayout> 
</android.support.v7.widget.CardView> 
</LinearLayout> 
</android.support.v4.widget.NestedScrollView> 
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
Haze
  • 143
  • 1
  • 1
  • 7

2 Answers2

49

You have two possible solutions with pros and cons.

First

Use the method fullScroll(int) on NestedScrollView. NestedScrollView must be drawn before using this method and the focus will be lost on the View that gained it before.

nestedScrollView.post(new Runnable() {
    @Override
    public void run() {
        nestedScrollView.fullScroll(View.FOCUS_DOWN);
    }
});

Second

Use the method scrollBy(int,int)/smoothScrollBy(int,int). It requires much more code, but you will not lose the current focus:

nestedScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        final int scrollViewHeight = nestedScrollView.getHeight();
        if (scrollViewHeight > 0) {
            nestedScrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);

            final View lastView = nestedScrollView.getChildAt(nestedScrollView.getChildCount() - 1);
            final int lastViewBottom = lastView.getBottom() + nestedScrollView.getPaddingBottom();
            final int deltaScrollY = lastViewBottom - scrollViewHeight - nestedScrollView.getScrollY();
            /* If you want to see the scroll animation, call this. */
            nestedScrollView.smoothScrollBy(0, deltaScrollY);
            /* If you don't want, call this. */
            nestedScrollView.scrollBy(0, deltaScrollY);
        }
    }
});
Giorgio Antonioli
  • 12,895
  • 8
  • 37
  • 64
6

For me this worked best. It scrolls to the bottom.

scrollView.smoothScrollTo(0, scrollView.getChildAt(0).height)
// scrollview has always only one child
miso01
  • 213
  • 4
  • 8