Search code examples
javaandroidandroid-scrollview

Get child of ScrollView programmatically


I have made a custom ScrollView which has a single child inside it (a layout). Finding the child by ID using findViewByid in the CustomScrollView.java causes the app to crash, so is it possible to find it in a simple manner similar to this (which detects the custom scrollview) or getParent() (which detects the parent layout that both the scrollview and the child is inside of)?

I'm trying to apply requestDisallowInterceptTouchEvent(true); to the child of the custom ScrollView.

xml:

<?xml version="1.0" encoding="utf-8"?>

<com.example.test4.CustomScrollView 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/dynamic_status_scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="none"
    tools:context=".MainActivity">

    <android.support.constraint.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/dynamic_status"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:context=".MainActivity">
    </android.support.constraint.ConstraintLayout>

</com.example.test4.CustomScrollView>

Code inside CustomScrollView.java where I want to add requestDisallowInterceptTouchEvent:

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // Add here
        return super.onTouchEvent(ev);
    }

Problem:

In short, I want to find the child of the custom ScrollView, the layout with the id dynamic_status, without using findViewById.


Solution

  • You should be able to do it like this:

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        ((ConstraintLayout)getChildAt(0)).requestDisallowInterceptTouchEvent(true);
        return super.onTouchEvent(ev);
    }
    

    You can always access child Views (Views nested deeper than your current View) with getChildAt. Since requestDisallowInterceptTouchEvent is only available to ViewGroups you have to cast it either directly to your ConstraintLayout or - for better reuseability - to a ViewGroup.

    Please note that I had not included any checks if the child is available.

    This code is also the same for Kotlin and Java. It does not make any difference (syntactically yes, but the concept is the same).