Android的协调滚动的几种实现方式

上一期,我们讲了嵌套滚动的实现方式,为什么有了嵌套滚动还需要协调滚动这种方式呢?(不细讲原理,本文只探讨实现的方式与步骤!)

那在一些细度化的操作中,如我们需要一些控件随着滚动布局做一些粒度比较小的动画、移动等操作,那么我们就需要监听滚动,然后改变当前控件的属性。

如何实现这种协调滚动的布局呢?我们使用 CoordinatorLayout AppBarLayout 或者 CoordinatorLayout Behavior 实现,另一种方案是 MotionLayout。我们看看都是怎么实现的吧。

一、CoordinatorLayout Behavior

CoordinatorLayout 顾名思义是协调布局,其原理很简单,在onMeasure()的时候保存childView,通过 PreDrawListener监听childView的变化,最终通过双层for循环找到对应的Behavior,分发任务即可。CoordinatorLayout实现了NestedScrollingParent2,那么在childView实现了NestedScrollingChild方法时候也能解决滑动冲突问题。

而Behavior就是一个应用于View的观察者模式,一个View跟随者另一个View的变化而变化,或者说一个View监听另一个View。

在Behavior中,被观察View 也就是事件源被称为denpendcy,而观察View,则被称为child。

一般自定义Behavior来说分两种情况:

  • 监听另一个view的状态变化,例如大小、位置、显示状态等
  • 监听CoordinatorLayout里的滑动状态

这里我们以之前的效果为主来实现自定义的Behavior,先设置NestedScrollView在ImageView下面:

public class MyScrollBehavior extends ViewOffsetBehavior<NestedScrollView> {
    private int topImgHeight;
    private int topTextHeight;
    public MyScrollBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull NestedScrollView child,
                                   @NonNull View dependency) {
        return dependency instanceof ImageView ;
    }
    @Override
    protected void layoutChild(CoordinatorLayout parent, NestedScrollView child, int layoutDirection) {
        super.layoutChild(parent, child, layoutDirection);
        if (topImgHeight == 0) {
            final List<View> dependencies = parent.getDependencies(child);
            for (int i = 0, z = dependencies.size(); i < z; i  ) {
                View view = dependencies.get(i);
                if (view instanceof ImageView) {
                    topImgHeight = view.getMeasuredHeight();
                } 
            }
        }
        child.setTop(topImgHeight);
        child.setBottom(child.getBottom()   topImgHeight);
    }
}

然后设置监听CoordinatorLayout里的滑动状态,ImageView做同样的滚动

public class MyImageBehavior extends CoordinatorLayout.Behavior<View> {
    private int topBarHeight = 0;  //负图片高度
    private int downEndY = 0;   //默认为0
    public MyImageBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
                                       @NonNull View child, @NonNull View directTargetChild,
                                       @NonNull View target, int axes, int type) {
        //监听垂直滚动
        return (axes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
    }
    @Override
    public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child,
                                  @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
        if (topBarHeight == 0) {
            topBarHeight = -child.getMeasuredHeight();
        }
        float transY = child.getTranslationY() - dy;
        //处理上滑
        if (dy > 0) {
            if (transY >= topBarHeight) {
                translationByConsume(child, transY, consumed, dy);
                translationByConsume(target, transY, consumed, dy);
            } else {
                translationByConsume(child, topBarHeight, consumed, (child.getTranslationY() - topBarHeight));
                translationByConsume(target, topBarHeight, consumed, (child.getTranslationY() - topBarHeight));
            }
        }
        if (dy < 0 && !target.canScrollVertically(-1)) {
            //处理下滑
            if (transY >= topBarHeight && transY <= downEndY) {
                translationByConsume(child, transY, consumed, dy);
                translationByConsume(target, transY, consumed, dy);
            } else {
                translationByConsume(child, downEndY, consumed, (downEndY - child.getTranslationY()));
                translationByConsume(target, downEndY, consumed, (downEndY - child.getTranslationY()));
            }
        }
    }
    @Override
    public boolean onNestedFling(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, float velocityX, float velocityY, boolean consumed) {
        return super.onNestedFling(coordinatorLayout, child, target, velocityX,
                velocityY, consumed);
    }
    private void translationByConsume(View view, float translationY, int[] consumed, float consumedDy) {
        consumed[1] = (int) consumedDy;
        view.setTranslationY(translationY);
    }
}

