androidandroid-linearlayoutmultiple-views

Android multiple views show when scrollview is added but only first shows if scrollview removed and custom scrolling implemented


I have added Fragments to a linearlayout where each child fragment view occupies complete screen. Now i have to implement a scrolling functionality so that i can navigate through them. I Tried to add a scrollView (horizontal) and it was showing all the children but due to some issues i cannot use scrollview. So, to scroll, i have used the following code that scrolls well but not all children are showed, only the first one is visible even after scrolling:

/**
     * A function to scroll towards the left.
     */
    public void scrollLeft(){
        LinearLayout layout = findViewById(R.id.viewList);
        int x = getResources().getDisplayMetrics().widthPixels;
        layout.scrollBy(-x, 0); // scroll by the amount of the screen's width
    }


    /**
     * A function to scroll towards the right.
     */
    public void scrollRight(){
        LinearLayout layout = findViewById(R.id.viewList);
        int x = getResources().getDisplayMetrics().widthPixels;
        layout.scrollBy(x, 0); // scroll by the amount of the screen's width
        }

I even tried to scroll the ConstraintLayout (the base layout) but that too gave the same results. Here is my activity_test.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/TestRoot"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".TestActivity">


    <LinearLayout
        android:id="@+id/viewList"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:baselineAligned="false"
        android:orientation="horizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"></LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Here is the code i used to add fragments to the LinearLayout and this is called only in the onCreate method:

FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();

for (int i = 0; i < results.length; i++) {
    ResultFragment result = new ResultFragment();         
    // configuring the fragment
    // ....


    LinearLayout l = new LinearLayout(this);
    l.setId(View.generateViewId());
    transaction.add(l.getId(), result, "result-"+i);
    ((LinearLayout)findViewById(R.id.viewList)).addView(l,i);
    findViewById(R.id.viewList).invalidate();
}
transaction.commit();

Solution

  • Got no response but no problem, I found the solution myself. So what i did was simple. I created a custom ScrollView which overrided the onTouchEvent function, implemented my own scrolling mechanism and placed my linearlayout inside this scrollView and kaboom! It worked. The new ScrollView looks like this:

    package com.nalin.test;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.widget.HorizontalScrollView;
    
    
    public class LockedHScrollView extends HorizontalScrollView {
    
        /** The variables used to detect left-right swipes*/
        float x1, x2;
        /** variable to check whether the swipes made were valid (distance was large enough) */
        final float distance = 200;
    
    
    
        public LockedHScrollView(Context context){super(context);}
        public LockedHScrollView(Context context, AttributeSet attrs){super(context, attrs);}
        public LockedHScrollView(Context context, AttributeSet attrs, int defStyleAttr){super(context, attrs, defStyleAttr);}
    
    
        /**
         * A function to scroll towards the left.
         */
        public void scrollLeft(){
            int x = getResources().getDisplayMetrics().widthPixels;
            scrollBy(-x, 0); // scroll by the amount of the screen's width
        }
    
    
        /**
         * A function to scroll towards the right.
         */
        public void scrollRight(){
            int x = getResources().getDisplayMetrics().widthPixels;
            scrollBy(x, 0); // scroll by the amount of the screen's width
        }
    
    
        /**
         * A function to check swipes for scrolling between multiple result fragments.
         */
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (event.getAction()==MotionEvent.ACTION_DOWN){
                x1 = event.getX();
            }else if (event.getAction() == MotionEvent.ACTION_UP){
                x2 = event.getX();
                if ((x2-x1)>0){             //Right swipe
                    if (x2-x1 >= distance){        // Validate that the swipe was long enough
                        scrollLeft();
                    }
                }else if((x1-x2)>0){        // Left swipe
                    if ((x1-x2)>=distance){        // Validate that the swipe was long enough
                        scrollRight();
                    }
                }
            }
            return true;
        }
    }