Search code examples
androidandroid-activitylayoutscrollviewandroid-linearlayout

How to add scrollview to only LinearLayout in main_activity not to the whole view?


I am simply trying to add scrollbar to my linearlayout one of many views I have in the main_activity.xml. However, every time I do that it destroys my whole main_activity setup. I looked up and down the whole Internet and on Stackoverflow and tried to follow it their suggestions, solutions and answers, but I still can't get it to work.

Here is my whole main_activity.xml. Look for bunch of less than symbol pointing at LinearLayout.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
tools:context="com.example.myapp.MainActivity">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/homeBtn"
        android:layout_width="131dp"
        android:layout_height="55dp"
        android:backgroundTint="#2196F3"
        android:text="Home"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.25" />

    <Button
        android:id="@+id/logoutBtn"
        android:layout_width="131dp"
        android:layout_height="55dp"
        android:backgroundTint="#2196F3"
        android:text="Logout"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.25" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="268dp"
        android:layout_height="111dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.496"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.091"
        app:srcCompat="@drawable/logo" />

    <Button
        android:id="@+id/hloginBtn"
        android:layout_width="131dp"
        android:layout_height="55dp"
        android:backgroundTint="#2196F3"
        android:text="Login"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.25" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="390dp"
        android:layout_height="40dp"
        android:text="Moisture Dashboard"
        android:textAlignment="center"
        android:textColor="#000000"
        android:textSize="24sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/imageView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/lineChart"
        android:layout_width="401dp"
        android:layout_height="203dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/llayout" />

    <LinearLayout  <<<<<<<<<<This is the ONLY LinearLayout I want to add scrollview or bar to NOT the whole main_activity.
        android:id="@+id/llayout"
        android:layout_width="399dp"
        android:layout_height="110dp"
        android:layout_marginTop="1dp"
        android:orientation="horizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/hloginBtn" />

    <TableLayout
        android:id="@+id/sensorTable"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:isScrollContainer="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/lineChart">

        <TableRow>

            <TextView
                android:layout_width="75dp"
                android:layout_column="0"
                android:layout_weight="1"
                android:text="Id"
                android:textSize="20sp"
                android:textStyle="bold" />

            <TextView
                android:layout_width="75dp"
                android:layout_column="0"
                android:layout_weight="1"
                android:text="Sensor"
                android:textSize="20sp"
                android:textStyle="bold" />

            <TextView
                android:layout_width="75dp"
                android:layout_column="1"
                android:layout_weight="1"
                android:text="Reading"
                android:textSize="20sp"
                android:textStyle="bold" />
        </TableRow>
    </TableLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>

Solution

  • So some general tips:-

    • Don't hardcode sizes because things won't work on devices with different display sizes or when the user changes display size or orientation or font sizes. Instead use "wrap_content" or "0dp" (which is a short hand to size to constraints).
    • With ConstraintLayout don't try and constrain everything to "parent", constraint things to objects to the left and right to make chains or to items above or below. Because as things change size your constraints to parents will probably not work.
    • ConstraintLayout is good for multi direction layouts to flatten the structure and remove extra depth but if your layout is mainly linear in on direction then a LinearLayout is more efficient.

    So I've change some View items to "placeholders with text" just so that they show up with a coloured background. I've added in another scrollview so things that go off the bottom of the screen are viewable (especially in a landscape orientation).

    Except for the buttons most is done simpler with a LinearLayout

    The output is like:-

    New Layout

    <?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"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/main"
        android:padding="4dp">
    
        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Moisture Dashboard"
            android:textAlignment="center"
            android:textColor="#000000"
            android:textSize="24sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toTopOf="@+id/imageView"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <TextView
            android:id="@+id/imageView"
            android:layout_width="268dp"
            android:layout_height="111dp"
            android:background="#40F321"
            android:text="Logo PlaceHolder"
            app:layout_constraintTop_toBottomOf="@+id/textView2"
            app:layout_constraintBottom_toTopOf="@+id/homeBtn"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />
    
        <Button
            android:id="@+id/homeBtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:backgroundTint="#2196F3"
            android:text="Home"
            android:textSize="16sp"
            android:layout_margin="5dp"
            app:layout_constraintTop_toBottomOf="@+id/imageView"
            app:layout_constraintBottom_toTopOf="@+id/scrollView"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/hloginBtn" />
    
        <Button
            android:id="@+id/hloginBtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:backgroundTint="#2196F3"
            android:text="Login"
            android:textSize="16sp"
            android:layout_margin="5dp"
            app:layout_constraintTop_toBottomOf="@+id/imageView"
            app:layout_constraintBottom_toTopOf="@+id/scrollView"
            app:layout_constraintStart_toEndOf="@+id/homeBtn"
            app:layout_constraintEnd_toStartOf="@+id/logoutBtn" />
    
        <Button
            android:id="@+id/logoutBtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:backgroundTint="#2196F3"
            android:text="Logout"
            android:textSize="16sp"
            android:layout_margin="5dp"
            app:layout_constraintTop_toBottomOf="@+id/imageView"
            app:layout_constraintBottom_toTopOf="@+id/scrollView"
            app:layout_constraintStart_toEndOf="@+id/hloginBtn"
            app:layout_constraintEnd_toEndOf="parent" />
    
        <ScrollView
            android:id="@+id/scrollView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintTop_toBottomOf="@+id/homeBtn"
            app:layout_constraintBottom_toBottomOf="parent" >
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                <HorizontalScrollView
                    android:id="@+id/llayout"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="#21F3D7">
                    <LinearLayout
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal">
                    <!-- Some other elements Here -->
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="PlaceHolder"
                        android:textSize="16sp"
                        android:padding="5dp" />
    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="PlaceHolder"
                        android:textSize="16sp"
                        android:padding="5dp" />
    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="PlaceHolder"
                        android:textSize="16sp"
                        android:padding="5dp" />
    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="PlaceHolder"
                        android:textSize="16sp"
                        android:padding="5dp" />
    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="PlaceHolder"
                        android:textSize="16sp"
                        android:padding="5dp" />
    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="PlaceHolder"
                        android:textSize="16sp"
                        android:padding="5dp" />
    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="PlaceHolder"
                        android:textSize="16sp"
                        android:padding="5dp" />
                    </LinearLayout>
                </HorizontalScrollView>
    
    
                <TextView
                    android:id="@+id/lineChart"
                    android:layout_width="match_parent"
                    android:layout_height="203dp"
                    android:background="#40F321"
                    android:text="Line Chart PlaceHolder" />
    
                <TableLayout
                    android:id="@+id/sensorTable"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
    
                    <TableRow>
                        <TextView
                            android:layout_column="0"
                            android:layout_weight="1"
                            android:text="Id"
                            android:padding="5px"
                            android:background="@drawable/table_border"
                            android:textSize="20sp"
                            android:textStyle="bold" />
    
                        <TextView
                            android:layout_column="0"
                            android:layout_weight="1"
                            android:text="Sensor"
                            android:padding="5px"
                            android:background="@drawable/table_border"
                            android:textSize="20sp"
                            android:textStyle="bold" />
    
                        <TextView
                            android:layout_column="1"
                            android:layout_weight="1"
                            android:text="Reading"
                            android:padding="5px"
                            android:background="@drawable/table_border"
                            android:textSize="20sp"
                            android:textStyle="bold"/>
                    </TableRow>
                </TableLayout>
            </LinearLayout>
        </ScrollView>
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    This barely works for Landscape due to the Logo size.

    I would put the buttons right at the top with the Logo below them in the main scrollview so that it scrolls away when you scroll down to see more stuff.