Change numColumns in GridView in Widget (RemoteViews) has no effect
Asked Answered
B

4

7

I have a widget(which works) with a GridView, which shows information in 1 or more columns/rows. I want to set the number of columns programmatically, cause the users shall choose. If I set the numColumns inside the Layout-XML to "1", it works fine. If I try to set the numColumns in the following way, it has no effect:

    rViews.setInt(R.id.duration_view, "setNumColumns", 1);

Layout looks like this:

    <GridView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/duration_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:minHeight="64dp"
        android:verticalSpacing="0dp"
        android:columnWidth="192dp"
        android:numColumns="auto_fit"
    />

My widget onUpdate() method, using the RemoteAdapter:

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // ....
        Intent intent = new Intent(context, ViewFlipperWidgetService.class);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
        RemoteViews rViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
        rViews.setRemoteAdapter(R.id.duration_view, intent);
        rViews.setEmptyView(R.id.duration_view, R.id.empty_view);

        // This doesnt have any effect...:-(
        rViews.setInt(R.id.duration_view, "setNumColumns", 1); 

        appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.duration_view);            

        AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, rViews);

        // ....
        super.onUpdate(context, appWidgetManager, appWidgetIds);

Not only the setNumColumns has no effect, other method calls as well. What I'm doing wrong?

Byrom answered 5/12, 2012 at 14:50 Comment(1)
please accept the answer below if it resolves your question.Milkandwater
M
3

The only methods you can call against a RemoteViews view are those with the @android.view.RemotableViewMethod annotation. There are only three such methods for GridView:

@android.view.RemotableViewMethod
public void setRemoteViewsAdapter(Intent intent) {

@android.view.RemotableViewMethod
public void smoothScrollToPosition(int position) {

@android.view.RemotableViewMethod
public void smoothScrollByOffset(int offset) {

You can verify this yourself:

https://android.googlesource.com/platform/frameworks/base/+/jb-release/core/java/android/widget/GridView.java

Milkandwater answered 2/5, 2013 at 3:2 Comment(0)
D
3

I'm trying to find this answer myself.

The only way I've found to do it so far is to change your initial RemoteViews object to use a different resource for each column amount:

RemoteViews rViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout_1_column);

or

RemoteViews rViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout_3_columns);

This works but I can't imagine it's efficient to either code or to run. But again, it works so...

Diabolize answered 17/7, 2013 at 15:7 Comment(0)
P
0

Very late to the party but still...

I solved that by defining GridLayout with columnCount = max possible in app. (ie 10).

I let user define how many cols he wants to see. (ie 3).

Than when I fill GridLayout I set as many real buttons as set by users, in other columns I set only filler buttons and also hide them. When all columns in one row are filled I again start to set real buttons.

Here is the code... Pay attention to appWidgetCols and buttonsInRow varibles.

  @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
  {
    super.onUpdate(context, appWidgetManager, appWidgetIds);
    for (int appWidgetId : appWidgetIds) {
      RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.novawidgets_widget);

      SharedPref                sp              = new SharedPref(context);
      String                    widgetsAllCache = sp.getString("widgets_all_cache");
      DoorWidgets.WidgetsAllMap widgetsAll      = new DoorWidgets.WidgetsAllMap();
      if (!"".equals(widgetsAllCache))
        widgetsAll = Json.fromJson(widgetsAllCache, DoorWidgets.WidgetsAllMap.class);

      String appWidgetHwIds = sp.getString("appwidget_hwids");
      int    appWidgetCols  = sp.getInt("appwidget_cols");
      if (appWidgetCols == 0)
        appWidgetCols = 2;
      views.removeAllViews(R.id.widget_buttons_container);
      int         buttonsInRow = 0;
      RemoteViews btn;
      if (widgetsAll != null) {
        for (String hwId : appWidgetHwIds.split(",")) {
          if (widgetsAll.containsKey(hwId)) {
            while (buttonsInRow >= appWidgetCols) {
              btn = new RemoteViews(context.getPackageName(), R.layout.novawidgets_button);
              btn.setViewVisibility(R.id.widget_button_container, GONE);
              views.addView(R.id.widget_buttons_container, btn);
              buttonsInRow++;

              if (buttonsInRow >= 10)
                buttonsInRow = 0;
            }
            WidgetCache widget = widgetsAll.get(hwId);
            assert widget != null;
            btn = new RemoteViews(context.getPackageName(), R.layout.novawidgets_button);
            btn.setImageViewResource(R.id.widget_button,
                                     widget.type == DOOR ? R.drawable.door_closed_vector : R.drawable.ic_light_vector);
            btn.setTextViewText(R.id.widget_name, widget.hwName);
            views.addView(R.id.widget_buttons_container, btn);
            buttonsInRow++;
          }
        }
      }
      appWidgetManager.updateAppWidget(appWidgetId, views);
    }
  }

Prescriptible answered 28/7, 2020 at 12:13 Comment(0)
O
0

Super necro, but

rViews.setInt(R.id.duration_view, "setNumColumns", 1);

does work for me in 2024. Tested on Android 12.

Outcross answered 28/6, 2024 at 7:40 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.