分别为ImageView和NestedScrollView设置对应的 Behavior。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical">
    <com.guadou.lib_baselib.view.titlebar.EasyTitleBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:Easy_title="CoordinatorLayout Behavior" />
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageView
            android:layout_width="150dp"
            android:layout_height="150dp"
            app:layout_behavior="com.google.android.material.appbar.MyImageBehavior"
            android:layout_gravity="center_horizontal"
            android:contentDescription="我是测试的图片"
            android:src="@mipmap/ic_launcher" />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="#ccc"
            android:gravity="center"
            android:text="我是测试的分割线"
            android:visibility="gone" />
        <androidx.core.widget.NestedScrollView
            android:id="@ id/nestedScroll"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_behavior="com.google.android.material.appbar.MyScrollBehavior">
            <TextView
                android:id="@ id/nestedScrollLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/scroll_content" />
        </androidx.core.widget.NestedScrollView>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

我们先把TextView隐藏先不处理TextView。效果如下:

这样我们就实现了自定义 Behavior 监听滚动的实现。那么我们加上TextView 的 Behavior 监听ImageView的滚动,做对应的滚动。

先修改 MyScrollBehavior 让他在ImageView和TextView下面

public class MyScrollBehavior extends ViewOffsetBehavior<NestedScrollView> {
    private int topImgHeight;
    private int topTextHeight;
    public MyScrollBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull NestedScrollView child,
                                   @NonNull View dependency) {
        return dependency instanceof ImageView || dependency instanceof TextView ;
    }
    @Override
    protected void layoutChild(CoordinatorLayout parent, NestedScrollView child, int layoutDirection) {
        super.layoutChild(parent, child, layoutDirection);
        if (topImgHeight == 0) {
            final List<View> dependencies = parent.getDependencies(child);
            for (int i = 0, z = dependencies.size(); i < z; i  ) {
                View view = dependencies.get(i);
                if (view instanceof ImageView) {
                    topImgHeight = view.getMeasuredHeight();
                } else if (view instanceof TextView) {
                    topTextHeight = view.getMeasuredHeight();
                    view.setTop(topImgHeight);
                    view.setBottom(view.getBottom()   topImgHeight);
                }
            }
        }
        child.setTop(topImgHeight   topTextHeight);
        child.setBottom(child.getBottom()   topImgHeight   topTextHeight);
    }
}

然后设置监听ImageView的滚动:

public class MyTextBehavior extends CoordinatorLayout.Behavior<View> {
    private int imgHeight;
    public MyTextBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull View child, @NonNull View dependency) {
        return dependency instanceof ImageView;
    }
    @Override
    public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull View child, @NonNull View dependency) {
        //跟随ImageView滚动,ImageView滚动多少我滚动多少
        float translationY = dependency.getTranslationY();
        if (imgHeight == 0) {
            imgHeight = dependency.getHeight();
        }
        float offsetTranslationY = imgHeight   translationY;
        child.setTranslationY(offsetTranslationY);
        return true;
    }
}

xml修改如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical">
    <com.guadou.lib_baselib.view.titlebar.EasyTitleBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:Easy_title="CoordinatorLayout Behavior" />
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ImageView
            android:layout_width="150dp"
            android:layout_height="150dp"
            app:layout_behavior="com.google.android.material.appbar.MyImageBehavior"
            android:layout_gravity="center_horizontal"
            android:contentDescription="我是测试的图片"
            android:src="@mipmap/ic_launcher" />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="#ccc"
            app:layout_behavior="com.google.android.material.appbar.MyTextBehavior"
            android:gravity="center"
            android:text="我是测试的分割线"
            android:visibility="visible" />
        <androidx.core.widget.NestedScrollView
            android:id="@ id/nestedScroll"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_behavior="com.google.android.material.appbar.MyScrollBehavior">
            <TextView
                android:id="@ id/nestedScrollLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/scroll_content" />
        </androidx.core.widget.NestedScrollView>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

Ok,修改完成之后我们看看最终的效果:

看到上面的示例,我们把常用的几种 Behavior 都使用了一遍,系统的ViewOffsetBehavior 和监听滚动的 Behavior 监听View的 Behavior。

为了实现这么一个简单的效果就用了这么多类,这么复杂。我分分钟就能实现!

行行,我知道你厉害,这不是为了演示同样的效果,使用不同的方式实现嘛。通过 Behavior 可以实现一些嵌套滚动不能完成的效果,比如鼎鼎大名的支付宝首页效果,美团详情效果等。Behavior 更加的灵活,控制的粒度也更加的细。

但是如果只是简单实现上面的效果,我们可以用 AppBarLayout 内部自带的 Behavior 也能实现类似的效果,AppBarLayout内部已经封装并使用了 Behavior 。我们看看如何实现。

