ScrollView内部嵌套ScrollView

32

我知道Google的人要求我们不要在一个可滚动视图中再放入另一个可滚动视图,但他们有任何官方声明直接指示我们不这样做吗?


谢谢您的回复,但这是我正在开发的应用程序的要求... :( ... 我尝试了很多方法,从重写触摸事件到创建自定义滚动视图,但似乎都不起作用。我需要官方文档,以便我可以向我的上级解释。 - AjOnFire
Blindstuff,你有检查过 iPhone 吗?例如,当你有一个 ListView,在 Scroll 内部时,你可以根据焦点或位置同时滚动它们。 - desgraci
你确定ListView后面还有另一个ScrollView吗?ListView本身就可以滚动。 - banzai86
1
https://dev59.com/-m855IYBdhLWcg3wKxHc#11554823 - Atul Bhardwaj
12个回答

66

试试这个

注意: 这里的parentScrollView指的是外部滚动视图,而childScrollView指的是内部滚动视图。

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

+1 你的方法在大部分情况下都是有效的。谢谢,但我的问题是关于Android官方声明的文档。 - AjOnFire
我赞成你的回答,但是我有一个问题。为什么需要为父滚动设置监听器“findViewById(R.id.child_scroll). getParent().requestDisallowInterceptTouchEvents(false)”?我有一个不可滚动的TextView和一个可滚动的EditText在ScrollView中。我永远不希望EditText内部的触摸事件传递到父级,因此一旦EditText disallowInterceptTouchEvent被设置为false,我永远不希望它改变。您当前的代码只有在用户触摸设置为true的特定childView之外时才会调用parentScrollView onTouch方法。 - flobacca
继续我的上面的评论- 然后一旦用户触摸了特定的childView,childview requestDisallowInterceptTouchEvent再次设置为true。那么,为什么要将其设置为false呢? - flobacca
1
我使用了你的代码的简化版本,用于在ScrollView中嵌套NumberPicker。它可以正常工作,谢谢 :-) - Luke47
1
有人能提供一下这里的布局是什么样子吗?我无法在scrollview中添加超过一个直接子元素。里面的scrollview对我来说不起作用。 - cppdev
@cppdev 你可以像这样使用 <ScrollView> 这是父级滚动视图 <LinearLayout> <ScrollView> 这是子级滚动视图 </ScrollView> </LinearLayout> </ScrollView> - Atul Bhardwaj

17

这个足够接近吗?

不要在ListView中使用HorizontalScrollView,因为ListView会自己处理滚动。最重要的是,这样做会破坏ListView处理大型列表的所有优化,因为它有效地强制ListView显示其整个项目列表以填充HorizontalScrollView提供的无限容器。

http://developer.android.com/reference/android/widget/HorizontalScrollView.html

更新:

如果你被迫使用两个维度的滚动视图,可以考虑使用这个: 这篇博客 of blog.gorges.us/2010/06/android-two-dimensional-scrollview/

我没有用过这个,但可能是一个合理的方法。


嗨,Pedro,首先感谢您的回复。我的应用程序包含一个需要滚动视图(因为它比屏幕大)的背景图像,并且该背景图像将包含另一张也需要滚动视图(因为它也比屏幕大)的图像。因此,我的需求是在垂直滚动视图内部拥有一个垂直滚动视图... 对此有任何想法将非常有帮助? - AjOnFire
你尝试过这样做吗?你需要为内部的ScrollView指定一些高度(比如200dip),而外部的ScrollView应该与父视图的大小匹配(整个屏幕,我猜)。尝试一下,并使用不同的背景颜色,以便知道你得到了什么。 - Pedro Loureiro
1
我已经尝试过了...当我尝试滚动内部滚动视图时,即使我重写内部的onTouch()方法返回true,触摸事件仍然被传递到外部滚动视图...因此只有外部滚动视图是可滚动的。 - AjOnFire
我们可以在ListView中使用HorizontalScrollView。在我的案例中,这是可行的并且运作良好。请查看"Atul Bhardwaj"在这个帖子中给出的答案[链接] (https://dev59.com/Yuo6XIcBkEYKwwoYSCpJ)。 - Atul Bhardwaj
很遗憾,你的Gorges博客链接似乎已经失效了,可能是文章被删除了。你能否找回它或者删除这个失效的链接呢?谢谢! - ForceMagic
1
互联网档案馆来拯救了:https://web.archive.org/web/20130305091318/http://blog.gorges.us/2010/06/android-two-dimensional-scrollview(已更新帖子) - Pedro Loureiro

16

Atul Bhardwaj的答案是正确的方法。但是如果有人需要将其应用到一个ScrollView中,而您对父级的控制较少,我认为以下方法就足够灵活,并且它就是应该工作的方式:

private void makeMyScrollSmart() {
    myScroll.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View __v, MotionEvent __event) {
            if (__event.getAction() == MotionEvent.ACTION_DOWN) {
                //  Disallow the touch request for parent scroll on touch of child view
                requestDisallowParentInterceptTouchEvent(__v, true);
            } else if (__event.getAction() == MotionEvent.ACTION_UP || __event.getAction() == MotionEvent.ACTION_CANCEL) {
                // Re-allows parent events
                requestDisallowParentInterceptTouchEvent(__v, false);
            }
            return false;
        }
    });
}

