[embedyt] https://www.youtube.com/watch?v=0ehrgrKi9eE[/embedyt]
gradient.xmlexample_widget_item.xmlExampleWidgetService.javaactivity_example_app_widget_config.xmlExampleAppWidgetConfig.javaexample_widget.xmlExampleAppWidgetProvider.javaexample_appwidget_info.xmlAndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <gradient android:angle="90" android:endColor="#044fab" android:startColor="#9cefee" /> </shape>
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/example_widget_item_text" android:layout_width="200dp" android:layout_height="200dp" android:background="@drawable/gradient" android:gravity="center" android:text="Item" android:textColor="@android:color/white" android:textSize="20sp" android:textStyle="bold" />
package com.codinginflow.widgetexample; import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; import android.os.SystemClock; import android.widget.RemoteViews; import android.widget.RemoteViewsService; import java.text.DateFormat; import java.util.Date; public class ExampleWidgetService extends RemoteViewsService { @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { return new ExampleWidgetItemFactory(getApplicationContext(), intent); } class ExampleWidgetItemFactory implements RemoteViewsFactory { private Context context; private int appWidgetId; private String[] exampleData = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"}; ExampleWidgetItemFactory(Context context, Intent intent) { this.context = context; this.appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); } @Override public void onCreate() { //connect to data source } @Override public void onDataSetChanged() { //refresh data Date date = new Date(); String timeFormatted = DateFormat.getTimeInstance(DateFormat.SHORT).format(date); exampleData = new String[]{"one\n" + timeFormatted, "two\n" + timeFormatted, "three\n" + timeFormatted}; SystemClock.sleep(3000); } @Override public void onDestroy() { //close data source } @Override public int getCount() { return exampleData.length; } @Override public RemoteViews getViewAt(int position) { RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_widget_item); views.setTextViewText(R.id.example_widget_item_text, exampleData[position]); Intent fillIntent = new Intent(); fillIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); views.setOnClickFillInIntent(R.id.example_widget_item_text, fillIntent); SystemClock.sleep(500); return views; } @Override public RemoteViews getLoadingView() { return null; } @Override public int getViewTypeCount() { return 1; } @Override public long getItemId(int position) { return position; } @Override public boolean hasStableIds() { return true; } } }
<?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="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" tools:context="com.codinginflow.widgetexample.ExampleAppWidgetConfig"> <EditText android:id="@+id/edit_text_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="16dp" android:hint="Button text" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="confirmConfiguration" android:text="Confirm" /> </LinearLayout>
package com.codinginflow.widgetexample; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.RemoteViews; import static com.codinginflow.widgetexample.ExampleAppWidgetProvider.ACTION_REFRESH; public class ExampleAppWidgetConfig extends AppCompatActivity { public static final String SHARED_PREFS = "prefs"; public static final String KEY_BUTTON_TEXT = "keyButtonText"; private int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; private EditText editTextButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_example_app_widget_config); Intent configIntent = getIntent(); Bundle extras = configIntent.getExtras(); if (extras != null) { appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); } Intent resultValue = new Intent(); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); setResult(RESULT_CANCELED, resultValue); if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { finish(); } editTextButton = findViewById(R.id.edit_text_button); } public void confirmConfiguration(View v) { AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this); Intent buttonIntent = new Intent(this, MainActivity.class); PendingIntent buttonPendingIntent = PendingIntent.getActivity(this, 0, buttonIntent, 0); String buttonText = editTextButton.getText().toString(); Intent serviceIntent = new Intent(this, ExampleWidgetService.class); serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); Intent clickIntent = new Intent(this, ExampleAppWidgetProvider.class); clickIntent.setAction(ACTION_REFRESH); PendingIntent clickPendingIntent = PendingIntent.getBroadcast(this, 0, clickIntent, 0); RemoteViews views = new RemoteViews(this.getPackageName(), R.layout.example_widget); views.setOnClickPendingIntent(R.id.example_widget_button, buttonPendingIntent); views.setCharSequence(R.id.example_widget_button, "setText", buttonText); views.setRemoteAdapter(R.id.example_widget_stack_view, serviceIntent); views.setEmptyView(R.id.example_widget_stack_view, R.id.example_widget_empty_view); views.setPendingIntentTemplate(R.id.example_widget_stack_view, clickPendingIntent); appWidgetManager.updateAppWidget(appWidgetId, views); SharedPreferences prefs = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putString(KEY_BUTTON_TEXT + appWidgetId, buttonText); editor.apply(); Intent resultValue = new Intent(); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); setResult(RESULT_OK, resultValue); finish(); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:gravity="center_horizontal" android:orientation="vertical"> <TextView android:id="@+id/example_widget_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#FFF" android:text="My Widget" android:textAppearance="@style/TextAppearance.AppCompat.Large" /> <Button android:id="@+id/example_widget_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Press me" /> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <StackView android:id="@+id/example_widget_stack_view" android:layout_width="match_parent" android:layout_height="match_parent" android:loopViews="true" /> <TextView android:id="@+id/example_widget_empty_view" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/darker_gray" android:gravity="center" android:text="Empty" android:textColor="@android:color/white" android:textSize="20sp" android:textStyle="bold" /> </FrameLayout> </LinearLayout>
package com.codinginflow.widgetexample; 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.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.RemoteViews; import android.widget.Toast; import static com.codinginflow.widgetexample.ExampleAppWidgetConfig.KEY_BUTTON_TEXT; import static com.codinginflow.widgetexample.ExampleAppWidgetConfig.SHARED_PREFS; public class ExampleAppWidgetProvider extends AppWidgetProvider { public static final String ACTION_REFRESH = "actionRefresh"; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { for (int appWidgetId : appWidgetIds) { Intent buttonIntent = new Intent(context, MainActivity.class); PendingIntent buttonPendingIntent = PendingIntent.getActivity(context, 0, buttonIntent, 0); SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE); String buttonText = prefs.getString(KEY_BUTTON_TEXT + appWidgetId, "Press me"); Intent serviceIntent = new Intent(context, ExampleWidgetService.class); serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); Intent clickIntent = new Intent(context, ExampleAppWidgetProvider.class); clickIntent.setAction(ACTION_REFRESH); PendingIntent clickPendingIntent = PendingIntent.getBroadcast(context, 0, clickIntent, 0); RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_widget); views.setOnClickPendingIntent(R.id.example_widget_button, buttonPendingIntent); views.setCharSequence(R.id.example_widget_button, "setText", buttonText); views.setRemoteAdapter(R.id.example_widget_stack_view, serviceIntent); views.setEmptyView(R.id.example_widget_stack_view, R.id.example_widget_empty_view); views.setPendingIntentTemplate(R.id.example_widget_stack_view, clickPendingIntent); Bundle appWidgetOptions = appWidgetManager.getAppWidgetOptions(appWidgetId); resizeWidget(appWidgetOptions, views); appWidgetManager.updateAppWidget(appWidgetId, views); appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.example_widget_stack_view); } } @Override public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_widget); resizeWidget(newOptions, views); appWidgetManager.updateAppWidget(appWidgetId, views); } private void resizeWidget(Bundle appWidgetOptions, RemoteViews views) { int minWidth = appWidgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH); int maxWidth = appWidgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH); int minHeight = appWidgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT); int maxHeight = appWidgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT); if (maxHeight > 100) { views.setViewVisibility(R.id.example_widget_text, View.VISIBLE); views.setViewVisibility(R.id.example_widget_button, View.VISIBLE); } else { views.setViewVisibility(R.id.example_widget_text, View.GONE); views.setViewVisibility(R.id.example_widget_button, View.GONE); } } @Override public void onDeleted(Context context, int[] appWidgetIds) { Toast.makeText(context, "onDeleted", Toast.LENGTH_SHORT).show(); } @Override public void onEnabled(Context context) { Toast.makeText(context, "onEnabled", Toast.LENGTH_SHORT).show(); } @Override public void onDisabled(Context context) { Toast.makeText(context, "onDisabled", Toast.LENGTH_SHORT).show(); } @Override public void onReceive(Context context, Intent intent) { if (ACTION_REFRESH.equals(intent.getAction())) { int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.example_widget_stack_view); } super.onReceive(context, intent); } }
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:autoAdvanceViewId="@id/example_widget_stack_view" android:configure="com.codinginflow.widgetexample.ExampleAppWidgetConfig" android:initialLayout="@layout/example_widget" android:minHeight="110dp" android:minResizeHeight="40dp" android:minWidth="110dp" android:previewImage="@drawable/widget_preview" android:resizeMode="vertical|horizontal" android:updatePeriodMillis="3600000" android:widgetCategory="home_screen" />
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.codinginflow.widgetexample"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".ExampleAppWidgetProvider"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/example_appwidget_info" /> </receiver> <activity android:name=".ExampleAppWidgetConfig"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> </intent-filter> </activity> <service android:name=".ExampleWidgetService" android:permission="android.permission.BIND_REMOTEVIEWS" /> </application> </manifest>