源代码级别解读AutocompleteTextview中CompletionHintView属性报空指针问题
Android中的自动完成文本框控件AutocompleteTextview是一个非常强大的控件,这个控件分为两部分,输入文本的EditTextView和用来显示更多信息的下拉列表控件ListView。 当用户输入一个字的时候,该控件会自动搜索与输入内容匹配的内容,并以列表项呈现。用户点击列表项,文本框自动填充选中的内容。
下午在使用这个控件的时候,在填充完美工给的贴图之后,属性 android:completionHint="最近搜索记录" 显得很难看, 如下图红框
查了一下控件的所有属性,可以使用android:completionHintView="@layout/completionhintview" 来代替android:completionHint="最近搜索记录" ,也就是自定义下拉菜单底部信息的样式。下面是我定义的布局文件。
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#343535"
android:gravity="left|center_vertical"
android:paddingLeft="5dp"
android:text="最近搜索记录"
android:textColor="#8c8c8c"
android:textSize="12sp" />
这个布局一定要这么写 ,否则你会遇到下面两个问题:
1.该布局已经有父布局错误
原因:该布局外部不得嵌套其他布局,如LinearLayout,RelativeLayout等。
2.找不到该控件布局,并且抛出空指针错误。
原因:布局中TextView的id必需为 @android:id/text1
所谓水有源,树有根。 下面我从源代码级别上来解释一下这些问题产生的原因。
通过查看AutoCompleteTextView源代码,我发现这样一个私有函数。
private View getHintView(Context context) {
if (mHintText != null && mHintText.length() > 0) {
final TextView hintView = (TextView) LayoutInflater.from(context).inflate(
mHintResource, null).findViewById(com.android.internal.R.id.text1);
hintView.setText(mHintText);
hintView.setId(HINT_VIEW_ID);
return hintView;
} else {
return null;
}
}
谷歌童鞋没有写代码解释,但是大致的意思我们可以知道,这段代码的功能是获得我们自定义下拉框提示内容的布局,封装成一个View。
在寻找这个控件的时候,寻找控件的id被写死为 com.android.internal.R.id.text1 红色代码所示。所以我们在布局中的id只能设置成安卓内部控件id了。
这个确实让我有点摸不到头脑,如果不是看源代码,根本不知道为什么要这样。
看到了getHintView这个函数,那么第一个问题也就迎刃而解了。因为android系统按照com.android.internal.R.id.text1 找到的这个控件,那么在向其他View添加这个控件的时候,这个控件是不允许有父布局存在的,否则你应该取得该控件的root布局的id,然后将它添加到其他View中去。
好了,两个问题都解释完了。不知道你看明白没有。
最终效果如图:
原文链接:http://www.67tgb.com/?p=489
欢迎访问:望月听涛