本文记录了一些项目开发中遇到的小bug,相信大部分大家都遇到过,在这里把解决方法记录下来,以供参考和回顾。
1.软键盘问题
有时候需要人工去干预软键盘的隐藏与显示,在这里将方法记录下来。
隐藏软键盘:
InputMethodManager manager= (InputMethodManager) view.getContext().getSystemService(INPUT_METHOD_SERVICE); manager.hideSoftInputFromWindow(view.getApplicationWindowToken(), 0);
显示软键盘:
InputMethodManager manager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
manager.showSoftInput(mEditText, 0);
项目中碰到过这样设置并没有什么作用,可以尝试下面这段代码。
InputMethodManager manager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
manager.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);
2.onPause()问题
当弹出dialog的时候Activity会不会调用onPause()方法?
首先看一些官方文档:
onPause() Called when the system is about to start resuming a previous activity.
当系统准备启动另一个Activity的时候,当前Activity才会去调用onPause()方法。而并不是所谓的失去焦点,被覆盖就一定会调用。所以,当弹出dialog,或者Toast的时候,并不会对当前Activity的生命周期造成影响。
3.onActivityResult()方法失效
开发过程中遇到从一个界面跳转到地图选点界面,选择地点之后返回原界面,在原界面的onActivityResult()方法中始终无法接收到地图界面返回过来的地址信息,百思不得其解。最后通过查询资料发现问题出来地图界面的启动模式上面,项目中将地图Activity的launchMode设置为了singleTask,结果导致onActivityResult()方法失效,详情准备单独写一篇博客来看一下。这里将launchMode默认即可。
PS:经过测试,singleInstance也是不可以的。详细分析见:《launchMode带来的onActivityResult失效问题》。
4.ScrollView嵌套ListView的问题
在布局文件中,如果ScrollView里面的ListView高度为包裹自己,填充数据之后你会发现你的ListView只显示了一行。如果需要显示完整的ListView,需要重写ListView的onMeasure函数来正确显示ListView的高度。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
然而实际开发中,我们也经常不需要去显示整个ListView,我们可能通过比重,或者设置固定高度,这时候又发现了新的问题。ScrollView是上下滑动,ListView也是在上下滑动,我们发现ListView这时候已经无法滑动了。这里采取一种最简单的解决方法,我们监听ListView的onTouch事件,当我们监听到ACTIION_UP的时候,即手指在ListView的视图范围内离开了屏幕,让父控件拦截事件,其他情况下,即ACTION_DOWN和ACTION_MOVE的时候,不拦截事件,交由ListView处理,即可解决这一冲突。看到这,大家肯定都知道用requestDisallowInterceptTouchEvent()这个函数。
listView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
scrollView.requestDisallowInterceptTouchEvent(false);
} else {
scrollView.requestDisallowInterceptTouchEvent(true);
}
return false;
}
});
这样ListView就可以正常滑动了。
5.Fragment中onActivityResult失效
当我们在Activity中嵌套Fragment,以startActivityForResult的方式启动另一个Activity,finish之后返回想在Fragment中取得返回的data,这时候你会发现是取不到任何数据的。我们看一下Fragment的startActivityForResult方法源码,
public void startActivityForResult(Intent intent, int requestCode) {
if(this.mActivity == null) {
throw new IllegalStateException("Fragment " + this + " not attached to Activity");
} else {
this.mActivity.startActivityFromFragment(this, intent, requestCode);
}
}
所以我们不管是在Fragment中的startActivity还是外部FragmentActivity的startActivity,最后调用的都是FragmentActivity的startActivityForResult,所以理所当然,最后应该由绑定的Fragment来接收数据。这里我们只需要把FragmentActivity在onActivityResult方法中将数据传递给Fragment的onActivityResult方法即可。代码如下,
/**
*在FragmentActivity中重写onActivityResult方法,将数据传递给 内置的Fragment
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (fragmentOne!=null){
fragmentOne.onActivityResult(requestCode,resultCode,data);
}
}
这样Fragment的onActivityResult方法中就可以拿到返回的数据了。