web-dev-qa-db-fra.com

Scrollview Android dans un autre scrollview ne défile pas

J'essaie de mettre un ScrollView dans un autre ScrollView et j'ai essayé les réponses trouvées sur ce site mais cela ne semble toujours pas fonctionner complètement. Voici le 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>

Et voici le code Java:

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

Voici ce qui semble se produire: lorsque j'ai du texte dans TextView, il ne semble pas me permettre de le faire défiler du tout. Il suffit de faire défiler le parent. Mais quand je n'ai pas de texte et que je touche l'enfant ScrollView, il ne fait pas défiler le parent, alors je suppose que ça fonctionne. Mais avez-vous des idées pour lesquelles cela ne fonctionne pas quand j'ai du texte?

12
Mihai Boisteanu

Vous devez utiliser NestedScrollView .

<Android.support.v4.widget.NestedScrollView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            >
            <!-- -->
</Android.support.v4.widget.NestedScrollView>
32
Volodymyr Kulyk

Old Question cependant, Je publie ce qui a fonctionné pour moi, je comprends le problème mais j’en ai parlé aussi, je viens de supprimer ScrollView pour TextView en XML, fonctionnalité de défilement plutôt implémentée pour TextView en code Java. Ainsi, XML serait:

    <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" />

et le code Java serait 

 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;
        }
    });
4
devgrg

Avoir une vue de défilement dans une autre vue de défilement n'est pas une bonne pratique. Cependant, le code que vous avez utilisé pourrait fonctionner dans certains cas. Mais cela peut échouer si vous avez plusieurs éléments. Dans ce cas, il pourrait ne pas être en mesure d'identifier le geste.

Cependant, vous pouvez essayer cette réponse, si cela vous aide ScrollView Inside ScrollView . Il désactive le contact du parent ScrollView, lorsqu'un contact pour l'enfant est identifié. Jetez également un coup d'œil à ce post si cela peut vous aider.

3
Sahil Mahajan Mj

J'utilise RectF pour vérifier si votre doigt se situe dans la plage de votre vue_enfant. 

Je l'ai utilisé pour un cas combinant scrollview et viewpager (qui contient deux pages avec recycleviews).

Essayez ces codes et vous obtiendrez ce que vous voulez. 

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;
        }
    });
2
TeeTracker

vous ne pouvez pas utiliser deux Scrollview dans le système d’exploitation Scrollview, vous ne savez pas lequel doit défiler pour que votre activité s’arrête et ne l’utilisez pas de la sorte 

1
venky

Je suis presque sûr que c'est impossible:

Comment Android gère les événements tactiles:

Le parent obtient l'événement et décide s'il doit le gérer ou s'il doit le laisser à l'enfant.

donc, si un scrollview gère le toucher, celui qui le gère est toujours le parent

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

personnellement, je ne sais pas s'il y a un moyen de comprendre ce qui est touché derrière le scrollview parent pour voir s'il s'agit d'un autre scrollview et le laisser gérer le mouvement.

0
cescom

utilisez cette vue de défilement personnalisée comme défilement intérieur:

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);
}
}
0
Hanaa Mohamed

check this link qui montre comment utiliser deux widgets avec la fonctionnalité de défilement dans la même activité. vérifiez ce code ci-dessous.

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;
            }
        });
0
i.n.e.f

Voici une solution possible qui fonctionne bien avec ScrollView et ListView dans un ScrollView. ScrollView Inside ScrollView

0
Nicolai Nita