GO安全桌面9月13日更新的版本,在android4.1以上版本中,系统小部件的选择由原来的列表形式,变成了预览图的形式。怎么做到的呢?我们一起来瞅瞅。
首先既然是android4.1以上,肯定和系统源码有关,我们搜索4.1的新特性,发现了一个和小插件有关的特性:桌面插件自动调整大小。所以肯定是利用这个特性来做的。
我们写一个例子来实现GO桌面的功能,这个例子有一个简单的布局文件:
<ScrollView
android:id="@+id/mywidgetScroll"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#666666"
android:scrollbars="vertical">
<LinearLayout
android:id="@+id/mywidget"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/mywidgetScroll"
android:scrollbars="vertical"
android:background="#555555">
<LinearLayout
android:id="@+id/myPreviewImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
两个线性布局中,第一个放置小插件,第二个放置预览图。
下面开始写我们的activity
定义一些属性:
private LinearLayout mywidget = null;
private LinearLayout myPreviewImage = null;
private AppWidgetManager appWidgetManager = null;
private Context otherContext = null;
private AppWidgetHost mAppWidgetHost = null;
private AppWidgetProviderInfo awpi = null;
private int appWidgetId = 0;
private static final int HOST_ID = 1024;//随便定义的
private static final int CONFIG = 1; //requestCode为设置
private static final int BIND = 2; //requestCode为绑定
在onCreate中找到我们的mywidget和myPreviewImage。
通过appWidgetManager = AppWidgetManager.getInstance(getContext());获取AppWidgetManager。
通过mAppWidgetHost = new AppWidgetHost(getContext(), HOST_ID);这里的HOST_ID为一个自定义的int值。
mAppWidgetHost.startListening();//这里要启动监听才能让小部件时时更新,并且为了保证能够时时更新,必须放在Activity的onCreate/onStar方法调用该方法,在onStop方法中,调用mAppWidgetHost.stopListenering() 停止AppWidget更新。
List<AppWidgetProviderInfo> list = appWidgetManager.getInstalledProviders(); 获取小插件的列表
迭代list,获得AppWidgetProviderInfo,里面的appWidgetProviderInfo.previewImage==0就说明没有预览图,不等于0就有预览图,下面我们怎么获得预览图呢?
Context otherContext = getContext().createPackageContext(appWidgetProviderInfo.provider.getPackageName(), Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
Resources res = otherContext.getResources();
ImageView imageView = new ImageView(getContext());
Drawable drawable = res.getDrawable(appWidgetProviderInfo.previewImage);
imageView.setImageDrawable(drawable);
同样,我们也可以通过appWidgetProviderInfo.icon来获取小插件的应用图标。
下面就是点击这个ImageView要添加到小插件的线性布局中了。
int appWidgetId = mAppWidgetHost.allocateAppWidgetId();//获取一个小插件的id
判断下这个id是否能够直接绑定到提供者中。
boolean testboolean = appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, appWidgetProviderInfo.provider);
if(!testboolean){//没有注册就注册
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
//API规定必须设置这两个参数appWidgetId和provider进行注册
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, appWidgetProviderInfo.provider);
startActivityForResult(intent,BIND);
}else if(appWidgetProviderInfo.configure != null){
//假如小部件需要配置就配置此Action
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
intent.setComponent(appWidgetProviderInfo.configure);
//API规定一定要传appWidgetId
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
startActivityForResult(intent,CONFIG);
}else{
//没有配置,就直接添加widget
AppWidgetHostView hostView = mAppWidgetHost.createView(MainActivity.this, appWidgetId , appWidgetProviderInfo);
mywidget.addView(hostView);
}
总共有3中情况,appWidgetId 需要注册就注册。小插件添加的时候需要配置,就启动配置,否则就直接添加到小插件布局中。
启动Intent然后分析返回结果:
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == CONFIG){
//配置完后添加
if(resultCode == Activity.RESULT_OK){//成功返回
appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID , AppWidgetManager.INVALID_APPWIDGET_ID) ;
AppWidgetHostView hostView = mAppWidgetHost.createView(MainActivity.this, appWidgetId , awpi);
mywidget.addView(hostView);
}
}else if (requestCode == BIND){
if(resultCode == Activity.RESULT_CANCELED){
//API规定绑定不成功,就要先删除掉该appWidgetId,然后再绑定
// AppWidgetProvider appWidgetProvider = new AppWidgetProvider();
// appWidgetProvider.onDeleted(getContext(), new int[]{appWidgetId});
//启动绑定intent
}
//绑定完成
if(awpi.configure != null){
//有配置就启动配置
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE) ;
intent.setComponent(awpi.configure) ;
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
startActivityForResult(intent , CONFIG);
}else{
AppWidgetHostView hostView = mAppWidgetHost.createView(MainActivity.this, appWidgetId , awpi);
mywidget.addView(hostView);
}
}
}
这样
就可以实现由预览图的添加小插件了,效果如图:
红线上方为小插件布局,下方为预览布局。