使用DialogFragment实现登录遇到的坑

使用DialogFragment实现登录遇到的坑

  • 为啥要用DialogFragment实现登录
  • 第一个坑——callback的保存与重建
  • 第二个坑——转场时的动画问题
  • 第三个坑——输入法
  • 第四个坑——show方法
  • 总结

为啥要用DialogFragment实现登录

之所以要采用DialogFragment实现登录,是因为有一个需求,就是希望未登录的用户,在触发登录之后,直接执行触发登录之前点击的那个按钮的事件。实现这个需求,我能想到的方法有三种,一个就是在Activity中通过onActivityResult方法的返回值来做,这样做坏处就是重写onActivityResult这个方法会写的很复杂,不好维护;第二个是用Eventbus,谁需要用到这个功能谁去注册Eventbus,这个方法比起第一个方法,各个调用登录的地方可以自己去注册eventbus,但是需要一个id区分每个调用,相比起来也没比第一个方法好,而且还需要注册和注销,看起来是更麻烦了;第三个就是我做的,用DialogFragment来实现登录,因为可以往里面传一个callback,这样谁需要谁自己实现一个callback就好了,比起前两个,这种方法简直是太简洁,太高效了。这么分析下来,所以我们就这么使用了这种方式。历史告诉我们,凡事两个方面去看,没有十全十美的东西,呵呵。

callback的保存与重建

既然使用了fragment,我们都知道,fragment在意外销毁的时候会自己重建(横竖屏切换也会传触发),而在重建的时候,fragment并不是原来的那个fragment,但是对fragment来说无所谓,因为fragment在销毁的时候会保存arguments,所以只要你是通过argument方式来传值的话,销毁和重建并不影响。但是,问题来了,我这次要传的并不是值,而是一个callback,很显然,它是被外面的对象持有的,是一个地址,他并不能像值一样,被序列化存储。这就很蛋疼了,怎么办?!其实这一点安卓早有遇见,as自动生成的示例代码里面有这种的处理,就是外面的activity直接实现这个callback,在fragment detach和attach的时候,对fragment中的callback对象进行置空和赋值(只要activity是callback的实现就赋值),这种方式解决了callback的重建问题,但是,问题又来了,这种样子的重建,对于外部调用登录的地方来说,其实跟第一种方式区别并不大。。。那我到底该如何是好?我试过用静态变量临时保存callback,但是很遗憾,虽然这个callback是重建了,但是由于外部activity其实也会有销毁和重建,所以对于新建的activity来说,并无卵用。最后我真的没找到啥招式,因为考虑到我这没有横竖屏切换,触发销毁重建的概率实在不大,我就阻止了fragment的重建,就是在重建fragment之后直接销毁当前fragment。。。我是真没招了,有知道招的还请告诉我一下。小生不胜感激!

转场时的动画问题

callback告一段落之后,在体验过程中,发现了体验上的一些缺陷第一个就是动画。DialogFragment在onStop()和onStart()的时候分别会调用dialog的hide和show方法。这就导致,我在打开其它Activity的时候,会透出登录下方的页面,同时返回的时候又会弹出登录。这种体验跟之前的Activity的实现完全是两样,因为登录部分的ui并没有调整,看起来依然跟之前的Activity一样,但是这样的情况就导致出现了十分明显的差异。正常的解决方式其实应该是DialogFragment在触发onStop()和onStart()的时候不对dialog做处理,但是很遗憾,行不通,没有暴露这些方法给我们。所以我采用了一种非常规的方式,就是在进入登录页之后,重新修改动画,将动画变成一直是alpha为1的动画,这样能解决转场的问题。

输入法问题

这里说的输入法问题,其实有两个问题,第一个是返回的时候,如果当前显示了输入法,希望先关闭输入法,再次点击返回才关闭页面。第二个是输入弹起的时候会侵占dialog的布局,导致底部的页面闪过。

输入法返回处理
这个问题的难点在于输入法状态的监听,就是我们怎么判断输入法是显示状态还是隐藏状态。这个问题往上搜一下,大概有两种,一个是输入法管理器有个isActive的方法,使用方式上最贴近我们期望的用法,但是很遗憾,没卵用。第二个就是根据布局的变化,来判断输入法状态,我是用这种方式实现的,目前来看,这是最靠谱的。目前没发现啥问题。

输入法弹起问题
这个问题目前没找到解决办法。。。同样跪求解决方案!不胜感激

show方法

这个问题就是DialogFragment的show方法中调用了FragmentTransaction.commit()方法,使用这个方法添加fragment会出现的问题就是在onsaveinstance调用之后,容易崩溃,具体的错误我就不写了,估计大家都遇到过。commitallowlossstate方法我们调不了,所以我就覆写了show方法,加了一个异常捕获。没想到啥好方法。同样跪求!

总结

这次的改动,让我感觉到了目标是美好的,道路是曲折的,在事实面前,有的时候是要有一些取舍。希望能给打算使用dialogfragment做事情的同学一些启发,也希望大家能帮我解答一下我提出的问题!!!么么哒

你可能感兴趣的:(android)