Widget double click

2020-07-23 04:17发布

I have a widget (AppWidgetProvider) and i want to know if there is a way to support multiple clicks.Example:

1)If is the first click on the widget, then the ImageButton of the widget changes (for example, changes the color).

2)If is the second time, then open an Activity.

-- There is some way to handle click events inside AppWidgetProvider?

My code:

public class MyWidgetProvider extends AppWidgetProvider
{


    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;

        for (int i=0; i<N; i++) {
            int appWidgetId = appWidgetIds[i];    

            Intent intent = new Intent(context, MyActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);


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

            views.setOnClickPendingIntent(R.id.asdf, pendingIntent);

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

My widget is working fine. When i click the ImageButton(R.id.asdf), it goes to the activity MyActivity.

Id like to know how can i handle click events on my widget to make a different action (example: change the color of the ImageButton) instead of go to some activity. Is there some other way to some click handle besides setOnClickPendingIntent()?

标签: android
7条回答
够拽才男人
2楼-- · 2020-07-23 04:50

Maybe this could help. It works for me:

public class WidgetProvider extends AppWidgetProvider {

private static final int DOUBLE_CLICK_DELAY = 500;

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


    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
    Intent intent = new Intent(context, getClass());
    intent.setAction("Click");
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
    views.setOnClickPendingIntent(R.id.image, pendingIntent);
    appWidgetManager.updateAppWidget(appWidgetIds, views);
    context.getSharedPreferences("widget", 0).edit().putInt("clicks", 0).commit();

}

@Override
public void onReceive(final Context context, Intent intent) {

    if (intent.getAction().equals("Click")) {

        int clickCount = context.getSharedPreferences("widget", Context.MODE_PRIVATE).getInt("clicks", 0);
        context.getSharedPreferences("widget", Context.MODE_PRIVATE).edit().putInt("clicks", ++clickCount).commit();

        final Handler handler = new Handler() {
            public void handleMessage(Message msg) {

                int clickCount = context.getSharedPreferences("widget", Context.MODE_PRIVATE).getInt("clicks", 0);

                if (clickCount > 1) Toast.makeText(context, "doubleClick", Toast.LENGTH_SHORT).show();
                else Toast.makeText(context, "singleClick", Toast.LENGTH_SHORT).show();

                context.getSharedPreferences("widget", Context.MODE_PRIVATE).edit().putInt("clicks", 0).commit();
            }
        };

        if (clickCount == 1) new Thread() {
            @Override
            public void run(){
                try {
                    synchronized(this) { wait(DOUBLE_CLICK_DELAY); }
                    handler.sendEmptyMessage(0);
                } catch(InterruptedException ex) {}
            }
        }.start();
    }

    super.onReceive(context, intent);

}

}

查看更多
姐就是有狂的资本
3楼-- · 2020-07-23 04:55

Why not just count the clicks yourself?

private class MyAwesomeClickListener implements OnClickListener {
    private int clicks = 0;
    @Override
    public void onClick(View v) {
        ++clicks;
        //do some cool stuff
    }

}
查看更多
Animai°情兽
4楼-- · 2020-07-23 04:56

I did it this way:

1)If is the first click on the widget, then the ImageButton of the widget changes

2)If is the second time, then open an Activity and return to the inicial ImageButton state.

Im handling click events with setOnClickPendingIntent:

private int[] RESOURCES = {R.drawable.button1,R.drawable.button2};

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


            ComponentName me = new ComponentName(context, MyWidgetProvider.class);
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.my_widget);

            Intent widgetIntent = new Intent(context, MyWidgetProvider.class);
            Intent myIntent= new Intent(context, MyOtherActivity.class); 

            widgetIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
            widgetIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);

            PendingIntent pendingIntent;

            if(clicks == 0)
            {
                clicks = 1;
                remoteViews.setImageViewResource(R.id.my_image_button, RESOURCES[0]);
                pendingIntent = PendingIntent.getBroadcast(context, 0, widgetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
            else if(clicks == 1)
            {
                clicks = 2;
                remoteViews.setImageViewResource(R.id.my_image_button, RESOURCES[1]);
                pendingIntent = PendingIntent.getActivity(context, 0, myIntent,0);
            }
            else //clicks == 2
            {
                clicks = 0;
                remoteViews.setImageViewResource(R.id.my_image_button, RESOURCES[0]);
                pendingIntent = PendingIntent.getBroadcast(context, 0, widgetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            }

            remoteViews.setOnClickPendingIntent(R.id.my_image_button, pendingIntent);

            mgr.updateAppWidget(me, remoteViews);
        }

        @Override
        public void onEnabled(Context context) {
            clicks = 0;     
            super.onEnabled(context);

        }
查看更多
迷人小祖宗
5楼-- · 2020-07-23 04:56

Don't count it in a listener (it's ridiculous, you don't know when your widget will be recycled from the memory and you will lose the value of int clicks)

Persist the number of clicks (add +1 each time it is clicked, restart to 0 when you reach the end of the click "cycle", the end of different click behaviors).

You could persist them in a database, with serialization, or with the shared preferences (I guess the preferences are the easiest way)

查看更多
放荡不羁爱自由
6楼-- · 2020-07-23 05:05

Unlike Button and its subclasses, AppWidget doesn't have the concept of an onClickListener. AppWidgets have to provide a PendingIntent for the application that hosts them to fire when the widget is clicked. If you wanted to track multiple clicks, you would need to have a receiver that filters on an intent specific to your widget and keeps track of how many times it has received it.

Slightly-less-relevant: You might reconsider your behavior model. Android is a one-click-to-take-action environment that doesn't have the same "click-once-to-select" concept like you'd find in, say, Windows. By emulating that behavior, your widget won't behave like all of the other UI elements and may cause confusion. Additionally, if there are two of your widgets on the screen and the user taps one and then the other, both will appear "selected," which probably isn't what you want.

查看更多
劳资没心,怎么记你
7楼-- · 2020-07-23 05:08

This is what I'm doing. Works beautifully =]

public class MyWidgetProvider extends AppWidgetProvider {

    //Length of allowed time in between clicks in milliseconds
    private static final long DOUBLE_CLICK_WINDOW = 400;
    private static volatile long firstClickTimeReference;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;

        for (int i=0; i<N; i++) {
            int appWidgetId = appWidgetIds[i];

            long currentSystemTime = System.currentTimeMillis();

            if(currentSystemTime - firstClickTimeReference <= DOUBLE_CLICK_WINDOW) {
                //double click happened in less than 400 miliseconds
                //so let's start our activity
                Intent intent = new Intent(context, MainActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity( intent );
            } else {
                firstClickTimeReference = currentSystemTime;



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

                Intent intent = new Intent(context, WidgetProvider.class);
                intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);

                PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                        0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
                remoteViews.setOnClickPendingIntent(R.id.actionButton, pendingIntent);
                appWidgetManager.updateAppWidget(widgetId, remoteViews);
            }
        }
    }
}
查看更多
登录 后发表回答