【问题标题】:Pass scroll event to another view将滚动事件传递给另一个视图
【发布时间】:2015-10-26 12:08:24
【问题描述】:

我一直在使用 android 设计支持库来折叠工具栏布局。 一切正常,除了我想在 collapsingBarlayout 中滚动滚动内容的整个视图

这是 xml 布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">


    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="420dp"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            android:fitsSystemWindows="true">

            <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/collapsing_toolbar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                app:contentScrim="?attr/colorPrimary"
                app:expandedTitleMarginStart="48dp"
                app:expandedTitleMarginEnd="64dp"
                android:fitsSystemWindows="true">

                <android.support.v4.view.ViewPager
                    xmlns:android="http://schemas.android.com/apk/res/android"
                    android:id="@+id/pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:scaleType="centerCrop"
                    app:layout_collapseMode="parallax"
                    app:layout_collapseParallaxMultiplier="0.8"
                    android:fitsSystemWindows="true"
                    app:layout_behavior="@string/appbar_scrolling_view_behavior"
                    />

                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                    app:layout_collapseMode="pin" />

            </android.support.design.widget.CollapsingToolbarLayout>

        </android.support.design.widget.AppBarLayout>

        <android.support.v4.widget.NestedScrollView
            android:id="@+id/scroll_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <include layout="@layout/activity_item_detail"
                />

        </android.support.v4.widget.NestedScrollView>

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_vertical_margin"
            android:clickable="true"
            android:src="@android:drawable/ic_menu_call"
            app:layout_anchor="@+id/appbar"
            app:layout_anchorGravity="bottom|right|end"
            style="@style/floating_action_button"
            />

    </android.support.design.widget.CoordinatorLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>

如果触摸除 viewpager/工具栏之外的任何内容,则滚动内容会起作用。 我也需要在视图寻呼机上垂直触摸和滚动时获得相同的滚动体验。 曾尝试覆盖视图寻呼机的 onTouchEvent 以将 ACTION_UP 运动事件传递给 scroll_view。

nestedScrollView.post(new Runnable() {
    @Override
    public void run() {
        mPager.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    return nestedScrollView.onTouchEvent(event);
                } else {
                    return v.onTouchEvent(event);
                }
            }
        });
    }
});

但它不起作用。请帮助解决方法/任何可以快速解决此问题的黑客。

【问题讨论】:

    标签: android android-layout android-design-library androiddesignsupport


    【解决方案1】:

    找出正在接收触摸事件的视图。在这种特定情况下,ViewPager 正在接收我们想要覆盖的触摸事件。一旦你有了接收触摸事件的视图,你就可以安装一个手势检测器。看看这个guide,尤其是在

    检测支持的手势子集

    通过这种方式,您可以管理在外部视图上执行的所有手势,并且您可以以某种方式对手势做出反应。
    注意:当您扩展 GestureDetector.SimpleOnGestureListener 时,请记住覆盖onDown 方法,否则您将不会收到任何其他事件。

    编辑

    我已经测试了我对此github project 的建议。如果你这样修改CheeseDetailActivity,当你在奶酪图像中滚动时,你会得到onScroll事件的调用。

    public class CheeseDetailActivity extends AppCompatActivity {
    
        public static final String EXTRA_NAME = "cheese_name";
    
        private GestureDetectorCompat mDetector;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_detail);
    
            MyGestureListener listener = new MyGestureListener();
            mDetector = new GestureDetectorCompat(this, new MyGestureListener());
            View root = findViewById(R.id.pager);
            root.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    return mDetector.onTouchEvent(event);
                }
            });
    
    
            Intent intent = getIntent();
            final String cheeseName = intent.getStringExtra(EXTRA_NAME);
    
            final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    
            CollapsingToolbarLayout collapsingToolbar =
                    (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
            collapsingToolbar.setTitle(cheeseName);
    
            loadBackdrop();
        }
    
        private void loadBackdrop() {
            final ImageView imageView = (ImageView) findViewById(R.id.backdrop);
            Glide.with(this).load(Cheeses.getRandomCheeseDrawable()).centerCrop().into(imageView);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.sample_actions, menu);
            return true;
        }
    
        class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
            private static final String DEBUG_TAG = "Gestures";
    
            @Override
            public boolean onDown(MotionEvent event) {
                Log.d(DEBUG_TAG,"onDown: " + event.toString());
                return true;
            }
    
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                Log.d(DEBUG_TAG, "onScroll: ");
                //Implement functionality you want e.g. horiontal scroll changes viewpager item, vertical scroll collpases the toolbar
                return true;
            }
        }
    }
    

    【讨论】:

    • 谢谢@Mimmo。在跟踪我收到 onTouch 事件的位置之后,它起作用了,在我的例子中是 ViewPager 元素。我将自定义的 gestureListener 应用到 viewpager 并且它起作用了。
    • @IntoTheWild:你能指导我如何在 Onscroll() 中实现整个内容的垂直滚动吗?当我尝试在 scrollBy() 中使用 distanceY 参数滚动 appbar 布局时,我没有得到想要的解决方案。
    • 我有更简单的问题。我在 viewpager 中有 recylerview,它再次包装在 Nestedscrollview 中。但是 Recylerview 不会将滚动传递给 NestedScrollView 以折叠工具栏。你能发布完整的解决方案吗?
    【解决方案2】:

    您的寻呼机内容需要启用嵌套滚动。完成此操作的最简单方法是将其包装在 NestedScrollView 中:

    fragment_image.xml

    <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/backdrop"
            android:layout_width="match_parent"
            android:layout_height="@dimen/detail_backdrop_height"
            android:scaleType="centerCrop" />
    </android.support.v4.widget.NestedScrollView>
    

    但是这会导致ImageView 的父级高度不确定,因此您必须将其设置为某个固定高度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 2013-08-14
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      相关资源
      最近更新 更多