1

Would it be possible to hide a view off the top edge of the screen, and only have it appear if the user scrolls upwards?

My first attempt used a scrollview, but it seems that scrollTo() doesn't work unless I used postDelayed (it doesn't even work with Post()). I tried adding it to the scrollview's view tree observer onPreDraw() event and it still doesn't work unless I delay it, so there is an ugly glitch when the activity is first launched.

The second issue is that if the onscreen keyboard is minimized, the view no longer needs to scroll so hiding things by using a scroll offset no longer works. I thought about manipulating the height in code, but this seems pretty hackish.

Is there a better way to do this than by using a scrollview? Alternatively, Does anyone have any tips on the best place to place the scrollTo (the end of onCreate does not work nor the other places I have tried) so I don't need to use postDelayed? That would at least eliminate one glitch.

Thanks!

This is the code I'm using right now, which is the least glitchy but I don't understand why it doesn't work until the third time onPreDraw() is called.

mScrollView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
    {
        @Override
        public boolean onPreDraw()
        {
            final int fieldYStart = mFieldIWantAtTheTop.getTop();

            if (mFieldIWantAtTheTopYStart != fieldYStart
             || mScrollView.getScrollY() < 10)
            {
                mFieldIWantAtTheTopYStart = fieldYStart;

                mScrollView.post(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        Log.v("Testing", "scrolling!");
                        mScrollView.scrollTo(0, mFieldIWantAtTheTopYStart);
                        Log.v("Testing", "scroll is now=" + mScrollView.getScrollY());
                    }
                });
            }


            return true;
        }
    });

I also tried using a custom scrollview as mentioned below, but this does not solve the issue of the graphical glitch:

@Override
public void onMeasure(int measureWidthSpec, int measureHeightSpec) {
    super.onMeasure(measureWidthSpec, measureHeightSpec);
    Log.v("Testing", "Scrolling");
    post(
            new Runnable()
            {
                public void run()
                {
                    scrollTo(0, 100);
                    Log.v("Testing", "ScrollY = " + getScrollY()); 
                }
            });       
}

This code works as does the onPreDraw() code above but there is still a glitch when the activity is launched because the activity is first drawn with the scroll at 0.

Kevin
  • 85
  • 8

1 Answers1

1

I haven't tried this, but you may want to create a custom ScrollView and override onMeasure:

ScrollView scroll = new ScrollView(this) {
    @Override
    public void onMeasure(int measureWidthSpec, int measureHeightSpec) {
        super.onMeasure(measureWidthSpec, measureHeightSpec);
        scrollTo(...);
    }
};

It seems like this would be the earliest point that scrollTo would be valid.

Edit - I found this answer, which apparently worked for the asker. Is this the method you tried?

Community
  • 1
  • 1
Matthew
  • 44,826
  • 10
  • 98
  • 87
  • Yes, basically, you have to wait until the first layout pass is complete before scrolling the ScrollView. – Brian Cooley Mar 23 '11 at 22:19
  • Re: the link: This works (I don't get why since scrollTo() was not working) but there is a noticeable glitch even though I am using post(). Right now I am using onPreDraw() and the scroll actually only works by the 3rd call (I am checking with getScrollY immediately after the scrollTo call and it just doesn't work until onPreDraw() #3, but in this case there is still a slight glitch). – Kevin Mar 23 '11 at 22:20
  • Were you able to try the `onMeasure` method? – Matthew Mar 23 '11 at 22:23
  • I haven't tried the onMeasure method yet since I've never used custom views in XML and code, so I'll have to figure that out first. I'll give it a shot tomorrow and see. – Kevin Mar 23 '11 at 22:28
  • Ok, I tried this out. onMeasure gets called six times, and each time I call scrollTo(0, 100) but when I check the Y value it is still 0 after the scrollTo call. I then tried the same thing by wrapping the scrollTo() call in a post(), and it works, but it's the same problem I had as before. There's a noticeable glitch at the beginning where you see the activity "jump" to the new position. – Kevin Mar 24 '11 at 15:13
  • Hmm, this is unfortunate. I'd like to see a reliable answer to this. – Matthew Mar 24 '11 at 16:30
  • Must be one of those quirks of Android. I guess it's probably not a good idea to try and do this given the way it works right now. Thanks for taking the time to help out, though! – Kevin Mar 24 '11 at 18:13