在fragment中实现返回键单击提醒 双击退出
最近在练习一个小项目,也就是郭霖大神的开源天气程序,尝试用mvp架构加dagger2来重写了一下,大致功能都实现了,还没有全部完成。
接近完成的时候,想在天气信息页面实现一个很常见的功能,也就是点击屏幕下方的返回键的时候不是返回到上一个activity或者退出,而是提醒用户再按一次就会退出。
实现思路也很简单,就是对返回键的动作进行监听和拦截,然后重写成需要的动作,因为在我的程序中activity只作为调度器使用,真正的View功能在fragment中,所以返回键的动作捕捉只能以接口形式写在BaseActivity中,然后让BaseFragment实现这个接口,代码如下:
- public class BaseActivity extends AppCompatActivity {
- protected final String TAG = this.getClass().getSimpleName();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- ActivityCollector.addActivity(this);
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- ActivityCollector.removeActivity(this);
- }
- //返回键监听实现
- interface FragmentBackListener {
- void onBackForward();
- }
- private FragmentBackListener backListener;
- private boolean isInterception = false;
- public void setBackListener(FragmentBackListener backListener) {
- this.backListener = backListener;
- }
- //是否拦截
- public boolean isInterception() {
- return isInterception;
- }
- public void setInterception(boolean isInterception) {
- this.isInterception = isInterception;
- }
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- if (isInterception()) {
- if (backListener != null) {
- backListener.onBackForward();
- return false;
- }
- }
- }
- return super.onKeyDown(keyCode, event);
- }
- }
- public abstract class BaseFragment extends Fragment implements BaseActivity.FragmentBackListener {
- protected Disposable disposable;
- protected final String TAG = this.getClass().getSimpleName();
- //返回键点击间隔时间计算
- private long exitTime = 0;
- //捕捉返回键点击动作
- @Override
- public void onBackForward() {
- //和上次点击返回键的时间间隔
- long intervalTime = System.currentTimeMillis() - exitTime;
- if (intervalTime > 2000) {
- Toast.makeText(getActivity(), getString(R.string.exit_toast), Toast.LENGTH_SHORT).show();
- exitTime = System.currentTimeMillis();
- } else {
- ActivityCollector.finishAll();
- }
- }
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- //注册监听
- ((BaseActivity) getActivity()).setBackListener(this);
- ((BaseActivity) getActivity()).setInterception(true);
- }
- @Override
- public void onDetach() {
- super.onDetach();
- //取消监听
- ((BaseActivity) getActivity()).setBackListener(null);
- ((BaseActivity) getActivity()).setInterception(false);
- }
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- unsubscribe();
- }
- protected void unsubscribe() {
- if (disposable != null && !disposable.isDisposed()) {
- disposable.dispose();
- }
- }
- }
通过一个ActivityCollector来管理活动:
- public class ActivityCollector {
- public static List<Activity> activities = new ArrayList<>();
- public static void addActivity(Activity activity) {
- activities.add(activity);
- }
- public static void removeActivity(Activity activity) {
- activities.remove(activity);
- }
- public static void finishAll() {
- for (Activity activity : activities) {
- if (!activity.isFinishing()) {
- activity.finish();
- }
- }
- }
- }
这样,所有继承BaseFragment的fragment都回拥有这个单击提醒 双击退出的功能了,代码不复杂,也带有注释,相信很容易看懂。
如果某个页面不需要这个功能可以在fragment中重写BaseFragment中的onAttach方法
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- ((BaseActivity) getActivity()).setInterception(false);
- }
当然如果手机应用的大多数页面不需要这个功能,可以在BaseFragment中默认关闭拦截,在需要用的fragment中重写onAttach来打开。
最后说一点我在开发过程中遇到的小坑,在网络访问的功能方面我使用了squareup的retrofit2和okhttp
一开始我在build.gradle是这么配置的
- //squareup dependencies
- compile 'com.squareup.okhttp3:okhttp:3.6.0'
- compile 'com.squareup.okio:okio:1.11.0'
- compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
- compile 'com.squareup.retrofit2:retrofit:2.2.0'
- compile 'com.squareup.retrofit2:converter-gson:2.2.0'
- compile 'com.squareup.retrofit2:converter-scalars:2.2.0'
- compile 'com.squareup.retrofit2:adapter-rxjava:2.2.0'
- //RxJava dependencies
- compile 'io.reactivex.rxjava2:rxandroid:2.0.0'
- compile 'io.reactivex.rxjava2:rxjava:2.0.2'
但是编译的时候无法通过,
经过排查,原因是retrofit2自带的rxjava适配器还未升级到rxjava2,所以产生了编译错误,解决办法也不复杂Jake大神给我写了一个rxjava2的适配器,替换原来的就可以了:
- //squareup dependencies
- compile 'com.squareup.okhttp3:okhttp:3.6.0'
- compile 'com.squareup.okio:okio:1.11.0'
- compile 'com.squareup.okhttp3:logging-interceptor:3.6.0'
- compile 'com.squareup.retrofit2:retrofit:2.2.0'
- compile 'com.squareup.retrofit2:converter-gson:2.2.0' //gson转化器
- compile 'com.squareup.retrofit2:converter-scalars:2.2.0'//String转化器
- compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
- //RxJava dependencies
- compile 'io.reactivex.rxjava2:rxandroid:2.0.0'
- compile 'io.reactivex.rxjava2:rxjava:2.0.2'
本人水平有限,之前很少写博客,以后会尽量坚持更新,分享学习心得,欢迎交流。
在fragment中实现返回键单击提醒 双击退出的更多相关文章
- Android 在fragment中实现返回键单击提醒 双击退出
尝试用mvp架构加dagger2来重写了一下,大致功能都实现了,还没有全部完成. 项目地址 接近完成的时候,想在天气信息页面实现一个很常见的功能,也就是点击屏幕下方的返回键的时候不是返回到上一个act ...
- 在Fragment 中拦截返回键
代码如下: class XXXFrgmt : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ...
- android中的返回键与Activity
我在做应用时遇到一个问题.就是在启动主页面时须要预先载入一些数据.我是在一个载入页中处理完这些数据然后再转到主页面.但当我在主页面中按返回键时,系统会返回载入页面.我不希望载入页在使用完之 ...
- 让Fragment监听返回键
Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.所以使用到了以下的方法. 首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPre ...
- Fragment监听返回键
首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPressed(),所有BackHandledFragment的子类在onBackPressed方法中处理各自对 ...
- 优雅的让Fragment监听返回键
转载请注明出处:http://write.blog.csdn.net/postedit/40507387 Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设Fragm ...
- Android必知必会-Fragment监听返回键事件
如果移动端访问不佳,请尝试 Github版<–点击左侧 背景 项目要求用户注册成功后进入修改个人资料的页面,且不允许返回到上一个页面,资料修改完成后结束当前页面,进入APP主页. 由于是使用多个 ...
- Android 优雅的让Fragment监听返回键
Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设FragmentActivity有三个Fragment,一般安卓用户期望点击返回键会一层层返回到FragmentAc ...
- Coco2d-js/Cocos2d-html5中Android返回键实现
导语: 首先Cocos2d-x其中实现Menu和Back按键相对简单一点,而在资源较少的Cocos2d-html5其中.要实现返回还是有一点不一样的,并且有没有详细的demo.也就仅仅有自己去看api ...
随机推荐
- 同步I/O和异步I/O
同步I/O包括:阻塞,非阻塞,多路复用 阻塞模型:给你送的外卖到了,给你打电话,你不去取,外卖小哥一直在那等你,直到你来,形成阻塞,当然应该给外卖小哥点赞,哈哈哈哈!! 非阻塞模型:取外卖的主人非常饿 ...
- C++学会STL
1.1 泛型程序设计简介 泛型程序设计,简单地说就是使用模板的程序设计法.将一些常用的数据结构(比如链表,数组,二叉树)和算法(比如排序,查找)写成模板,以后则不论数据结构里放的是什么对象,算法针对什 ...
- 第三方控件引起的"类型Universe无法解析程序集"的血案
前一阵子在项目中添加了IrisSkin2皮肤控件,今天用VS打开悲剧了. 提示"类型Universe无法解析程序集:System.Design,Version=2.0.0.0,Culture ...
- VUE组件 单独文件封装
https://www.cnblogs.com/SamWeb/p/6391373.html vuejs 单文件组件.vue 文件 vuejs 自定义了一种.vue文件,可以把html, css, ...
- java怎么调用子类中父类被覆盖的方法
public class b { { void show() { System.out.println("b"); } } public class c extends b { v ...
- lc 0228
目录 ✅ 412. Fizz Buzz 描述 解答 c数字转字符: other's c my c tdo py ✅ 235. 二叉搜索树的最近公共祖先 描述 解答 评价者 思路: c py ✅ 412 ...
- lc 0223
目录 ✅ 669. 修剪二叉搜索树 描述 解答 java py ✅ 883. 三维形体投影面积 描述 解答 my understanding c py py map ?? python zip(*gr ...
- Codeforces Round #600 (Div. 2) - D. Harmonious Graph(并查集)
题意:对于一张图,如果$a$与$b$连通,则对于任意的$c(a<c<b)$都有$a$与$c$连通,则称该图为和谐图,现在给你一张图,问你最少添加多少条边使图变为和谐图. 思路:将一个连通块 ...
- OPENTSDB: Request failed: Internal Server Error net.opentsdb.core.IllegalDataException
今天Opentsdb补传历史数据的时候,出现了如下的错误: Request failed: Internal Server Error net.opentsdb.core.IllegalDataExc ...
- 「JSOI2011」棒棒糖
「JSOI2011」棒棒糖 传送门 双倍经验 考虑主席树做法. 对于当前的主席树节点,如果 \(\le mid\) 的个数足够就往左边走,否则就尝试往右边走,都不行就返回 \(0\). 参考代码: # ...