关于映客App房间效果的研究

作者: Brucetoo | 来源:发表于2016-03-01 10:18 被阅读1371次

    最近在使用映客App的时候,发现IOS端和 android端房间内效果有一些的出入,android端明显少了右滑隐藏上方礼物区域,上下滑动切换房间的需求。于是我就寻思着能否在android上实现IOS端的效果(虽然映客android端没做)。


    截图

    要解决的问题:
    1.点击 1 位置的按钮显示 EditText 的同时 **上层界面 **被键盘顶上去,但是 下层界面 (视频播放区域) 不被键盘往上顶

    1. 左滑效果实现
    2. 上下滑效果实现
      关于问题 1
      这里涉及到activity的 windowSoftInputMode 各种模式的使用
      但是问题就出在这里,无论 windowSoftInputMode 设置成什么值(各个值的含义google一下会有一大推 传送门),上下两层都会被键盘弹出而往上顶,因为windowSoftInputMode是作用于整个 activity的 根布局的

    寻思苦想出了2个解决方案
    1.下层视频播放用一个 Activity,上层礼物消息等用 另一个 Activity,然后两个Activity设置不同的windowSoftInputMode,就可以实现1的效果.但是 这样会变得很 “庞大”和臃肿,真的一定需要两个Activity? 于是有了第二个方案

    1. 既然Activity内部的所以view都会随根布局被顶上去而跟着动,那就采用一个具有系统窗口属性的 DialogFragment来实现,DialogFragment有一个好处就是他是一个单独的窗口,不会随activity的被顶而被顶。于是设计一个Activity启动的时候 底层用一个 Fragment放视频播放的区域,上层用DialogFragment处理礼物各种的具体界面
      界面分成移动的代码片段 Github
      代码实现了只会移动上层,而下层保持状态的效果
      但是接下来又会出现一个问题: 用户是需要点击某个按钮才会显示 EditText,然后弹出软键盘,在按系统返回键的时候会收起系统软键盘,在显示按钮同时隐藏 EditText,这个需求看起来貌似很简单,实现的时候就发现我们无法获取到系统 软键盘 显示/隐藏的监听
      于是google了一堆解决方案 大致如下:
      //监听软键盘的隐藏和显示
      但是activity的配置必须是android:windowSoftInputMode="adjustResize"
      但是此处的需求不能resize>>activity中的布局,在此需要设置 DialogFragment中Dialog 的 SoftInputMode 在
      public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
      中设置
      getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    //        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {//                }else {
    //            @Override
    //            public void onGlobalLayout() {
    //                int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight();
    //                if (heightDiff > 100) { // 软键盘存在
    //                       Log.e("onGlobalLayout","show");
    //                }else{
    //                       Log.e("onGlobalLayout","gone");
     //                   }     
    //            }
    //        });
    

    ~~~二一个是自定义EditText 重写onKeyPreIme(intkeyCode,KeyEventevent)方法
    具体实现代码 CustomEditText.java 这个目前看来是最好的方法~~~
    关于问题2
    最初的想法是在DialogFragment中自定义根布局的ViewGroup,然后用 ViewDragHelper来处理滑动事件 来左右滑动 根布局。但是,实际操作起来也不是那么轻松。于是我又想到了一个更好的实现方案,毕竟少写code才是王道 --- 用ViewPager来实现滚动滑动不是很简单???
    ViewPager 一共两页,左边一页为空白页,右边一页为真正的上层视图页,初始化的时候设置 viewPager.setCurrentItem(1); 很轻松就实现了想要的效果
    具体代码见 主布局用viewpager做左滑效果
    关于问题3
    相当于显示是要在 DialogFragment中ViewPager的第二页实现上下滑动的效果
    要想实现上下滚动,无非就是各种滚动的View的使用,ListView ? RecyclerView ? ScrollView? 但是好像这几种方案都要很恶心在滚动时判断是否滚动过半,然后松手后再自动滚动到上一页或者下一页或者还原到当前页。这样貌似很麻烦,直接pass掉。
    假如有 垂直滚动的ViewPager就好了,对 垂直滚动的ViewPager ,于是Github上乱找一通,发现一个靠谱的 VerticalViewPager ,主要是 将原生的ViewPager所有的事件截断,然后通过宽高比的将原来横向的宽度变成现在垂直的高度,然后通过 event.setLocation(swappedX, swappedY); 来重新设置MotionEvent的坐标。说起来有些绕 还是直接看代码吧。
    BTW viewPager.setOverScrollMode(ViewPager.OVER_SCROLL_NEVER); 需要设置这个属性,否则在overScroll效果的时候会发现是在左右侧而非上下侧,干脆直接禁止掉OverScrollMode
    到此为止上下滑动算是实现了,但是 映客 IOS App中上下滚动的时候下层视频播放区域也是会跟随滚动的,而我显示的实现方案只是在上层的DialogFragment中ViewPager的第二页实现的滚动,要必须实现滚动的相关性,在此就下层Fragment中就必须有一个回调处理来至上层ViewPager滚动监听时的位置变化的大小和方向。(当初想过用EventBus来发送和处理这个滚动位置的Y坐标变化的信息,但是项目中EventBus大都接收TCP的各种消息而担心频繁滚动会致使性能问题,所以放弃了)
    支持上下滚动且下层也跟随滚动的相关代码 添加上下滚动的支持
    最后上一张没加上上下滚动时的GIF图片

    效果

    具体的代码参见 Github brucetoo

    相关文章

      网友评论

      • 674fa1c36ad3:这个貌似不对  切换数据你怎么更换啊
        674fa1c36ad3:@廷皓 你这是写死的三个 其他的数据怎么进来?想过吗
      • 迷途小书童nb:看了下,效果不是很好,比较卡
      • gadfly_only:万分感谢大神
        Brucetoo:@gadfly_only 不是大神哈。。
      • gadfly_only:有一个问题是按返回键的时候,上层布局消失,而不是整个页面退出?
        gadfly_only:看到了。涨见识了。当时我还纳闷怎么实现呢
        Brucetoo:@gadfly_only 我记得代码里面是有做这个处理的

      本文标题:关于映客App房间效果的研究

      本文链接:https://www.haomeiwen.com/subject/jqngkttx.html