Google的Android源码包含较多自带应用程序的代码,比如QuickSearchBox,Music,Gallery3D等等,这绝对是一笔宝贵的财富,哈哈。
最近拜读了QuickSearchBox部分源码,QuickSearchBox可以搜索联系人、音乐、信息、应用程序等等。期间发现一个小小的问题,当我们在搜索应用程序没有找到匹配的结果时,程序没有给出任何提示,这从用户角度来说是不太合理的。于是决定花点时间改进该程序。
搜索页面如下图所示,选择应用程序,
在点击搜索后,QuickSearchBox将跳转到搜索内容对用的程序中,比如搜索应用程序时会跳转到ApplicationProvider中,该程序源码在package/providers目录里,包含三个java文件,ApplicationLauncher、ApplicationsAdapter、ApplicationsProvider。
ApplicationsAdapter利用bindView将搜索的结果显示为自定义的列表布局。ApplicationsProvider则提供了手机中应用程序的信息,包括程序图标、名称等,封装了数据库的操作以提供更方便的操作。ApplicationLauncher主要是页面的展示和逻辑操作。
private void showSearchResults(String query) {
setTitle(query);
mCursor = Applications.search(getContentResolver(), query);
startManagingCursor(mCursor);
ApplicationsAdapter adapter = new ApplicationsAdapter(this, mCursor);
setListAdapter(adapter);
}
showSearchResults为将搜索的数据映射至列表中。
再来看看xml布局代码。
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:layout_width="match_parent"
android:layout_height="56dip" >
<ImageView android:id="@+id/icon1"
android:layout_width="48dip"
android:layout_height="48dip"
android:scaleType="centerInside"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true" />
<TextView android:id="@+id/text1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="4dip"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/icon1" />
</RelativeLayout>
搜索结果有数据展示时如下图, 但没有数据展示时则除了title,页面中间只是黑色背景,没有任何提示。
解决这个问题有几种方案,第一种为直接弹一个Toast,提示显示“未找到应用程序”,自动浮现并消失,这个办法很简单,代码如下,
private void showSearchResults(String query) {
setTitle(query);
mCursor = Applications.search(getContentResolver(), query);
startManagingCursor(mCursor);
ApplicationsAdapter adapter = new ApplicationsAdapter(this, mCursor);
if(adapter.isEmpty()) {
Toast.makeText(this, R.string.application_search_not_found, Toast.LENGTH_LONG).show();
}
setListAdapter(adapter);
}
第二种方案为跳转到一个新的Activity,提示信息,但是从程序的框架来讲,不太合理,因为ApplicationProvider为后台提供数据的程序,让该部分程序跳转至新Activity不符合框架结构,因此放弃。
第三种方案,这个是我们容易忽略的方案。ApplicationLauncher继承了ListActivity,我们可以指定自己的布局,布局中必须包含一个id为“@android:id/list”的ListView,为了让布局在ListView无数据时显示提示信息,需要加一个id为“@android:id/empty”的view,此处采用TextView即可,此外要注意设置TextView为gone。具体xml代码修改如下:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView android:id="@+id/icon1"
android:layout_width="48dip"
android:layout_height="48dip"
android:scaleType="centerInside"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true" />
<TextView android:id="@+id/text1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="4dip"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/icon1" />
<TextView
android:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:layout_gravity="center"
android:visibility="gone"
android:text="@string/application_search_not_found" />
</RelativeLayout>
另外在ApplicationLauncher的onCreate方法中要添加setContentView方法。
super.onCreate(savedInstanceState);
setContentView(R.layout.application_list_item);
Intent intent = getIntent();
将修改的工程编译,然后将apk文件adb push到手机上,bingo~
当然,可能还有更多的方案,折腾无极限,欢迎大家提出,文章不当的地方欢迎指出。