文档章节

使用SlidingPaneLayout 实现仿微信的滑动返回

o
 osc_x4h57ch8
发布于 2018/04/24 15:20
字数 1304
阅读 8
收藏 0

精选30+云产品,助力企业轻松上云!>>>

上周,公司的项目改版要求加上一个右滑返回上一个界面,于是就在网上找了一些开源库打算实现.但是在使用的时候遇见了许多的问题.试了两天用过 https://github.com/ikew0ng/SwipeBackLayout ,https://github.com/r0adkll/Slidr等库都没成功.

然后在https://www.jianshu.com/p/c0a15bdc2690 看见了使用SlidingPaneLayout 来实现的一个滑动返回案例然后就看了看发现不错于是就使用了这个.

虽然上面链接里面已近写好啦.但是还是写一下代码:

先看看最终效果:

 

 

 

实现如下:

主要是在baesActivity里面

public class BaesActivity extends AppCompatActivity implements SlidingPaneLayout.PanelSlideListener{
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        initSlideBackClose();//滑动返回的设置
        super.onCreate(savedInstanceState);
    }

    private void initSlideBackClose() {
        if (isSupportSwipeBack()) {
           SlidingPaneLayout slidingPaneLayout = new SlidingPaneLayout(this);
            // 通过反射改变mOverhangSize的值为0,
            // 这个mOverhangSize值为菜单到右边屏幕的最短距离,
            // 默认是32dp,现在给它改成0
            try {
                Field overhangSize = SlidingPaneLayout.class.getDeclaredField("mOverhangSize");
                overhangSize.setAccessible(true);
                overhangSize.set(slidingPaneLayout, 0);
            } catch (Exception e) {
                e.printStackTrace();
            }
            slidingPaneLayout.setPanelSlideListener(this);
            slidingPaneLayout.setSliderFadeColor(getResources()
                    .getColor(android.R.color.transparent));

            // 左侧的透明视图
            View leftView = new View(this);
            leftView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            slidingPaneLayout.addView(leftView, 0);

            ViewGroup decorView = (ViewGroup) getWindow().getDecorView();


            // 右侧的内容视图
            ViewGroup decorChild = (ViewGroup) decorView.getChildAt(0);
            decorChild.setBackgroundColor(getResources()
                    .getColor(android.R.color.white));
            decorView.removeView(decorChild);
            decorView.addView(slidingPaneLayout);

            // 为 SlidingPaneLayout 添加内容视图
            slidingPaneLayout.addView(decorChild, 1);
        }
    }
    //设置是否使用滑动返回
    protected boolean isSupportSwipeBack() {
        return true;
    }

    @Override
    public void onPanelSlide(View panel, float slideOffset) {

    }

    @Override
    public void onPanelOpened(View panel) {
        finish();
    }

    @Override
    public void onPanelClosed(View panel) {

    }
}

然后让Acitivity继承baesActivity就可以了

public class MainActivity extends BaesActivity

看看效果

怎么会这样!

然后就去看看那需要改动,发现在BaesActivity里面写了一个方法:

//设置是否使用滑动返回
    protected boolean isSupportSwipeBack() {
        return true;
    }

在不需要返回的界面重写此方法并返回 false,就行了向这样

  @Override
    protected boolean isSupportSwipeBack() {
        return false;
    }

 

主界面不滑动的问题解决了,但是还有一个问题在滑动的时候左边显示的是一个白板,这怎么破?

这就要设置  activity 的 style了 在AndroidManifest.xml 文件里面找到 application 就是黄色那行,跳进去

<application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">//设置样式
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".TwoActivity"/>
        <activity android:name=".ThreeActivity"/>
    </application>

设置styles.xml ,添加黄色部分的内容

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--设置窗口背景为透明-->
        <item name ="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
    </style>

运行起来:

偶买噶! 我的首页怎么变成这样了,透明了?怎么办,

小事,因为我们设置了上面那两行的原因,现在只要把界面的根布局里面添加一个背景色就行了

<android.support.constraint.ConstraintLayout
    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:orientation="vertical"
    android:background="#f2f2f2"
    tools:context="com.mvp.tl.myslidingpanelayoutdemo.MainActivity">

    <Button
        android:id="@+id/next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="第一个,下一界面"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

OK,初步实现就这样了,但是这效果也太丑了吧!

嗯,现在来改改Activity的开启关闭的样式

还是在styles.xml 进行修改<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--设置窗口背景为透明-->
        <item name ="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <!--activity启动关闭样式-->
        <item name="android:windowAnimationStyle">@style/activityAnimation</item>
    </style>

