[Android] ScrollView Inside ScrollView


Answers

Essaye celui-là

Note: Ici parentScrollView signifie parentScrollView externe et childScrollView signifie Innner ScrollView

parentScrollView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
        Log.v(TAG, "PARENT TOUCH");

        findViewById(R.id.child_scroll).getParent()
                .requestDisallowInterceptTouchEvent(false);
        return false;
    }
});

childScrollView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        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;
    }
});
Question

Je sais que des personnes de Google nous ont demandé de ne pas placer la vue défilante dans une autre vue défilable, mais y a-t-il une déclaration officielle de leur part nous demandant de ne pas le faire?




J'ai trouvé une très bonne solution. Merci d'utiliser ce code.

    parentScrollView.setOnTouchListener(new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {

            Utils.showLog("PARENT TOUCH");
            findViewById(R.id.activity_mesh_child_scrollView).getParent().requestDisallowInterceptTouchEvent(false);
            return false;
        }
    });

    childScrollView.setOnTouchListener(new View.OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {

            Utils.showLog("CHILD TOUCH");
            // Disallow the touch request for parent scroll on touch of child view
            v.getParent().requestDisallowInterceptTouchEvent(true);
            return false;
        }
    });

Cela fonctionnera sûrement. S'il vous plaît essayez et laissez-moi savoir si ne fonctionne pas.




Si quelqu'un cherche une réponse à cela, j'ai eu une implémentation légèrement différente. J'ai étendu la classe ScrollView et implémenté onTouchListener dans l'enfant, et l'ai mis à self dans le constructeur.

Dans le rappel onTouch, si l'objet d'événement de mouvement est venu avec une valeur pour le compte de pointeur comme 2, j'ai renvoyé vrai, sinon faux. De cette façon, si deux doigts se déplaçaient sur l'écran, cela le considérerait comme une pincée à zoomer, sinon cela le considérerait comme un défilement normal. Je n'ai pas demandé de désactiver le contact parental, etc.

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    if(motionEvent.getPointerCount() == 2){
        mCallbacks.onPinchZoomAction(motionEvent);
        return true;
    }
    return false;
}



Ici, j'ai créé un exemple de projet lié à ScrollView dans un ScrollView. Une vue est défilable dans les deux sens. Vérifiez-le :-

MainActivity.java -

package com.example.dev_task_193_scrollview;

import com.example.dev_task_196_scrollview.R;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.Toast;

public class MainActivity extends Activity implements View.OnClickListener{
    ImageView imageView1,imageView2,imageView3,IVimage1,IVimage2,IVimage3,IVimage4,IVimage5,IVimage6;
    ListView listView1,listView2;
    HorizontalScrollView horizontalScrollView1,horizontalScrollView2;
    ScrollView parentScrollView, scrollView1;
    RelativeLayout relativeLayout1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String[] values = new String[] { "Android", "iPhone", "WindowsMobile",
                "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X",
                "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux",
                "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2",
                "Android", "iPhone", "WindowsMobileWindowsMobileWindowsMobileWindowsMobile" };

        relativeLayout1 = (RelativeLayout) findViewById(R.id.relativeLayout1);
        imageView1 = (ImageView) findViewById(R.id.imageView1);
        imageView1.setBackgroundResource(R.drawable.info);

        imageView2 = (ImageView) findViewById(R.id.imageView2);
        imageView2.setBackgroundResource(R.drawable.info);

        imageView3 = (ImageView) findViewById(R.id.imageView3);
        imageView3.setBackgroundResource(R.drawable.info);

