Hello Friends,
Here we are going to learn how to create Collection widget with each item click event in android.
Widget RemoteView service
Widget RemoteViewFactory
You can find more detail about this xml metadata on http://developer.android.com/guide/topics/appwidgets/index.html#MetaData
Note that here I have created widget_provider_layout.xml file as below.
WidgetProvider class:
Now we required one widget provider class (also called widget receiver)
Now we are ready to see the output of widget. Run application and add widget from widget menu:
Output will be :
Creating RemoteViewService :
Updating WidgetProvider to initialize collection view.
Now adding each item click event for collection and making toast for an item.
To do we have to add setOnClickFillInIntent in getViewAt in WedgetDataProvider.
Now handling click event in WidgetProvider->onReceive:
Download Full source :
https://www.dropbox.com/s/u019v6arbae37oh/CollectionWidget.tar.gz
Hope you like it.
Here we are going to learn how to create Collection widget with each item click event in android.
Final output :
What we required for widget ?
Widget Provider (xml and receiver)
XML stores widget information and reciver update that widget details.
Widget RemoteView service
Remote View (ListView collection) update service which will call RemoteViewFactory.
Widget RemoteViewFactory
RemoteViewFactory used for setting data in listview or gridview, also handling each item getView and its event.
Widget Provider (xml and receiver)
You need to create one xml folder in your res directory and create one file named widget_provider.xml
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/widget_provider_layout" android:minHeight="100dip" android:minResizeHeight="100dip" android:minResizeWidth="100dip" android:minWidth="100dip" android:previewImage="@drawable/ic_launcher" android:resizeMode="vertical|horizontal" android:updatePeriodMillis="1800000" android:widgetCategory="keyguard|home_screen" > </appwidget-provider>
You can find more detail about this xml metadata on http://developer.android.com/guide/topics/appwidgets/index.html#MetaData
Note that here I have created widget_provider_layout.xml file as below.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="@dimen/widget_margin" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#88ffffff" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="Hello Widget" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="#fff" android:textStyle="bold" /> </LinearLayout> </FrameLayout>
WidgetProvider class:
Now we required one widget provider class (also called widget receiver)
package com.dharmangsoni.widgets; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; public class WidgetProvider extends AppWidgetProvider { @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); } }Now we are going to register this provider to AndroidManifest.xml so we can see the output of widget.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.dharmangsoni.collectionwidget" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.dharmangsoni.collectionwidget.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- Widget Receiver --> <receiver android:name="com.dharmangsoni.widgets.WidgetProvider" > <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_provider" /> </receiver> </application> </manifest>
Now we are ready to see the output of widget. Run application and add widget from widget menu:
Ok now we are going to create our required layout for widget as below:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="@dimen/widget_margin" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#bbDEDFDE" android:orientation="vertical" > <LinearLayout android:id="@+id/widgetLayoutMain" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#aaDEDFDE" android:orientation="horizontal" android:paddingLeft="5dp" android:paddingRight="5dp" > <ImageView android:id="@+id/widgetImgLauncher" android:layout_width="32dp" android:layout_height="32dp" android:layout_gravity="center_vertical" android:src="@drawable/ic_launcher" /> <LinearLayout android:id="@+id/widgetTopBar" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" android:paddingBottom="4dp" android:paddingLeft="8dp" android:paddingTop="4dp" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/app_name" android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="#4B4B4D" android:textStyle="bold" /> <TextView android:id="@+id/txvWidgetTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="dharmangsoni.blogspot.in" android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="#4B4B4D" /> </LinearLayout> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="1dp" android:background="#aaa" /> <ListView android:id="@+id/widgetCollectionList" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout> </FrameLayout>
Output will be :
More about widget GUI : http://developer.android.com/guide/practices/ui_guidelines/widget_design.html
Now we are ready with our receiver and xml provider and layout file.
Before create RemoteViewService we have to create RemoteViewFactory for handling listview data.
Widget RemoteViewFactory:
package com.dharmangsoni.widgets; import java.util.ArrayList; import java.util.List; import android.annotation.SuppressLint; import android.content.Context; import android.widget.RemoteViews; import android.widget.RemoteViewsService.RemoteViewsFactory; @SuppressLint("NewApi") public class WidgetDataProvider implements RemoteViewsFactory { ListmCollections = new ArrayList (); Context mContext = null; public WidgetDataProvider(Context context, Intent intent) { mContext = context; } @Override public int getCount() { return mCollections.size(); } @Override public long getItemId(int position) { return position; } @Override public RemoteViews getLoadingView() { return null; } @Override public RemoteViews getViewAt(int position) { RemoteViews mView = new RemoteViews(mContext.getPackageName(), android.R.layout.simple_list_item_1); mView.setTextViewText(android.R.id.text1, mCollections.get(position));
mView.setTextColor(android.R.id.text1, Color.BLACK); return mView; } @Override public int getViewTypeCount() { return 1; } @Override public boolean hasStableIds() { return true; } @Override public void onCreate() { initData(); } @Override public void onDataSetChanged() { initData(); } private void initData() { mCollections.clear(); for (int i = 1; i <= 10; i++) { mCollections.add("ListView item " + i); } } @Override public void onDestroy() { } }
Creating RemoteViewService :
package com.dharmangsoni.widgets; import android.annotation.SuppressLint; import android.content.Intent; import android.widget.RemoteViewsService; @SuppressLint("NewApi") public class WidgetService extends RemoteViewsService { @Override public RemoteViewsFactory onGetViewFactory(Intent intent) { WidgetDataProvider dataProvider = new WidgetDataProvider( getApplicationContext(), intent); return dataProvider; } }Adding service entry into Manifest file under <application> tag:
<!-- Widget service --> <service android:name="com.dharmangsoni.widgets.WidgetService" android:permission="android.permission.BIND_REMOTEVIEWS" />
Updating WidgetProvider to initialize collection view.
package com.dharmangsoni.widgets; import android.annotation.SuppressLint; 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 com.dharmangsoni.collectionwidget.R; public class WidgetProvider extends AppWidgetProvider { @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { for (int widgetId : appWidgetIds) { RemoteViews mView = initViews(context, appWidgetManager, widgetId); appWidgetManager.updateAppWidget(widgetId, mView); } super.onUpdate(context, appWidgetManager, appWidgetIds); } @SuppressWarnings("deprecation") @SuppressLint("NewApi") private RemoteViews initViews(Context context, AppWidgetManager widgetManager, int widgetId) { RemoteViews mView = new RemoteViews(context.getPackageName(), R.layout.widget_provider_layout); Intent intent = new Intent(context, WidgetService.class); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); mView.setRemoteAdapter(widgetId, R.id.widgetCollectionList, intent); return mView; } }Now run your app will give you following output:
To do we have to add setOnClickFillInIntent in getViewAt in WedgetDataProvider.
. . . @Override public RemoteViews getViewAt(int position) { RemoteViews mView = new RemoteViews(mContext.getPackageName(), android.R.layout.simple_list_item_1); mView.setTextViewText(android.R.id.text1, mCollections.get(position)); mView.setTextColor(android.R.id.text1, Color.BLACK); final Intent fillInIntent = new Intent(); fillInIntent.setAction(WidgetProvider.ACTION_TOAST); final Bundle bundle = new Bundle(); bundle.putString(WidgetProvider.EXTRA_STRING, mCollections.get(position)); fillInIntent.putExtras(bundle); mView.setOnClickFillInIntent(android.R.id.text1, fillInIntent); return mView; } . . .
Now handling click event in WidgetProvider->onReceive:
. . . . public class WidgetProvider extends AppWidgetProvider { public static final String ACTION_TOAST = "com.dharmangsoni.widgets.ACTION_TOAST"; public static final String EXTRA_STRING = "com.dharmangsoni.widgets.EXTRA_STRING"; @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(ACTION_TOAST)) { String item = intent.getExtras().getString(EXTRA_STRING); Toast.makeText(context, item, Toast.LENGTH_LONG).show(); } super.onReceive(context, intent); } @SuppressLint("NewApi") @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { for (int widgetId : appWidgetIds) { RemoteViews mView = initViews(context, appWidgetManager, widgetId); // Adding collection list item handler final Intent onItemClick = new Intent(context, WidgetProvider.class); onItemClick.setAction(ACTION_TOAST); onItemClick.setData(Uri.parse(onItemClick .toUri(Intent.URI_INTENT_SCHEME))); final PendingIntent onClickPendingIntent = PendingIntent .getBroadcast(context, 0, onItemClick, PendingIntent.FLAG_UPDATE_CURRENT); mView.setPendingIntentTemplate(R.id.widgetCollectionList, onClickPendingIntent); appWidgetManager.updateAppWidget(widgetId, mView); } super.onUpdate(context, appWidgetManager, appWidgetIds); } . . .
Download Full source :
https://www.dropbox.com/s/u019v6arbae37oh/CollectionWidget.tar.gz
Hope you like it.