从里面的Widget AppWidgetProvider访问布局项目 [英] Accessing Layout Items from inside Widget AppWidgetProvider

查看:73
本文介绍了从里面的Widget AppWidgetProvider访问布局项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始发疯试图弄清楚这一点。现在看来似乎应该是很容易的,我开始不知道这是可能的。

I am starting to go insane trying to figure this out. It seems like it should be very easy, I'm starting to wonder if it's possible.

我所要做的是创建一个主屏幕小部件,只包含的ImageButton。 当pressed,这个想法是改变一些设置(如在Wi-Fi切换),然后更改按钮图像。

What I am trying to do is create a home screen widget, that only contains an ImageButton. When it is pressed, the idea is to change some setting (like the wi-fi toggle) and then change the Buttons image.

我有ImageButton的声明像这样在我的main.xml

I have the ImageButton declared like this in my main.xml

<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" />

我AppWidgetProvider类,名为ButtonWidget

my AppWidgetProvider class, named ButtonWidget

* 的注意,RemoteViews类是本地存储的变量。这让我获得访问RViews布局元素......我这样想着。

* note that the RemoteViews class is a locally stored variable. this allowed me to get access to the RViews layout elements... or so I thought.

@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);
    }
}

所以,我一直在测试这个和的onReceive方法的伟大工程,我能发送通知和各种材料(由code删除为了便于阅读)

so, I've been testing this and the onReceive method works great, I'm able to send notifications and all sorts of stuff (removed from code for ease of reading)

一件事,我不能做的就是改变视图元素的任何属性。

the one thing I can't do is change any properties of the view elements.

要试图解决这个问题,我做了RemoteViews本地和静态私有变量。使用日志的,我能够看到,当应用程序的多个实例是在屏幕上,他们都提到RemoteViews的一个实例。完美的我想要做的。

To try and fix this, I made RemoteViews a local and static private variable. Using log's I was able to see that When multiple instances of the app are on screen, they all refer to the one instance of RemoteViews. perfect for what I'm trying to do

麻烦的是在试图改变的ImageButton的形象。

The trouble is in trying to change the image of the ImageButton.

我可以使用这个方法的OnUpdate内做到这一点。

I can do this from within the onUpdate method using this.

remoteViews.setImageViewResource(R.id.buttonOne, R.drawable.button_pressed_ringer);

在创建Widget不我好,但。 出于某种原因,即使它在同一类中,作为的onReceive方法中,使该行无法正常工作。

that doesn't do me any good though once the widget is created. For some reason, even though its inside the same class, being inside the onReceive method makes that line not work.

用于抛出一个空指针事实上,直到我改变了变量静态的这条线。现在它通过空试验,是指在相同的layoutId,因为它没有在一开始,读取该行,但不起任何作用。

That line used to throw a Null pointer as a matter of fact, until I changed the variable to static. now it passes the null test, refers to the same layoutId as it did at the start, reads the line, but it does nothing.

它像code不是即使在那里,只是保持车轮继续滚滚向前。

Its like the code isn't even there, just keeps chugging along.

所以......

有什么办法给小窗口创建后,从一个小窗口中修改布局元素!? 我想这样做基于环境,不与配置活动启动。

Is there any way to modify layout elements from within a widget after the widget has been created!? I want to do this based on the environment, not with a configuration activity launch.

我一直在寻找各种各样的问题,这似乎是真的还没有得到解决,如<一个问题href="http://stackoverflow.com/questions/2181588/whats-the-proper-way-to-implement-an-android-widget-with-dynamically-drawn-conte">link文字和链接文本

I've been looking at various questions and this seems to be an issue that really hasn't been solved, such as link text and link text

哦,和任何人谁发现这一点,并希望一个好的开始教程窗口小部件,这是容易做到的(虽然有点老了,它可以让你舒服的小部件).PDF 链接文本

oh and for anyone who finds this and wants a good starting tutorial for widgets, this is easy to follow (though a bit old, it gets you comfortable with widgets) .pdf link text

希望有人能帮助在这里。我还挺有感觉,这是非法的,有一种不同的方式来进行此事。我很想告诉另一种方法!!!!

hopefully someone can help here. I kinda have the feeling that this is illegal and there is a different way to go about this. I would LOVE to be told another approach!!!!

感谢

推荐答案

您可以重绘使用其他布局,只修改了的ImageButton屏幕。这听起来像一个hackish的解决方案,但它为我工作。

You can redraw the screen using another layout with only the ImageButton modified. This sounds like a hackish solution but it works for me.

// 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);
    }
}

正如你所看到的,我使用它,用户可以通过点击按钮来切换两种不同的布局。您可以使用不同的触发器来改变布局取决于你所需要的。类似的解决方案,可以发现的链接文本。原谅我把code中的onReceive代替的onupdate:)

As you can see, I used two different layouts which the user is able to switch via button clicks. You can use different triggers to change the layout depending on what you need. A similar solution can be found link text. Pardon me for putting the code in onReceive instead of onUpdate :)

这篇关于从里面的Widget AppWidgetProvider访问布局项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