Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically add items to scrollview top, but should not scroll to top

I have scrollview with child LinearLayout . I am adding data programmaticaly to it. When i add some data to top of linearlayout it automatically scrolls to top element. But i want something like , user reaches top -> scrolls upside to load previous data ->add data to linearlayout top but should not get focus, after addition complete , if user scrolls then and then only it should display .

How to achieve this?

like image 881
Mind Android Avatar asked Nov 02 '22 01:11

Mind Android


2 Answers

Well I thought of a way and it works almost perfectly.

I have a LinearLayout (llCommunicationsLayout) inside a ScrollView (svCommunications) .

I inflate a new LinearLayout, I'm going to add views to the top of this new LinearLayout and then add this new layout to the LinearLayout inside the ScrollView.

This is the new layout:

final LinearLayout wrapperLayout = (LinearLayout) mInflater.inflate(R.layout.empty_layout, null);

I add my views to the 0'th position of this layout.

wrapperLayout.addView(view, 0);

After all the views are added into the wrapperLayout, I add the wrapperLayout into the llCommunicationsLayout (the one inside my ScrollView)

llCommunicationsLayout.addView(wrapperLayout, 0);

After this, I calculate their heights after the wrapperLayout is on screen (has a measurable height)

wrapperLayout.post(new Runnable() {

                    @Override
                    public void run() {
                        int wrapperHeight = wrapperLayout.getHeight();

                        int svHeight = svCommunications.getHeight();

                        int scrollHeight = Math.abs(svHeight - wrapperHeight);

                        DisplayMetrics displaymetrics = new DisplayMetrics();
                        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
                        int displayHeight = displaymetrics.heightPixels / 4;


                        svCommunications.scrollTo(0, (scrollHeight + displayHeight));

                    }
                });

Here, I get both the newly added layout's and the ScrollView's heights.

I calculate their difference, add the 1/4 of the height of the screen of my device and scroll it, voila!

It's not perfect, but after the layouts are added, it no longer scrolls to the top of the screen. Experiment with the displayHeight for different results.

Hope this helps someone out.

like image 53
Lev Avatar answered Nov 12 '22 18:11

Lev


You can grab the current view which is on top of your LinearLayout then add new content to your LinearLayout and then scroll back to view which was previously on top. The code would be something like:

public void addViewsOnTop(List<View> views) {
    final View currentViewOnTop = (linearLayout.getChildCount() > 0) ? linearLayout.getChildAt(0) : null;

    // Add Views. Note that views will appear in reverse order
    for(View view : views) {
        linearLayout.addView(view, 0);
    }

    // Scroll back to view which was on top
    if(currentViewOnTop != null) {
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                scrollView.scrollTo(0, currentViewOnTop.getBottom());
            }
        });
    }
}
like image 38
Piotr Wilczek Avatar answered Nov 12 '22 18:11

Piotr Wilczek