Wednesday 1 January 2014

Handle Scrolling of Scrollable Controls in Scrollview in Android

In life of any Android developer, there are times when there is a requirement in the application to use one scrollable control inside another scrollable control. In such cases, the scrolling functionality of one or all scrollable controls gets enabled and the Android application cannot identify that scroll event of which control is to be handled first. Here, UI may get stuck in some scenarios.
The ideal behavior expected is when the user touches the parent scroll view, only the parent view’s scroll event is called and when the user scrolls the child scroll view, the child view’s scroll event is called. In our standard Android application development and implementation process it does not happen when we add scrollable control in another scrollable control.
Below is the solution to handle the scroll event of both the controls without any glitch.
Example
We have a layout that has a ScrollView as parent layout and it contains some TextViews, ImageViews and ListView as child controls. As the below Layout:
 <ScrollView android:id=”@+id/parent_scroll” 
        android:layout_width=”fill_parent”
        android:layout_height=”wrap_content”
        android:layout_weight=”1″
        android:background=”@drawable/dotted_bg”
        android:focusableInTouchMode=”false”>
                    <LinearLayout   />
                    <LinearLayout   />
                    <LinearLayout  >
                    <ScrollView android:id=”@+id/child_scroll”  
                    android:layout_width=”fill_parent”
                    android:layout_height=”fill_parent”
                    android:background=”@drawable/text_box_bg”>
                <TextView android:id=”@+id/text_description”
                    android:layout_width=”fill_parent”
                    android:layout_height=”fill_parent”
                    android:textColor=”@color/gray”
                    android:textSize=”12dip”
                    android:padding=”5dip”
                    android:scrollbars=”vertical”/>
                <!–ScrollView>
              </LinearLayout>

Step 1 : Provide unique id to both the scrollview.
The id of the parent ScrollView is parent_scroll and child ScrollView is child_scroll. Now in the onCreate method we have to set Touchlistener event for both the scroll views and use requestDisallowInterceptTouchEvent of the view.
Step 2 : get reference of that two scrollview in your activity.
  parentScroll=(ScrollView)findViewById(R.id.parent_scroll);
    childScroll=(ScrollView)findViewById(R.id.child_scroll);
For parent scroll view, below code disables the scrolling event for the child scrollable controls in the parentScroll. So the user can scroll the parent scroll view and see the controls of parent scroll view without UI getting stuck.
 parentScroll.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                Log.v(TAG,”PARENT TOUCH”);
  findViewById(R.id.child_scroll).getParent().requestDisallowInterceptTouchEvent(false);
                return false;
            }
        });

For the child scroll view, below code disables the scroll event of parent scroll view if the user touches on child scroll view,

 childScroll.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) 
            {
                Log.v(TAG,”CHILD TOUCH”);
                // Disallow the touch request for parent scroll on touch of child view
                v.getParent().requestDisallowInterceptTouchEvent(true);
                return false;
            }
        });

Note: According to the UI guide lines and best practices, it is advisable not to use Scrollable content inside Scrollview and doing that prevents the scrolling of the Scrollable content.
When you put two scrollview android just get confused which scroll view is touched. So sometimes it gets unable to deliver touch event.
But if still you want to achieve the scrolling functionality you can manage it by using the onTouch event of the particular view. And you need to design your layout accordingly.
But even if the requirement forces you to make such layouts. You can try as above.

No comments:

Post a Comment