Last active
August 4, 2018 06:04
-
-
Save HRankit/d9df12912d2d25a0ec1908faf64743e7 to your computer and use it in GitHub Desktop.
This is gist for creating a widget. Let me know if something is missing. The Widget has a gridview which shows an image and text below it. It is set to show only one item per column.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<appwidget-provider | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
android:minWidth="180dp" | |
android:minHeight="180dp" | |
android:updatePeriodMillis="10000" | |
android:previewImage="@drawable/ic_tablespoon" | |
android:initialLayout="@layout/widget_layout" | |
android:resizeMode="horizontal|vertical" | |
> | |
</appwidget-provider> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.udacity.baketime.baketime.widget; | |
import android.app.PendingIntent; | |
import android.appwidget.AppWidgetManager; | |
import android.appwidget.AppWidgetProvider; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.net.Uri; | |
import android.widget.RemoteViews; | |
import android.widget.Toast; | |
import com.udacity.baketime.baketime.MainActivity; | |
import com.udacity.baketime.baketime.R; | |
import static com.udacity.baketime.baketime.misc.MiscFunctions.ACTION_FROM_WIDGET; | |
import static com.udacity.baketime.baketime.misc.MiscFunctions.INTENT_FROM_WIDGET; | |
public class StackWidgetProvider extends AppWidgetProvider { | |
public static final String TOAST_ACTION = "com.example.android.stackwidget.TOAST_ACTION"; | |
public static final String EXTRA_ITEM = "com.example.android.stackwidget.EXTRA_ITEM"; | |
@Override | |
public void onDeleted(Context context, int[] appWidgetIds) { | |
super.onDeleted(context, appWidgetIds); | |
} | |
@Override | |
public void onDisabled(Context context) { | |
super.onDisabled(context); | |
} | |
@Override | |
public void onEnabled(Context context) { | |
super.onEnabled(context); | |
} | |
@Override | |
public void onReceive(Context context, Intent intent) { | |
AppWidgetManager mgr = AppWidgetManager.getInstance(context); | |
if (intent.getAction().equals(TOAST_ACTION)) { | |
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, | |
AppWidgetManager.INVALID_APPWIDGET_ID); | |
int viewIndex = intent.getIntExtra(EXTRA_ITEM, 0); | |
Toast.makeText(context, "Touched view " + viewIndex, Toast.LENGTH_SHORT).show(); | |
startMainActivity(context, viewIndex); | |
} | |
super.onReceive(context, intent); | |
} | |
public void startMainActivity(Context context, int positions) { | |
Intent toastIntent = new Intent(context, MainActivity.class); | |
toastIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); | |
toastIntent.setAction(ACTION_FROM_WIDGET); | |
toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, positions); | |
toastIntent.putExtra(INTENT_FROM_WIDGET, positions); | |
context.startActivity(toastIntent); | |
} | |
@Override | |
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { | |
// update each of the widgets with the remote adapter | |
for (int i = 0; i < appWidgetIds.length; ++i) { | |
// Here we setup the intent which points to the StackViewService which will | |
// provide the views for this collection. | |
Intent intent = new Intent(context, StackWidgetService.class); | |
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); | |
// When intents are compared, the extras are ignored, so we need to embed the extras | |
// into the data so that the extras will not be ignored. | |
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); | |
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout); | |
rv.setRemoteAdapter(appWidgetIds[i], R.id.gridView1, intent); | |
// The empty view is displayed when the collection has no items. It should be a sibling | |
// of the collection view. | |
rv.setEmptyView(R.id.gridView1, R.id.empty_view); | |
// Here we setup the a pending intent template. Individuals items of a collection | |
// cannot setup their own pending intents, instead, the collection as a whole can | |
// setup a pending intent template, and the individual items can set a fillInIntent | |
// to create unique before on an item to item basis. | |
Intent toastIntent = new Intent(context, StackWidgetProvider.class); | |
toastIntent.setAction(StackWidgetProvider.TOAST_ACTION); | |
toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]); | |
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); | |
PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent, | |
PendingIntent.FLAG_UPDATE_CURRENT); | |
rv.setPendingIntentTemplate(R.id.gridView1, toastPendingIntent); | |
appWidgetManager.updateAppWidget(appWidgetIds[i], rv); | |
} | |
super.onUpdate(context, appWidgetManager, appWidgetIds); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.udacity.baketime.baketime.widget; | |
import java.util.ArrayList; | |
import java.util.List; | |
import android.appwidget.AppWidgetManager; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.os.Bundle; | |
import android.widget.RemoteViews; | |
import android.widget.RemoteViewsService; | |
import com.google.gson.Gson; | |
import com.google.gson.reflect.TypeToken; | |
import com.udacity.baketime.baketime.R; | |
import com.udacity.baketime.baketime.misc.MyPreferences; | |
import static com.udacity.baketime.baketime.misc.MiscFunctions.EXTRA_WIDGET_DATA; | |
import static com.udacity.baketime.baketime.misc.MiscFunctions.MAIN_ACTIVITY; | |
import static com.udacity.baketime.baketime.misc.MiscFunctions.NUMBER_OF_STEPS; | |
import static com.udacity.baketime.baketime.misc.MiscFunctions.WHICH_ACTIVITY; | |
import static com.udacity.baketime.baketime.misc.MiscFunctions.isEmpty; | |
public class StackWidgetService extends RemoteViewsService { | |
@Override | |
public RemoteViewsFactory onGetViewFactory(Intent intent) { | |
return new StackRemoteViewsFactory(this.getApplicationContext(), intent); | |
} | |
} | |
class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { | |
private int mStepsCount; | |
private List<WidgetItem> mWidgetItems = new ArrayList<WidgetItem>(); | |
private Context mContext; | |
private int mAppWidgetId; | |
public StackRemoteViewsFactory(Context context, Intent intent) { | |
mContext = context; | |
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, | |
AppWidgetManager.INVALID_APPWIDGET_ID); | |
} | |
public void onCreate() { | |
// In onCreate() you setup any connections / cursors to your data source. Heavy lifting, | |
// for example downloading or creating content etc, should be deferred to onDataSetChanged() | |
// or getViewAt(). Taking more than 20 seconds in this call will result in an ANR. | |
MyPreferences yourPrefrence = MyPreferences.getInstance(mContext); | |
mStepsCount = yourPrefrence.getDataInt(NUMBER_OF_STEPS); | |
if (yourPrefrence.getDataInt(WHICH_ACTIVITY) == MAIN_ACTIVITY){ | |
Gson gson = new Gson(); | |
java.lang.reflect.Type type = new TypeToken<List<String>>() {}.getType(); | |
String json = yourPrefrence.getData(EXTRA_WIDGET_DATA); | |
if (!isEmpty(json)){ | |
List<String> arrayList = gson.fromJson(json, type); | |
for (int i = 0; i < mStepsCount; i++) { | |
mWidgetItems.add(new WidgetItem(arrayList.get(i))); | |
} | |
} | |
} | |
// We sleep for 3 seconds here to show how the empty view appears in the interim. | |
// The empty view is set in the StackWidgetProvider and should be a sibling of the | |
// collection view. | |
try { | |
Thread.sleep(3000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
public void onDestroy() { | |
// In onDestroy() you should tear down anything that was setup for your data source, | |
// eg. cursors, connections, etc. | |
mWidgetItems.clear(); | |
} | |
public int getCount() { | |
return mStepsCount; | |
} | |
public RemoteViews getViewAt(int position) { | |
// position will always range from 0 to getCount() - 1. | |
// We construct a remote views item based on our widget item xml file, and set the | |
// text based on the position. | |
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item); | |
rv.setTextViewText(R.id.widget_item_text, mWidgetItems.get(position).text); | |
// Next, we set a fill-intent which will be used to fill-in the pending intent template | |
// which is set on the collection view in StackWidgetProvider. | |
Bundle extras = new Bundle(); | |
extras.putInt(StackWidgetProvider.EXTRA_ITEM, position); | |
Intent fillInIntent = new Intent(); | |
fillInIntent.putExtras(extras); | |
// rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent); | |
rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent); | |
rv.setOnClickFillInIntent(R.id.widget_image, fillInIntent); | |
// You can do heaving lifting in here, synchronously. For example, if you need to | |
// process an image, fetch something from the network, etc., it is ok to do it here, | |
// synchronously. A loading view will show up in lieu of the actual contents in the | |
// interim. | |
try { | |
System.out.println("Loading view " + position); | |
Thread.sleep(500); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
// Return the remote views object. | |
return rv; | |
} | |
public RemoteViews getLoadingView() { | |
// You can create a custom loading view (for instance when getViewAt() is slow.) If you | |
// return null here, you will get the default loading view. | |
return null; | |
} | |
public int getViewTypeCount() { | |
return 1; | |
} | |
public long getItemId(int position) { | |
return position; | |
} | |
public boolean hasStableIds() { | |
return true; | |
} | |
public void onDataSetChanged() { | |
// This is triggered when you call AppWidgetManager notifyAppWidgetViewDataChanged | |
// on the collection view corresponding to this factory. You can do heaving lifting in | |
// here, synchronously. For example, if you need to process an image, fetch something | |
// from the network, etc., it is ok to do it here, synchronously. The widget will remain | |
// in its current state while work is being done here, so you don't need to worry about | |
// locking up the widget. | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:orientation="vertical"> | |
<ImageView | |
android:id="@+id/widget_image" | |
android:layout_width="150dp" | |
android:layout_height="150dp" | |
android:layout_gravity="center_horizontal" | |
android:gravity="center" | |
android:src="@mipmap/ic_launcher_foreground" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toStartOf="@+id/widget_item" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<TextView xmlns:android="http://schemas.android.com/apk/res/android" | |
android:id="@+id/widget_item_text" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_margin="5dp" | |
android:autoSizeMaxTextSize="50dp" | |
android:autoSizeMinTextSize="20dp" | |
android:autoSizeStepGranularity="2dp" | |
android:gravity="center" | |
android:layout_gravity="center_horizontal" | |
android:padding="2dp" | |
android:text="Hello World" | |
android:textColor="@color/anothercolorText" | |
android:textSize="24sp" | |
android:textStyle="bold" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:id="@+id/widget_item_layout" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:background="@color/widgetBackgroundColor" | |
android:orientation="vertical"> | |
<TextView xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginBottom="5dp" | |
android:layout_marginTop="10dp" | |
android:gravity="center_horizontal" | |
android:paddingBottom="15dp" | |
android:text="@string/recipe_s_available" | |
android:textColor="#ffffff" | |
android:textSize="20sp" | |
android:fontFamily="serif-monospace" | |
android:textStyle="bold" /> | |
<GridView | |
android:id="@+id/gridView1" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:numColumns="1" /> | |
<TextView xmlns:android="http://schemas.android.com/apk/res/android" | |
android:id="@+id/empty_view" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_gravity="center" | |
android:gravity="center" | |
android:text="@string/time_to_bake" | |
android:textColor="#ffffff" | |
android:textSize="20sp" | |
android:textStyle="bold" /> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.udacity.baketime.baketime.widget; | |
public class WidgetItem { | |
public String text; | |
public WidgetItem(String text) { | |
this.text = text; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment