Update app widget on click in android

2019-05-04 10:09发布

I am working on Android Widget my widget is like following diagram, [prev] event name [next]

prev, next are the buttons on the widget.So i want to update the event name on click of next and prev button.On start of the service i loaded the data and stored it in array list. Now i want to iterate through the array list by clicking the next and prev buttons on the widget.

So how can i achieve this.Please help me with proper solution. Here is my xml layout

<LinearLayout
    android:id="@+id/lytWidget2"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dip"
    android:orientation="horizontal" >

    <Button
        android:id="@+id/btnPreviousView"
        android:layout_width="43dp"
        android:layout_height="fill_parent"
        android:layout_gravity="left|center"
        android:background="@drawable/ic_leftarrow"
        android:padding="5dip" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="52dp"
        android:layout_weight="0.97"
        android:text="Event Name" />

    <Button
        android:id="@+id/btnNextView"
        android:layout_width="43dp"
        android:layout_height="fill_parent"
        android:layout_gravity="right|center_vertical"
        android:background="@drawable/ic_rightarrow"
        android:padding="5dip" />
</LinearLayout>

3条回答
看我几分像从前
2楼-- · 2019-05-04 10:53

So, just handle the click events of your buttons in the AppWidgetProvider class like this. See this good tutorial on how to create simple widget. There are click handlers added too.

Sample code

 @Override 
 public void onReceive(Context context, Intent intent) 
 { 
      super.onReceive(context, intent); 

      RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
      // find your TextView here by id here and update it.

      Toast.makeText(context, "Clicked!!", Toast.LENGTH_SHORT).show(); 
 } 
查看更多
看我几分像从前
3楼-- · 2019-05-04 10:53

NewAppWidget.java

package com.example.android.appwidgetsample;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.widget.RemoteViews;

import java.text.DateFormat;
import java.util.Date;

/**
 * App widget provider class, to handle update broadcast intents and updates
 * for the app widget.
 */
public class NewAppWidget extends AppWidgetProvider {

    // Name of shared preferences file & key
    private static final String SHARED_PREF_FILE =
            "com.example.android.appwidgetsample";
    private static final String COUNT_KEY = "count";

    /**
     * Update a single app widget.  This is a helper method for the standard
     * onUpdate() callback that handles one widget update at a time.
     *
     * @param context          The application context.
     * @param appWidgetManager The app widget manager.
     * @param appWidgetId      The current app widget id.
     */
    private void updateAppWidget(Context context,
                                AppWidgetManager appWidgetManager,
                                int appWidgetId) {

        // Get the count from prefs.
        SharedPreferences prefs =
                context.getSharedPreferences(SHARED_PREF_FILE, 0);
        int count = prefs.getInt(COUNT_KEY + appWidgetId, 0);
        count++;

        // Get the current time.
        String dateString =
                DateFormat.getTimeInstance(DateFormat.SHORT).format(new Date());

        // Construct the RemoteViews object.
        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.new_app_widget);
        views.setTextViewText(R.id.appwidget_id,
                String.valueOf(appWidgetId));
        views.setTextViewText(R.id.appwidget_update,
                context.getResources().getString(
                    R.string.date_count_format, count, dateString));

        // Save count back to prefs.
        SharedPreferences.Editor prefEditor = prefs.edit();
        prefEditor.putInt(COUNT_KEY + appWidgetId, count);
        prefEditor.apply();

        // Setup update button to send an update request as a pending intent.
        Intent intentUpdate = new Intent(context, NewAppWidget.class);

        // The intent action must be an app widget update.
        intentUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);

        // Include the widget ID to be updated as an intent extra.
        int[] idArray = new int[]{appWidgetId};
        intentUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray);

        // Wrap it all in a pending intent to send a broadcast.
        // Use the app widget ID as the request code (third argument) so that
        // each intent is unique.
        PendingIntent pendingUpdate = PendingIntent.getBroadcast(context,
                appWidgetId, intentUpdate, PendingIntent.FLAG_UPDATE_CURRENT);

        // Assign the pending intent to the button onClick handler
        views.setOnClickPendingIntent(R.id.button_update, pendingUpdate);

        // Instruct the widget manager to update the widget.
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

    /**
     * Override for onUpdate() method, to handle all widget update requests.
     *
     * @param context          The application context.
     * @param appWidgetManager The app widget manager.
     * @param appWidgetIds     An array of the app widget IDs.
     */
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                         int[] appWidgetIds) {
        // There may be multiple widgets active, so update all of them.
        for (int appWidgetId : appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }
}

NewAppWidget.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#09C"
                android:padding="@dimen/widget_margin" >

    <!-- Panel for Widget ID -->
    <LinearLayout
        android:id="@+id/section_id"
        style="@style/AppWidgetSection"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/appwidget_id_label"
            style="@style/AppWidgetLabel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:text="@string/widget_id_label"/>

        <TextView
            android:id="@+id/appwidget_id"
            style="@style/AppWidgetText"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="end"
            android:text="XX"/>
    </LinearLayout>

    <!-- Panel for widget update date and number of updates -->
    <LinearLayout
        android:id="@+id/section_update"
        style="@style/AppWidgetSection"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/section_id"
        android:orientation="vertical">

        <TextView
            android:id="@+id/appwidget_update_label"
            style="@style/AppWidgetLabel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="2dp"
            android:text="@string/widget_update_label"/>

        <TextView
            android:id="@+id/appwidget_update"
            style="@style/AppWidgetText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/date_count_format"/>
    </LinearLayout>

    <!-- Update widget button -->
    <Button
        android:id="@+id/button_update"
        style="@style/AppWidgetButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/section_update"
        android:layout_centerHorizontal="true"
        android:text="@string/widget_button_update" />
</RelativeLayout>
查看更多
Bombasti
4楼-- · 2019-05-04 10:54

First, in your WidgetProviderClass you should define your actions so that you could differentiate them. In this case:

private static final String ACTION_UPDATE_CLICK_NEXT = "action.UPDATE_CLICK_NEXT";
private static final String ACTION_UPDATE_CLICK_PREVIOUS = "action.UPDATE_CLICK_PREVIOUS";

Next, in your overrided onUpdate() funcion you should put:

@Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

            RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.your_widget_layout);

            views.setOnClickPendingIntent(R.id.nextButtonWidget, getPendingSelfIntent(context, ACTION_UPDATE_CLICK_NEXT));
            views.setOnClickPendingIntent(R.id.previousButtonWidget, getPendingSelfIntent(context, ACTION_UPDATE_CLICK_PREVIOUS));

}

Function for creating an intent that's directed to the current class (to itself):

private PendingIntent getPendingSelfIntent(Context context, String action) {

        Intent intent = new Intent(context, getClass()); // An intent directed at the current class (the "self").
        intent.setAction(action);
        return PendingIntent.getBroadcast(context, 0, intent, 0);
    }

When the event occurs onReceive() function will be called:

    @Override
        public void onReceive(Context context, Intent intent) {
            super.onReceive(context, intent);


            if (ACTION_UPDATE_CLICK_NEXT.equals(intent.getAction())) {
                 // if the user clicked next
                }


            else if (ACTION_UPDATE_CLICK_PREVIOUS.equals(intent.getAction())) {
                // if the user clicked previous
        }

}

BONUS: If you want to call the onUpdate() function here is a function that will do that for you. It requires only the context parameter!

/**
 * A general technique for calling the onUpdate method,
 * requiring only the context parameter.
 *
 * @author John Bentley, based on Android-er code.
 * @see <a href="http://android-er.blogspot.com
 * .au/2010/10/update-widget-in-onreceive-method.html">
 * Android-er > 2010-10-19 > Update Widget in onReceive() method</a>
 */

private void onUpdate(Context context) {

    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    ComponentName thisAppWidgetComponentName = new ComponentName(context.getPackageName(), getClass().getName());
    int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidgetComponentName);
    onUpdate(context, appWidgetManager, appWidgetIds);
}
查看更多
登录 后发表回答