private void requestDisallowParentInterceptTouchEvent(View __v, Boolean __disallowIntercept) {
    while (__v.getParent() != null && __v.getParent() instanceof View) {
        if (__v.getParent() instanceof ScrollView) {
            __v.getParent().requestDisallowInterceptTouchEvent(__disallowIntercept);
        }
        __v = (View) __v.getParent();
    }
}

该函数的作用是为 myScroll 添加一个触摸监听器,在子元素开始触摸时禁用父元素的触摸截获功能,当触摸实际结束时再重新启用。您不需要引用父 ScrollView,也不必是直接的父级... 它会遍历显示列表直到找到它。

在我看来,这两种方式兼得。


双下划线名称有什么问题?此外,最好定位父视图一次并保留对其的引用,因为它可能永远不会改变。最后,一些非ScrollView小部件(如ViewPager)需要相同的解决方法。 - kar
双下划线只是我私下用来跟踪方法/函数参数的约定;您可以将其更改为任何您想要的内容。在上面的示例中,我不使用引用来保持简单、干净和安全(例如,没有引用保存在内存中)。对于非ScrollView小部件,请更改代码以匹配您正在使用的任何超类 - 上面的代码可以作为要做什么的一般想法。 - zeh
如果我有一个嵌套布局怎么办? - Cyph3rCod3r
requestDisallowInterceptTouchEvent(boolean) 方法会自我递归向上调用。为什么您要再次向上调用 requestDisallowInterceptTouchEvent(__disallowIntercept) 呢? - Yingpei Zeng

4
这里有一个可能的解决方案。当到达子ScrollView的末尾时,将控制权传递给父ScrollView进行滚动。它适用于ScrollView和ListView在ScrollView中的情况。
步骤1 - 设置父OnTouchListener。
parentScroll.setOnTouchListener(new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        v.getParent().requestDisallowInterceptTouchEvent(false);
        return false;
    }
});

步骤2 - 设置子元素的OnTouchListener(ScrollView或ListView)
aChildScrollView.setOnTouchListener(new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event)
    {
        v.getParent().requestDisallowInterceptTouchEvent(shouldRequestDisallowIntercept((ViewGroup) v, event));
        return false;
    }
});
aListView.setOnTouchListener(new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        v.getParent().requestDisallowInterceptTouchEvent(shouldRequestDisallowIntercept((ViewGroup) v, event));
        return false;
    }
});

步骤3 - 下面是正确功能所需的必要魔术方法

protected boolean shouldRequestDisallowIntercept(ViewGroup scrollView, MotionEvent event) {
    boolean disallowIntercept = true;
    float yOffset = getYOffset(event);

    if (scrollView instanceof ListView) {
        ListView listView = (ListView) scrollView;
        if (yOffset < 0 && listView.getFirstVisiblePosition() == 0 && listView.getChildAt(0).getTop() >= 0) {
            disallowIntercept = false;
        }
        else if (yOffset > 0 && listView.getLastVisiblePosition() == listView.getAdapter().getCount() - 1 && listView.getChildAt(listView.getChildCount() - 1).getBottom() <= listView.getHeight()) {
            disallowIntercept = false;
        }
    }
    else {
        float scrollY = scrollView.getScrollY();
        disallowIntercept = !((scrollY == 0 && yOffset < 0) || (scrollView.getHeight() + scrollY == scrollView.getChildAt(0).getHeight() && yOffset >= 0));

    }

    return disallowIntercept;
}

protected float getYOffset(MotionEvent ev) {
    final int historySize = ev.getHistorySize();
    final int pointerCount = ev.getPointerCount();

    if (historySize > 0 && pointerCount > 0) {
        float lastYOffset = ev.getHistoricalY(pointerCount - 1, historySize - 1);
        float currentYOffset = ev.getY(pointerCount - 1);

        float dY = lastYOffset - currentYOffset;

        return dY;
    }

    return 0;
}

2

我认为他们有官方声明,指示我们不要这样做,尽管我在笔记中找不到。当我试图在列表活动中拥有一个滚动视图时,我知道我发现了这样的声明。我认为实际上Android UI系统处理嵌套可滚动视图存在逻辑焦点“漏洞”,这可能应该更好地被检测并传达给开发人员。但我的建议是……

最终考虑用户体验,最好考虑单个可滚动视图。这就像在HTML页面内部有滚动条;它可能是合法的,但这是一个可怕的用户体验。


我在许多iPhone应用程序中看到过这种情况,它仍然很用户友好。 - Joshua Partogi

2
我找到了一个非常好的解决方案。请使用这段代码。
    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;
        }
    });

这肯定会起作用。请尝试并让我知道如果无法工作。

1
实际上,关于此事有一份官方声明,可以在一个相当古老的视频 "ListView的世界" 中找到。他们说不要将可滚动视图放在另一个可滚动视图内(当两个视图方向相同时)。
然而,现在我们有了一个新的视图,允许两个视图同时滚动,可能是为了展示一个酷炫的效果:

https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html

我没有找到任何关于这个的例子,所以我写的只是猜测它做什么及其用途。


1

0

这里,我创建了一个与ScrollView相关的示例项目。其中一个视图可以双向滚动。快来看看吧:

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(用于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"
/>

0

你可以在另一个ScrollView中放置一个ScrollView。只需扩展子ScrollView以覆盖onTouchEvent方法。就像这样

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;

public class ChildScrollView extends android.widget.ScrollView {
    private int parent_id;

    public ChildScrollView(Context context) {
        super(context);
    }

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

    public ChildScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接