5

我之前问过类似的问题,但我的要求太含糊了。下面的代码绘制了一个漂亮的风格化按钮。当您单击按钮时,您可以输入一个数字,并根据该数字,使用更改背景颜色

remoteViews.setInt(R.id.nmcButton, "setBackgroundColor", 颜色);

不幸的是,当我尝试通过使用来保留样式时

remoteViews.setInt(R.id.nmcButton, "setBackground", 颜色);

小部件不会加载。有没有解决的办法?有没有办法在更改背景颜色的同时保留样式?

以下是一些相关文件

    package test.widget;

    import android.os.Bundle;
    import android.app.PendingIntent;
    import android.appwidget.AppWidgetManager;
    import android.appwidget.AppWidgetProvider;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    import android.widget.RemoteViews;
    import android.graphics.Color;

    public class MyWidget extends AppWidgetProvider {

        private final static String TEST_ACTIVITY = "test.widget.action.TEST_ACTIVITY";
        private final static int INTENT_NO_REQUEST = 0; /* no requestCode */
        private final static int INTENT_NO_FLAGS = 0; /* code for no Flags */
        private int count = 9;

        @Override
        public void onReceive(Context context, Intent intent) {
            super.onReceive(context, intent);
            Bundle b = intent.getExtras();
            if (b != null) {
                count = b.getInt("nmcCount");
                callOnUpdate(context);
            }
        }

        private void callOnUpdate(Context context) {
            AppWidgetManager appWidgetManager = AppWidgetManager
                    .getInstance(context);
            ComponentName thisAppWidget = new ComponentName(
                    context.getPackageName(), MyWidget.class.getName());
            int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
            onUpdate(context, appWidgetManager, appWidgetIds);
        }

        @Override
        public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                int[] appWidgetIds) {
            super.onUpdate(context, appWidgetManager, appWidgetIds);
            buildUpdate(context, appWidgetManager, appWidgetIds);
        }

        private void buildUpdate(Context context,
                AppWidgetManager appWidgetManager, int[] appWidgetIds) {
            final int N = appWidgetIds.length;
            for (int i = 0; i < N; i++) {
                int appWidgetId = appWidgetIds[i];

                RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
                        R.layout.widget);

                Intent intent = new Intent(TEST_ACTIVITY);
                PendingIntent pendingIntent = PendingIntent.getActivity(context,
                        INTENT_NO_REQUEST, intent, INTENT_NO_FLAGS);
                remoteViews.setOnClickPendingIntent(R.id.nmcButton, pendingIntent);
                remoteViews.setTextViewText(R.id.nmcButton, String.valueOf(count));

                // the code below works, but the button does not have nice styling
                // int color = (count >= 5) ? Color.GREEN : Color.RED;
                // remoteViews.setInt(R.id.nmcButton, "setBackgroundColor", color);

                // this code doesn't work, you get "problem loading widget"
                int color = (count >= 5) ? R.drawable.btn_green
                        : R.drawable.btn_red;
                remoteViews.setInt(R.id.nmcButton, "setBackground", color);

                appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
            }
        }
    }

btn_red.xml

    <?xml version="2.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">

        <item android:state_pressed="true"><shape>
       <solid android:color="#ef4444" />

       <stroke android:width="1dp" android:color="#992f2f" />

       <corners android:radius="3dp" />

       <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
    </shape></item>
        <item><shape>
       <gradient android:angle="270" android:endColor="#992f2f" android:startColor="#ef4444" />

       <stroke android:width="1dp" android:color="#992f2f" />

       <corners android:radius="3dp" />

       <padding android:bottom="11dp" android:left="10dp" android:right="10dp" android:top="10dp" />
    </shape></item>

    </selector>

样式.xml

    <resources>
        <style name="ButtonText">
            <item name="android:layout_width">wrap_content</item>
            <item name="android:layout_height">wrap_content</item>
            <item name="android:gravity">center</item>
            <item name="android:layout_margin">1dp</item>
            <item name="android:textSize">10dp</item>
            <item name="android:textStyle">normal</item>
            <item name="android:shadowColor">#000000</item>
            <item name="android:shadowDx">1</item>
            <item name="android:shadowDy">1</item>
            <item name="android:shadowRadius">2</item>
            <item name="android:textColor">#ffffff</item>  
        </style>
        <style name="AppTheme" parent="android:Theme.Light" />
    </resources>
4

4 回答 4

16

一位同事给出了答案,我应该使用:

remoteViews.setInt(R.id.nmcButton, "setBackgroundResource", color);

代替:

remoteViews.setInt(R.id.nmcButton, "setBackground", color);
于 2012-11-21T22:09:20.970 回答
2

I tried this but that didn't work for me.

If you want to set a color in your widget you should do this:

remoteViews.setInt(R.id.nmcButton, "setBackgroundColor", color);
于 2014-09-04T15:47:51.450 回答
0

这对我的小部件中的 ListView 不起作用,所以我想出了一个解决方法:

首先,我将我的布局定义为 FrameLayout,其中有一个 ImageView 来绘制我的背景:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/iv_widget_background"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:orientation="vertical"
        android:padding="@dimen/widget_listview_padding">

        <ListView
            android:id="@+id/lv_widget"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:divider="@null"
            android:dividerHeight="0dp" />
    </LinearLayout>

</FrameLayout>

然后我在 R.drawable 中定义了drawables,如下所示:

红色.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#F44336" />
</shape>

当用户通过 SharedPrefs 更改背景时,我必须执行以下操作:

        Intent intent = new Intent(context, WidgetProvider.class);
        intent.setAction("android.appwidget.action.APPWIDGET_UPDATE");
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
        context.sendBroadcast(intent);

然后在 AppWidgetProvider 的 onUpdate() 函数中,我执行以下操作:

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWdgetIds) {
    try {
        RemoteViews remoteViews;
        for (int appWdgetId : appWdgetIds) {
            remoteViews = updateWidgetListView(context, appWdgetId);
            appWidgetManager.updateAppWidget(appWdgetId, remoteViews);
        }
        super.onUpdate(context, appWidgetManager, appWdgetIds);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private RemoteViews updateWidgetListView(Context context, int appWidgetId) {
    //which layout to show on widget
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
    Intent svcIntent = new Intent(context, WidgetService.class);
    svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);        svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
    remoteViews.setRemoteAdapter(appWidgetId, R.id.lv_widget, svcIntent);

    setBackground(context, remoteViews);

    return remoteViews;
}

private void setBackground(Context context, RemoteViews remoteViews) {
    String background = Utils.getStringValue(context, R.string.pref_widget_backgroundcolor_key,
            R.string.pref_widget_backgroundcolor_default);

    if (!TextUtils.isEmpty(background)) {
        int identifier = context.getResources().getIdentifier(
                background, "drawable", context.getPackageName());
        remoteViews.setImageViewResource(R.id.iv_widget_background, identifier);
    }
}

结果:

在此处输入图像描述

于 2016-01-01T08:46:45.493 回答
0

一种简单可靠的方法是创建一个 imageview 并用我们想要的颜色填充位图:

  Bitmap image = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
  Canvas canvas=new Canvas (image);
  canvas.drawColor (Color.parseColor(color));
  contentView_big.setImageViewBitmap(R.id.ntp_colorhint, image);
于 2020-03-25T22:06:04.377 回答