<!--activity启动关闭动画-->

<style name="activityAnimation" parent="@android:style/Animation">

<item name="android:activityOpenEnterAnimation">@anim/in_from_right</item>

<item name="android:activityCloseExitAnimation">@anim/out_to_left</item>

</style>

anim/in_from_right.xml和anim/out_to_left在 

进行设置:

in_from_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fillAfter="true"
        android:fromXDelta="100%p"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toXDelta="0" />
</set>

out_to_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fillAfter="true"
        android:fromXDelta="0"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toXDelta="100%p" />
</set>

然后看看效果

OK,效果出来了.但是当它遇到ViewPager的时候呢?

怎么这样,ViewPager的右滑无法使用了,SlidingPaneLayout的右滑抢了ViewPager的滑动事件.怎么办

然后我就在网上找呀找.终于发现了  https://blog.csdn.net/dota_wy/article/details/52890870 自定义SlidingPaneLayout

import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.widget.SlidingPaneLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
/*
在使用侧滑菜单的时候如果主界面中有ViewPager的时候调用该自定义控件,避免二者的冲突事件的发生
 */
public class PageEnabledSlidingPaneLayout extends SlidingPaneLayout {
    private float mInitialMotionX;
    private float mInitialMotionY;
    private float mEdgeSlop;//手滑动的距离

    public PageEnabledSlidingPaneLayout(Context context) {
        this(context, null);
    }

    public PageEnabledSlidingPaneLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

        ViewConfiguration config = ViewConfiguration.get(context);
        mEdgeSlop = config.getScaledEdgeSlop();//getScaledTouchSlop是一个距离
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (MotionEventCompat.getActionMasked(ev)) {
            case MotionEvent.ACTION_DOWN: {
                mInitialMotionX = ev.getX();
                mInitialMotionY = ev.getY();
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                final float x = ev.getX();
                final float y = ev.getY();
                // The user should always be able to "close" the pane, so we only check
                // for child scrollability if the pane is currently closed.
                if (mInitialMotionX > mEdgeSlop && !isOpen() && canScroll(this, false,
                        Math.round(x - mInitialMotionX), Math.round(x), Math.round(y))) {

                    // How do we set super.mIsUnableToDrag = true?

                    // send the parent a cancel event
                    MotionEvent cancelEvent = MotionEvent.obtain(ev);
                    cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
                    return super.onInterceptTouchEvent(cancelEvent);
                }
            }
        }
        return super.onInterceptTouchEvent(ev);
    }
}

并用其替换BaesActivity 里面的SlidingPaneLayout 就可以了

OK,最终效果就这样完成了.

感谢 https://blog.csdn.net/dota_wy/article/details/52890870,

感谢 https://www.jianshu.com/p/c0a15bdc2690

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

2020-07-03:有1亿个数字,其中有2个是重复的,快速找到它,时间和空间要最优

福哥答案2020-07-03: 1.双重遍历。 时间复杂度是O(N^2)。 2.排序。 采用外部排序。时间复杂度是O(NlogN)。 3.遍历加哈希存储。 空间换时间,时间复杂度是O(N),空间复杂度是O(N)。这种方法适...

osc_ix000whh
26分钟前
17
0
O2OA开源免费开发平台:在O2门户页面中使用React(三)

在前面的章节中,我们介绍了两种在O2OA中使用React开发应用的方式,已经可以满足绝大多数的情况了。如果您考虑完全脱离O2的web服务器,自己搭建web服务器,那就请阅读本章。   我们还是使用...

O2OA企业信息化平台
26分钟前
21
0
harbor 2.0 搭建docker私有仓库

harbor Harbor 是一个CNCF基金会托管的开源的可信的云原生docker registry项目,可以用于存储、签名、扫描镜像内容,Harbor 通过添加一些常用的功能如安全性、身份权限管理等来扩展 docker r...

osc_l7zl78wt
28分钟前
20
0
Java并发编程(06):Lock机制下API用法详解

本文源码:GitHub·点这里 || GitEE·点这里 一、Lock体系结构 1、基础接口简介 Lock加锁相关结构中涉及两个使用广泛的基础API:ReentrantLock类和Condition接口,基本关系如下: Lock接口 ...

osc_kiub62pt
29分钟前
27
0
DNS存在的问题

1、域名缓存问题 本地做一个缓存,直接返回缓存数据。可能会导致全局负载均衡失败,因为上次进行的缓存,不一定是这次离客户最近的地方,可能会绕远路。 2、域名转发问题 如果是A运营商将解析...

mind-blowing
30分钟前
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部