cam*_*mav 5 android android-widget
我开始发疯试图弄清楚这一点。看起来应该很容易,我开始怀疑是否有可能。
我想要做的是创建一个主屏幕小部件,它只包含一个 ImageButton。当它被按下时,想法是改变一些设置(比如 wi-fi 切换),然后改变按钮图像。
我在 main.xml 中有这样声明的 ImageButton
<ImageButton android:id="@+id/buttonOne"
android:src="@drawable/button_normal_ringer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
Run Code Online (Sandbox Code Playgroud)
我的 AppWidgetProvider 类,名为 ButtonWidget
*** 请注意, RemoteViews 类是本地存储的变量。这让我可以访问 RViews 布局元素......或者我是这么想的。
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
remoteViews = new RemoteViews(context.getPackageName(),
R.layout.main);
Intent active = new Intent(context, ButtonWidget.class);
active.setAction(VIBRATE_UPDATE);
active.putExtra("msg","TESTING");
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context,
0, active, 0);
remoteViews.setOnClickPendingIntent(R.id.buttonOne,
actionPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}
@Override
public void onReceive(Context context, Intent intent) {
// v1.5 fix that doesn't call onDelete Action
final String action = intent.getAction();
Log.d("onReceive",action);
if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
final int appWidgetId = intent.getExtras().getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
this.onDeleted(context, new int[] { appWidgetId });
}
} else {
// check, if our Action was called
if (intent.getAction().equals(VIBRATE_UPDATE)) {
String msg = "null";
try {
msg = intent.getStringExtra("msg");
} catch (NullPointerException e) {
Log.e("Error", "msg = null");
}
Log.d("onReceive",msg);
if(remoteViews != null){
Log.d("onReceive",""+remoteViews.getLayoutId());
remoteViews.setImageViewResource(R.id.buttonOne, R.drawable.button_pressed_ringer);
Log.d("onReceive", "tried to switch");
}
else{
Log.d("F!", "--naughty language used here!!!--");
}
}
super.onReceive(context, intent);
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我一直在测试这个并且 onReceive 方法工作得很好,我能够发送通知和各种东西(从代码中删除以方便阅读)
我不能做的一件事是更改视图元素的任何属性。
为了尝试解决这个问题,我将 RemoteViews 设为本地和静态私有变量。使用日志我能够看到当应用程序的多个实例出现在屏幕上时,它们都指的是 RemoteViews 的一个实例。非常适合我正在尝试做的事情
问题在于试图更改 ImageButton 的图像。
我可以使用 this 在 onUpdate 方法中执行此操作。
remoteViews.setImageViewResource(R.id.buttonOne, R.drawable.button_pressed_ringer);
Run Code Online (Sandbox Code Playgroud)
尽管一旦创建了小部件,这对我没有任何好处。出于某种原因,即使它在同一个类中,在 onReceive 方法中也会使该行不起作用。
事实上,该行曾经抛出一个空指针,直到我将变量更改为静态。现在它通过了空测试,引用与开始时相同的 layoutId,读取该行,但它什么也不做。
它就像代码甚至不存在一样,只是不断地前进。
所以......
创建小部件后,有没有办法从小部件内部修改布局元素!?我想根据环境执行此操作,而不是通过配置活动启动。
我一直在看各种问题,这似乎是一个真正没有解决的问题,例如链接文本和链接文本
哦,对于任何发现这个并想要一个很好的小部件入门教程的人来说,这很容易理解(虽然有点旧,但它会让你对小部件感到满意).pdf 链接文本
希望有人可以在这里提供帮助。我有点觉得这是非法的,有一种不同的方法来解决这个问题。我很想被告知另一种方法!!!!
谢谢
您可以使用另一种布局重绘屏幕,仅修改 ImageButton。这听起来像是一个黑客解决方案,但它对我有用。
// Your appWidgetProvider class should track which layout it's currently on
private static int layoutId;
// onReceive should be something like this
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
int newLayoutId = bundle.getInt("layout_id");
// Change the current layout id to the layout id contained in the bundle
layoutId = newLayoutId;
initViews(context);
} else {
initViews(context);
}
}
// Initialize the view according to the chosen layout
private void initViews(Context context) {
RemoteViews views = null;
// Set the initial layout
if (layoutId == 0) {
Intent layoutIntent = new Intent("android.appwidget.action.APPWIDGET_UPDATE");
Bundle layoutBundle = new Bundle();
// I put in the layoutId of the next layout. Note that the layoutId is not
// from R. I just made up some easy to remember number for my layoutId
layoutBundle.putInt("layout_id", 1);
PendingIntent lPendingIntent = PendingIntent.getBroadcast(context, 0,
layoutIntent, PendingIntent.FLAG_ONE_SHOT);
// Set the layout to the first layout
views = new RemoteViews(context.getPackageName(), R.layout.layout_zero);
// I used buttons to trigger a layout change
views.setOnClickPendingIntent(R.id.btnNext, lPendingIntent);
} // Else if there's some trigger to change the layout...
else if (layoutId == 1) {
Intent layoutIntent = new Intent("android.appwidget.action.APPWIDGET_UPDATE");
Bundle layoutBundle = new Bundle();
// Since I only have two layouts, I put here the id of the previous layout
layoutBundle.putInt("layout_id", 0);
PendingIntent lPendingIntent = PendingIntent.getBroadcast(context, 0,
layoutIntent, PendingIntent.FLAG_ONE_SHOT);
// Set the layout to the second layout
// This layout should be almost the same as the first layout except for the
// part that you want to change
views = new RemoteViews(context.getPackageName(), R.layout.layout_one);
views.setOnClickPendingIntent(R.id.btnPrev, lPendingIntent);
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我使用了两种不同的布局,用户可以通过单击按钮进行切换。您可以根据需要使用不同的触发器来更改布局。可以在链接文本中找到类似的解决方案。请原谅我将代码放在 onReceive 而不是 onUpdate :)
| 归档时间: |
|
| 查看次数: |
5671 次 |
| 最近记录: |