`
panxq0809
  • 浏览: 294783 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

为何GoogleSearch中可以嵌入EditText?

阅读更多

原文出自:http://www.eoeandroid.com/viewthread.php?tid=1729

eoeandroid社区是国内最火的android社区。

最近在学习AppWidget,想做一个像GoogleSearch那样带有输入框的Widget练习。

可是,Dev Guide关于AppWidget的讲解明确指出,在App Widget中只能用FrameLayout,LinearLayout,RelativeLayout三种Layout和AnalogClock,Button,Chronometer,ImageButton,ImageView,ProgressBar,TextView这几种Widget,而且它们的子类也不能用。

不管怎样还是用先用EditText看看。编译和安装都没有问题。但是在向桌面加入AppWidget的时候,就会出现“Problem loading widget”错误。

看来真的只能用TextView了。

虽然通过修改TextView的属性,可以让TextView看起来象EditText,而且也可以输入,但是至少有两个问题:

1.光标不能在文本框内移动 -
按左右箭头时,焦点会跳到其它的Item上,而不是像EditText那样在字符间移动。看了一下EditText是通过Override TextView的getDefaultMovementMethod这个方法设置箭头按键的移动方式的。而TextView中虽然也有setMovementMethod方法,但是搞了半天也没办法从RemoteViews中拿到TextView的实例;

2.这一点比较重要:不知道该如何从RemoteViews中获得TextView的输入的结果?

可是GoogleSearch上明明就有输入框。它是怎么实现的呢?

在网上查了一下,结论是:GoogleSearch并不是用普通AppWidget方法实现的Widget,而是在Home(Launcher)中独立实现,是属于Launcher的一部分。

翻出Launcher的代码(/packages/apps/Launcher),果然看到了GoogleSearch的实现在Search.java,它的Layout定义在widget_search.xml。其中的输入框是Launcher封装了的AutoCompleteTextView(即SearchAutoCompleteTextView)。

那么Launcher是怎样区别加载GoogleSearch和其它普通的AppWidget的呢?

在Launcher中有一个static成员LauncherModel,它主要负责维护Launcher的状态和提供一些更新Launcher数据库状态的API。LaunchModel中用不同的ArrayList记录ItemInfo和LauncherAppWidgetInfo的信息(ITEM_TYPE_APPLICATION, ITEM_TYPE_USER_FOLDER, ITEM_TYPE_LIVE_FOLDER, ITEM_TYPE_WIDGET_SEARCH这些类型的Item都被记录在ItemInfo类型中)。

具体的加载过程大概是:在Launcher的onCreate和onResume中都调用了LauncherModel::loadUserItems方法。之后的顺序是LauncherModel::loadUserItems->Launcher::onDesktopItemsLoaded->Launcher::bindDesktopItems->…->最后在Launcher::DesktopBinder::handleMessage中通过Launcher::bindItems方法加载了Widget Search到workspace(控制桌面显示区域的class)上,而通过Launcher::bindAppWidgets加载了普通的AppWidgets。

再看一下Widget添加的过程吧。Launcher通过addSearch直接用inflate的方法产生一个GoogleSearchWidget的View,并添加到workspace;而普通的AppWidget则是通过completeAddAppWidget中产生并添加一个AppWidgetHostView来实现的。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics