Search code examples
androidlistviewscrollscrollviewandroid-relativelayout

RelativeLayout with ListViews inside ScrollView not scrolling when touching ListView area


I've got a problem with my view which looks like below:

My view before scrolling

My view after scrolling

As you can see it's supposed to be a scrollable view with unscrollable ListViews.

It consists of DrawerLayout inside which I've got CoordinatorLayout (with AppBarLayout and my FrameLayout containing my fragments) and NavigationView.

activity_main.xml

<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:background="@color/colorBackground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">

<include
    layout="@layout/app_bar_vision"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_vision"
    app:menu="@menu/activity_vision_drawer" />

app_bar_vision.xml

<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
tools:context=".activity.MainActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorBar"
        app:popupTheme="@style/AppTheme.PopupOverlay"
        app:layout_scrollFlags="scroll|enterAlways|snap"/>

</android.support.design.widget.AppBarLayout>

<FrameLayout
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="?attr/actionBarSize"/>

Now the main part. My fragment layout consists of ScrollView inside which there is RelativeLayout inside wich I've got two ListViews wchich height is set programatically according to assigned elements.

fragment_preferences.xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<include layout="@layout/content_preferences" />

</ScrollView>

content_preferences.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
tools:context="dron.mkapiczynski.pl.dronvision.fragment.PreferencesFragment"
tools:showIn="@layout/fragment_preferences">>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Preferencje wizualizacji"
    android:id="@+id/preferencesTitle"
    android:layout_gravity="center" />

<TextView
    android:id="@+id/trackedListTitle"
    android:text="Drony śledzone"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/preferencesTitle"
    android:layout_marginTop="20dp"/>

<ListView
    android:id="@+id/trackedDroneList"
    android:layout_below="@+id/trackedListTitle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:layout_gravity="center_horizontal"
    android:layout_centerInParent="true"
    tools:showIn="@layout/fragment_preferences"/>

<TextView
    android:id="@+id/visualizedListTitle"
    android:text="Drony do wizualizacji obszaru przeszukanego"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/trackedDroneList"
    android:layout_marginTop="20dp"/>

<ListView
    android:id="@+id/visualizedDroneList"
    android:layout_below="@+id/visualizedListTitle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:layout_gravity="center_horizontal"
    android:layout_centerInParent="true"
    android:nestedScrollingEnabled="true"
    tools:showIn="@layout/fragment_preferences"/>

In general scrolling works but only if I touch the screen in areas outside of ListView for example in area with my TextView. When I try to scroll in areas with ListView nothing happens.

I'll be gratefull for any advice. I've tried to implement my own nonScrollingListView extending ListView thought that may enable parent scrolling but that doesn't help. I've also read about using LinearLayout instead of ListView but maybe there is still a way to use ListView with ScrollView?


Solution

  • It is generally a discouraged to use a Scrollable view as a childview of the scrollview or any other scrollable content. But, however if there is a need of the application and if the developer wants to handle the scrolling events smoothly, below is the way to handle the scrollable contents individually,

    For the parent scrollview, you can handle the scrolling event as

    m_parentScrollView.setOnTouchListener(new View.OnTouchListener() 
    {
           public boolean onTouch(View p_v, MotionEvent p_event) 
            {
                m_childScrollView.getParent().requestDisallowInterceptTouchEvent(false);
               //  We will have to follow above for all scrollable contents
               return false;
            }
    });
    

    For the child scrollview,in your case Listview, we have to handle the event as shown below:

    m_childScrollView.setOnTouchListener(new View.OnTouchListener() 
    {
          public boolean onTouch(View p_v, MotionEvent p_event)
           {
              // this will disallow the touch request for parent scroll on touch of child view
               p_v.getParent().requestDisallowInterceptTouchEvent(true);
               return false;
           }
    });
    

    You can get more details about it from here: handle-scrollable-views-or-controls-in-another-scrollview-in-android

    Also, as a side note, I have also faced some similar issues while using Scrollview and RelativeLayout and this user is also facing same issue as you.

    Hope it helps you :)