二、CoordinatorLayout AppBarLayout

其实内部也是基于 Behavior 实现的,内部实现为 HeaderBehavior 和 HeaderScrollingViewBehavior 。

对一些场景使用进行了封装,滚动效果,吸顶效果,折叠效果等。我们看看同样的效果,使用 AppBarLayout 如何实现吧:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical">
    <com.guadou.lib_baselib.view.titlebar.EasyTitleBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:Easy_title="CoordinatorLayout AppBarLayout" />
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:elevation="0dp"
            android:background="@color/white"
            android:orientation="vertical">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:contentDescription="我是测试的图片"
                android:src="@mipmap/ic_launcher"
                app:layout_scrollFlags="scroll" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#ccc"
                android:gravity="center"
                android:text="我是测试的分割线"
                app:layout_scrollFlags="noScroll" />
        </com.google.android.material.appbar.AppBarLayout>
        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/scroll_content" />
        </androidx.core.widget.NestedScrollView>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

效果:

So Easy ! 真的是太方便了,类似的效果我们都能使用 AppbarLayout 来实现,比如一些详情页面顶部图片,下面列表或ViewPager的都可以使用这种方式,更加的便捷。

三、MotionLayout

不管怎么说,AppbarLayout 只能实现一些简单的效果,如果想要一些粒度比较细的效果,我们还得使用自定义 Behavior 来实现,但是它的实现确实是有点复杂,2019年谷歌推出了 MotionLayout 。

淘宝的出现可以说让世上没有难做的生意,那么 MotionLayout 的出现可以说让 Android 没有难实现的动画了。不管是动画效果,滚动效果,MotionLayout 绝杀!能用 Behavior 实现的 MotionLayout 几乎是都能做。

使用 MotionLayout 我们只需要定义起始点和结束点就行了,我们这里不需要根据百分比Fram进行别的操作,所以只定义最简单的使用。

我们看看如何用 MotionLayout 实现同样的效果:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/white"
    android:orientation="vertical">
    <com.guadou.lib_baselib.view.titlebar.EasyTitleBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:Easy_title="MotionLayout的动作" />
    <androidx.constraintlayout.motion.widget.MotionLayout
        android:layout_width="match_parent"
        android:layout_weight="1"
        app:layoutDescription="@xml/scene_scroll_13"
        android:layout_height="0dp">
        <ImageView
            android:id="@ id/iv_img"
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:scaleType="centerCrop"
            android:contentDescription="我是测试的图片"
            android:src="@mipmap/ic_launcher" />
        <TextView
            android:id="@ id/tv_message"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="#ccc"
            android:gravity="center"
            android:text="我是测试的分割线"
            tools:layout_editor_absoluteY="150dp" />
        <androidx.core.widget.NestedScrollView
            android:id="@ id/nestedScroll"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:id="@ id/nestedScrollLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/scroll_content" />
        </androidx.core.widget.NestedScrollView>
    </androidx.constraintlayout.motion.widget.MotionLayout>
</LinearLayout>

定义的scene_scroll_13.xml

<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">
    <Transition
        motion:constraintSetEnd="@ id/end"
        motion:constraintSetStart="@ id/start">
        <OnSwipe
            motion:dragDirection="dragUp"
            motion:touchAnchorId="@id/nestedScroll" />
    </Transition>
    <ConstraintSet android:id="@ id/start">
        <Constraint
            android:id="@id/iv_img"
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:translationY="0dp"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toRightOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@id/tv_message"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            motion:layout_constraintTop_toBottomOf="@id/iv_img" />
        <Constraint
            android:id="@id/nestedScroll"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintTop_toBottomOf="@id/tv_message" />
    </ConstraintSet>
    <ConstraintSet android:id="@ id/end">
        <Constraint
            android:id="@id/iv_img"
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:translationY="-150dp"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toRightOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@id/tv_message"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            motion:layout_constraintLeft_toLeftOf="parent"
            motion:layout_constraintRight_toRightOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@id/nestedScroll"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintTop_toBottomOf="@id/tv_message" />
    </ConstraintSet>
</MotionScene>

效果:

非常的简单,效果很流畅,性能也很好。有时候都不得不感慨一句,有了 MotionLayout 要你 Behavior 何用。

总结

Android真的是太卷了,以前学RxJava Dagger2 NestedScrolling Behavior 等,这些都是很难学的,更难以应用,如果能学会,那都是高工了。现在谷歌新框架层出不穷,越来越易用了,越来越好入门了。以前学的都已经被淘汰,新入Android的同学已经可以无需门槛,直接学谷歌的脚手架就能完成效果了。

