Android scrollview inside another scrollview doesn

2019-01-25 07:58发布

问题:

I'm trying to put a ScrollView inside another ScrollView and I tried the answers found on this site but it still doesn't seems to work completely. Here is the XML:

 <ScrollView
    android:id="@+id/scrollView1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusableInTouchMode="false" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/textViewDirectoryDetailName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Name"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@color/red" />

        <LinearLayout
            android:id="@+id/linearLayoutDirectoryDetailContainImage"
            android:layout_width="300dp"
            android:layout_height="200dp"
            android:layout_gravity="center_vertical|center_horizontal"
            android:background="@drawable/general_image"
            android:gravity="center"
            android:orientation="vertical" >
        </LinearLayout>

        <ScrollView
            android:id="@+id/scrollView2"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:focusableInTouchMode="false" >

            <TextView
                android:id="@+id/textViewDirectoryDescription"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:autoLink="phone"
                android:text="098 123 45 678"
                android:textAppearance="?android:attr/textAppearanceLarge" />
        </ScrollView>

And here is the Java code:

parentScrollView = (ScrollView) findViewById(R.id.scrollView1);
    childScrollView = (ScrollView) findViewById(R.id.scrollView2);

    parentScrollView.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View p_v, MotionEvent p_event) {
            childScrollView.getParent().requestDisallowInterceptTouchEvent(
                    false);
            // We will have to follow above for all scrollable contents
            return false;
        }
    });
    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;
        }
    });
    // We will have to follow above for all child scrollable contents

What seems to happen is this: when I have text in the TextView it doesn't seem to let me scroll it at all. It just scrolls the parent. But when I have no text and I touch the child ScrollView it doesn't scroll the parent so I guess it's working then. But do you have any ideas why it doesn't work when I have text?

回答1:

You should use NestedScrollView.

<android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >
            <!-- -->
</android.support.v4.widget.NestedScrollView>


回答2:

Having a Scroll View inside another another Scroll View is not a good practice. However the code you have used could work in some cases. But it might fail when you are having multiple elements. In that case, it might not be able to identify the gesture.

However, you can try this answer, if it helps ScrollView Inside ScrollView. It disables the parent ScrollView's touch, when a touch for the child is identified. Also have a look at this post if it helps.



回答3:

I use RectF to test whether you finger locates in the range of your child_view.

I've used it for a case that a mix between scrollview and viewpager(that contains two pages with recycleviews).

Try these codes and you will get what you wanna.

findViewById(R.id.parent_view).setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            View childV = findViewById(R.id.child_view);
            if (childV != null) {
                int[] l = new int[2];
                childV.getLocationOnScreen(l);
                RectF rect = new RectF(l[0], l[1], l[0] + childV.getWidth(), l[1] + childV.getHeight());
                if(rect.contains(  event.getX(), event.getY())) {
                    childV.getParent()
                            .requestDisallowInterceptTouchEvent(false);
                    childV.onTouchEvent(event);
                    return true;
                }
            }
            childV.getParent()
                    .requestDisallowInterceptTouchEvent(true);
            return false;
        }
    });


回答4:

Old Question though, I am posting what worked for me,I understand the issue Coz i have gone through it too, I just removed the ScrollView for TextView in XML, rather implemented scrolling feature for TextView in java code. Thus, XML would be:

    <TextView
        android:id="@+id/textViewDirectoryDetailName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Name"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="@color/red" />

    <LinearLayout
        android:id="@+id/linearLayoutDirectoryDetailContainImage"
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:layout_gravity="center_vertical|center_horizontal"
        android:background="@drawable/general_image"
        android:gravity="center"
        android:orientation="vertical" >
    </LinearLayout>   
            <TextView
            android:id="@+id/textViewDirectoryDescription"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:autoLink="phone"
            android:text="098 123 45 678"
            android:textAppearance="?android:attr/textAppearanceLarge" />

and the Java Code would be

 TextView extViewDD =  
    (TextView)findViewById(R.id.textViewDirectoryDescription);    
    //for Scrolling of textView       
    textViewDD.setMovementMethod(new ScrollingMovementMethod());
//to stop parent linearlayout scrollview when touched on textview
    textViewDD.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            v.getParent().requestDisallowInterceptTouchEvent(true);
            return false;
        }
    });


回答5:

you can not use two Scrollview inside Scrollview OS get confuse which one have to scroll so your activity hang so do not use like this



回答6:

check this link which shows that how to use two widget with scroll functionality in same activity. check this below code in that.

parentScroll.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event) {
                Log.v("PARENT", "PARENT TOUCH");
                findViewById(R.id.child_scroll).getParent()
                        .requestDisallowInterceptTouchEvent(false);
                return false;
            }
        });
        childScroll.setOnTouchListener(new View.OnTouchListener() {

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


回答7:

I'm almost sure it is impossible:

How android handles touch events:

Parent gets event and decides if it has to handle it or if it should let handle it to the child;

so,if a scrollview handles the touch, the one which handles it, is always the parent one

http://developer.android.com/training/gestures/viewgroup.html

personally i don't know if is there a way to understand what is touched behind the parent scrollview to see if it is another scrollview and let it handle the movement



回答8:

Here is a possible solution which works fine with ScrollView and ListView inside a ScrollView. ScrollView Inside ScrollView



回答9:

use this custom scrollview as inner scrollview:

public class TouchMeScrollView extends ScrollView {
public TouchMeScrollView(Context context) {
    super(context);
}

public TouchMeScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public TouchMeScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TouchMeScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
}

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