        listView1 = (ListView) findViewById(R.id.listView1);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                R.layout.list_item, values);
        listView1.setAdapter(adapter);

        listView2 = (ListView) findViewById(R.id.listView2);
        ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this,
                R.layout.list_item, values);
        listView2.setAdapter(adapter1);


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


        horizontalScrollView1 = (HorizontalScrollView) findViewById(R.id.horizontalScrollView1);
        horizontalScrollView2 = (HorizontalScrollView) findViewById(R.id.horizontalScrollView2);


        IVimage1 = (ImageView) findViewById(R.id.IVimage1);
        IVimage2 = (ImageView) findViewById(R.id.IVimage2);
        IVimage3 = (ImageView) findViewById(R.id.IVimage3);
        IVimage4 = (ImageView) findViewById(R.id.IVimage4);
        IVimage5 = (ImageView) findViewById(R.id.IVimage5);
        IVimage6 = (ImageView) findViewById(R.id.IVimage6);


        scrollView1.setOnTouchListener(new View.OnTouchListener() {

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

        horizontalScrollView1.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event)
            {
                //  Disallow the touch request for parent scroll on touch of child view
                parentScrollView.requestDisallowInterceptTouchEvent(true);
                return false;
            }
        });
        listView1.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event)
            {
                //  Disallow the touch request for parent scroll on touch of child view
                parentScrollView.requestDisallowInterceptTouchEvent(true);
                return false;
            }
        });
        listView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                Toast.makeText(getApplicationContext(), "Clicked "+parent.getItemAtPosition(position).toString(), Toast.LENGTH_SHORT).show();

            }

        });
        listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                Toast.makeText(getApplicationContext(), "Clicked "+parent.getItemAtPosition(position).toString(), Toast.LENGTH_SHORT).show();

            }

        });

        listView2.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event)
            {
                //  Disallow the touch request for parent scroll on touch of child view
                parentScrollView.requestDisallowInterceptTouchEvent(true);
                return false;
            }
        });
        horizontalScrollView2.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event)
            {
                //  Disallow the touch request for parent scroll on touch of child view
                parentScrollView.requestDisallowInterceptTouchEvent(true);
                return false;
            }
        });
        /*imageView1.setOnClickListener(this);
        imageView2.setOnClickListener(this);
        imageView3.setOnClickListener(this);*/
        IVimage1.setOnClickListener(this);
        IVimage2.setOnClickListener(this);
        IVimage3.setOnClickListener(this);
        IVimage4.setOnClickListener(this);
        IVimage5.setOnClickListener(this);
        IVimage6.setOnClickListener(this);
        imageView1.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event)
            {
                //  Disallow the touch request for parent scroll on touch of child view
                parentScrollView.requestDisallowInterceptTouchEvent(true);
                Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();

                return false;
            }
        });

        imageView2.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event)
            {
                //  Disallow the touch request for parent scroll on touch of child view
                parentScrollView.requestDisallowInterceptTouchEvent(true);
                Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();

                return false;
            }
        });
        imageView3.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event)
            {
                //  Disallow the touch request for parent scroll on touch of child view
                parentScrollView.requestDisallowInterceptTouchEvent(true);
                Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();

                return false;
            }
        });

    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    @Override
    public void onClick(View v) {
        switch(v.getId()){
        case R.id.imageView1:
            Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.imageView2:
            Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.imageView3:
            Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.IVimage1:
            Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.IVimage2:
            Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.IVimage3:
            Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.IVimage4:
            Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.IVimage5:
            Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.IVimage6:
            Toast.makeText(getApplicationContext(), "Clicked "+v.getTag(), Toast.LENGTH_SHORT).show();
            break;  




        }
        // TODO Auto-generated method stub

    }
}

activity_main.xml -

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parentScrollView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_marginBottom="5dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:layout_marginTop="5dp"
    android:background="@drawable/login_bg" >

    <RelativeLayout
        android:id="@+id/relativeLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <ScrollView
            android:id="@+id/scrollView1"
            android:layout_width="fill_parent"
            android:layout_height="300dp" >

            <HorizontalScrollView
                android:id="@+id/horizontalScrollView1"
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:fillViewport="false" >

                <RelativeLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:background="@drawable/bg" >

                    <ImageView
                        android:id="@+id/imageView1"
                        android:layout_width="300dp"
                        android:layout_height="400dp"
                        android:tag="imageView1" />

                    <ImageView
                        android:id="@+id/imageView2"
                        android:layout_width="300dp"
                        android:layout_height="400dp"
                        android:layout_toRightOf="@+id/imageView1"
                        android:tag="imageView2" />

                    <ImageView
                        android:id="@+id/imageView3"
                        android:layout_width="300dp"
                        android:layout_height="400dp"
                        android:layout_toRightOf="@+id/imageView2"
                        android:tag="imageView3" />
                </RelativeLayout>
            </HorizontalScrollView>
        </ScrollView>

        <ListView
            android:id="@+id/listView1"
            android:layout_width="500dp"
            android:layout_height="400dp"
            android:layout_below="@+id/scrollView1"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="5dp"
            android:background="@drawable/ic_launcherwrweq" >
        </ListView>

        <HorizontalScrollView
            android:id="@+id/horizontalScrollView2"
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            android:layout_below="@+id/listView1"
            android:layout_centerHorizontal="true"
            android:layout_gravity="center"
            android:layout_marginTop="5dp"
            android:background="@drawable/claim_detail_header_bg"
            android:fillViewport="true" >

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <ImageView
                    android:id="@+id/IVimage1"
                    android:layout_width="125dp"
                    android:layout_height="125dp"
                    android:padding="15dp"
                    android:src="@drawable/a"
                    android:tag="a" >
                </ImageView>

                <ImageView
                    android:id="@+id/IVimage2"
                    android:layout_width="125dp"
                    android:layout_height="125dp"
                    android:padding="15dp"
                    android:src="@drawable/b"
                    android:tag="b" >
                </ImageView>

                <ImageView
                    android:id="@+id/IVimage3"
                    android:layout_width="125dp"
                    android:layout_height="125dp"
                    android:padding="15dp"
                    android:src="@drawable/c"
                    android:tag="c" >
                </ImageView>

                <ImageView
                    android:id="@+id/IVimage4"
                    android:layout_width="125dp"
                    android:layout_height="125dp"
                    android:padding="15dp"
                    android:src="@drawable/g"
                    android:tag="g" >
                </ImageView>

                <ImageView
                    android:id="@+id/IVimage5"
                    android:layout_width="125dp"
                    android:layout_height="125dp"
                    android:padding="15dp"
                    android:src="@drawable/e"
                    android:tag="e" >
                </ImageView>

                <ImageView
                    android:id="@+id/IVimage6"
                    android:layout_width="125dp"
                    android:layout_height="125dp"
                    android:padding="15dp"
                    android:src="@drawable/f"
                    android:tag="f" >
                </ImageView>
            </LinearLayout>
        </HorizontalScrollView>

        <ListView
            android:id="@+id/listView2"
            android:layout_width="500dp"
            android:layout_height="400dp"
            android:layout_below="@+id/horizontalScrollView2"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="5dp"
            android:background="@drawable/ic_launcherwrweq" >
        </ListView>
    </RelativeLayout>

</ScrollView>

list_item.xml (pour ListView) -

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:textSize="25sp"
    android:maxLines="1"
    android:singleLine="true"
/>



childScrollView.setOnTouchListener(new View.OnTouchListener() {

      @Override
    public boolean onTouch(View v, MotionEvent event) {

        int action = event.getAction();
        switch (action) {
        case MotionEvent.ACTION_DOWN:
           // Disallow ScrollView to intercept touch events.
          v.getParent().requestDisallowInterceptTouchEvent(true);
           break;

        case MotionEvent.ACTION_UP:
            // Allow ScrollView to intercept touch events.
            v.getParent().requestDisallowInterceptTouchEvent(false);
            break;
        }

        return false;
    }
});

v.getParent () = parent scrollView.




[...] y a-t-il une déclaration officielle de leur part nous ordonnant de ne pas le faire?

Je pense qu'il y a bien que je n'arrive pas à le trouver dans mes notes. Je sais que j'ai trouvé une telle déclaration en essayant d'avoir une vue de défilement dans une activité de liste. Je pense qu'il y a en fait une logique "bug" dans la façon dont le système d'interface utilisateur Android traite des scrollables imbriqués qui devraient probablement être mieux détectés et communiqués au développeur. Mais mon conseil est ...

En fin de compte, il est préférable de considérer une seule vue défilante pour le bien de l'utilisateur. C'est comme avoir des barres de défilement à l'intérieur des barres de défilement sur une page HTML; C'est peut-être légal, mais c'est une expérience utilisateur terrible.