言归正传,这几种方案大家都理解了吗?什么时候需要用协调滚动,什么时候需要用嵌套滚动,大家可以做到心中有数。能用 MotionLayout 的还是推荐使用 MotionLayout 实现,毕竟实现简单,性能优秀嘛!

当然如果仅限这种效果来说,还有很多的方式实现如RV ListView,纯粹的自定义View也能实现是吧,自定义ViewGroup,ViewDragHelper一样能实现,就是稍微麻烦点,这里也仅从嵌套滚动和协调滚动这点来实现的。

好了,如果大家理解了协调滚动和嵌套滚动,那万变不离其宗,几乎应用开发中全部的滚动效果都是基于这两条,内部的具体实现方案几乎都是基于这6种方案来实现。

后面如果大家有兴趣,我会出一期超复杂的嵌套具体实现相关的功能,类似美团外卖点餐的页面分为上、中、下布局。下布局又分左右列表布局 ,还分上布局抽屉效果和中布局吸顶效果。

到此这篇关于Android嵌套滚动与协调滚动的几种实现方式的文章就介绍到这了,更多相关Android嵌套滚动内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Android嵌套滚动与协调滚动的实现方式汇总的更多相关文章

  1. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  4. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  5. Ionic – Splash Screen适用于iOS,但不适用于Android

    我有一个离子应用程序,其中使用CLI命令离子资源生成的启动画面和图标iOS版本与正在渲染的启动画面完美配合,但在Android版本中,只有在加载应用程序时才会显示白屏.我检查了config.xml文件,所有路径看起来都是正确的,生成的图像出现在相应的文件夹中.(我使用了splash.psd模板来生成它们.我错过了什么?这是config.xml文件供参考,我觉得我在这里做错了–解决方法在config.xml中添加以下键:它对我有用!

  6. ios – 无法启动iPhone模拟器

    /Library/Developer/CoreSimulator/Devices/530A44CB-5978-4926-9E91-E9DBD5BFB105/data/Containers/Bundle/Application/07612A5C-659D-4C04-ACD3-D211D2830E17/ProductName.app/ProductName然后,如果您在Xcode构建设置中选择标准体系结构并再次构建和运行,则会产生以下结果:dyld:lazysymbolbindingFailed:Symbol

  7. Xamarin iOS图像在Grid内部重叠

    heyo,所以在Xamarin我有一个使用并在其中包含一对,所有这些都包含在内.这在Xamarin.Android中看起来完全没问题,但是在Xamarin.iOS中,图像与标签重叠.我不确定它的区别是什么–为什么它在Xamarin.Android中看起来不错但在iOS中它的全部都不稳定?

  8. 在iOS上向后播放HTML5视频

    我试图在iPad上反向播放HTML5视频.HTML5元素包括一个名为playbackRate的属性,它允许以更快或更慢的速率或相反的方式播放视频.根据Apple’sdocumentation,iOS不支持此属性.通过每秒多次设置currentTime属性,可以反复播放,而无需使用playbackRate.这种方法适用于桌面Safari,但似乎在iOS设备上的搜索限制为每秒1次更新–在我的情况下太慢了.有没有办法在iOS设备上向后播放HTML5视频?解决方法iOS6Safari现在支持playbackRat

  9. 使用 Swift 语言编写 Android 应用入门

    Swift标准库可以编译安卓armv7的内核,这使得可以在安卓移动设备上执行Swift语句代码。做梦,虽然Swift编译器可以胜任在安卓设备上编译Swift代码并运行。这需要的不仅仅是用Swift标准库编写一个APP,更多的是你需要一些框架来搭建你的应用用户界面,以上这些Swift标准库不能提供。简单来说,构建在安卓设备上使用的Swiftstdlib需要libiconv和libicu。通过命令行执行以下命令:gitclonegit@github.com:SwiftAndroid/libiconv-libi

  10. Android – 调用GONE然后VISIBLE使视图显示在错误的位置

    我有两个视图,A和B,视图A在视图B上方.当我以编程方式将视图A设置为GONE时,它将消失,并且它正下方的视图将转到视图A的位置.但是,当我再次将相同的视图设置为VISIBLE时,它会在视图B上显示.我不希望这样.我希望视图B回到原来的位置,这是我认为会发生的事情.我怎样才能做到这一点?编辑–代码}这里是XML:解决方法您可以尝试将两个视图放在RelativeLayout中并相对于彼此设置它们的位置.

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部