9

I'm adding floating arrows to my HorizontalScrollView which will let the user know that there are more item's outside of the current view.

What I need is how to tell if the View has been scrolled to it's maximum. You would have thought the method getMaxScrollAmount() would give you this - it doesn't, in my code it gives me the width of the View. Go figure why. Here's my code - nice and simple:

    final ImageView leftArrow = (ImageView) toReturn.findViewById(R.id.leftArrow);
    final ImageView rightArrow = (ImageView) toReturn.findViewById(R.id.rightArrow);

    final HorizontalScrollView scrollView = (HorizontalScrollView) toReturn.findViewById(R.id.actionBarHoriztonalScroll);


    final GestureDetector gd = new GestureDetector(new SimpleOnGestureListener() {
        @Override
        public boolean onScroll(MotionEvent e1, 
                                MotionEvent e2, 
                                float distanceX, 
                                float distanceY) {
            if(scrollView.getScrollX() == 0) {
                leftArrow.setVisibility(View.GONE);
            } else {
                leftArrow.setVisibility(View.VISIBLE);
            }
            if(scrollView.getScrollX() == scrollView.getMaxScrollAmount() ||
                scrollView.getMaxScrollAmount() == 0) {
                rightArrow.setVisibility(View.GONE);
            } else {
                rightArrow.setVisibility(View.VISIBLE);
            }

            Log.v(ClientDetailsFragment.class.getSimpleName(), "max: " + scrollView.getMaxScrollAmount() +
                                                            "current: " + scrollView.getScrollX());
            return super.onScroll(e1, e2, distanceX, distanceY);
        }
    });

    scrollView.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View arg0, MotionEvent ev) {
            gd.onTouchEvent(ev);
            return false;
        }
    });

Output from the above debugging:

10-03 14:36:16.343: VERBOSE/(20508): max: 240 current: 126
10-03 14:36:16.363: VERBOSE/(20508): max: 240 current: 127
10-03 14:36:16.386: VERBOSE/(20508): max: 240 current: 132
10-03 14:36:16.398: VERBOSE/(20508): max: 240 current: 143
10-03 14:36:16.417: VERBOSE/(20508): max: 240 current: 149
10-03 14:36:16.433: VERBOSE/(20508): max: 240 current: 152
10-03 14:36:16.449: VERBOSE/(20508): max: 240 current: 152
10-03 14:36:16.468: VERBOSE/(20508): max: 240 current: 152

(152 is the Max in this case)

Graeme
  • 25,714
  • 24
  • 124
  • 186

1 Answers1

24

The child of the horizontal scrollview should have the correct width. Try this

Log.e("ScrollWidth",Integer.toString(horizontalScrollview.getChildAt(0).getMeasuredWidth()-
        getWindowManager().getDefaultDisplay().getWidth()));

This should be the max scroll amount.

Put the following code in your onCreate method

ViewTreeObserver vto = scrollView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        scrollView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        Log.e("ScrollWidth",Integer.toString(horizontalScrollview.getChildAt(0)
                .getMeasuredWidth()-getWindowManager().getDefaultDisplay().getWidth()));

    }
});
blessanm86
  • 31,439
  • 14
  • 68
  • 79
  • Gives "0" for it's width in onCreateView after the xml has been inflated. Even doing a `findById` gives width of 0 - absolutely no idea why. Good idea though! – Graeme Oct 03 '11 at 15:19
  • 2
    oncreate is fired before views are actually drawn on screen. You can only get the correct width after the layout has been drawn. Ive update my unanswer. – blessanm86 Oct 03 '11 at 15:29
  • Great answer, explanation and way to get the actual width of a view after it's laid out! – Graeme Oct 03 '11 at 15:56
  • @blessenm, Can you help me with my Vertical ScrollView. http://stackoverflow.com/questions/13698725/scroll-at-the-bottom-of-the-activity-on-onclick-listener – ambit Dec 04 '12 at 09:46
  • @blessenm When I use scroll.scrollTo(0, (scroll.getChildAt(0).getMeasuredHeight()- getWindowManager().getDefaultDisplay().getHeight())); it takes me to somewhere on the middle of my page and not at the end as I want it to be – ambit Dec 06 '12 at 04:48
  • 4
    This assumes that your scrollview is the same width as your screen. Try using horizontalScrollview.getChildAt(0).getMeasuredWidth()- horizontalScrollView.getMeasuredWidth() – Jacob Tabak Oct 23 '13 at 21:08