Implement multiple widget providers

pull/30/head
Alinson S. Xavier 10 years ago
parent b8cacaffa9
commit ae7869d3a2

@ -64,18 +64,53 @@
android:label=""
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
<receiver android:name=".HabitWidgetProvider">
<receiver
android:name=".widgets.CheckmarkWidgetProvider"
android:label="Checkmark">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_checkmark_info"/>
</receiver>
<receiver
android:name=".widgets.HistoryWidgetProvider"
android:label="History">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_history_info"/>
</receiver>
<receiver
android:name=".widgets.ScoreWidgetProvider"
android:label="Score">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_score_info"/>
</receiver>
<receiver
android:name=".widgets.StreakWidgetProvider"
android:label="Streaks">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/small_widget_info"/>
android:resource="@xml/widget_streak_info"/>
</receiver>
<activity
android:name=".HabitWidgetConfigure"
android:theme="@style/Theme.AppCompat.Dialog">
android:name=".widgets.HabitPickerDialog"
android:theme="@style/Theme.AppCompat.Light.Dialog">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>

@ -36,6 +36,11 @@ import org.isoron.helpers.ReplayableActivity;
import org.isoron.uhabits.fragments.ListHabitsFragment;
import org.isoron.uhabits.helpers.ReminderHelper;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.widgets.BaseWidgetProvider;
import org.isoron.uhabits.widgets.CheckmarkWidgetProvider;
import org.isoron.uhabits.widgets.HistoryWidgetProvider;
import org.isoron.uhabits.widgets.ScoreWidgetProvider;
import org.isoron.uhabits.widgets.StreakWidgetProvider;
public class MainActivity extends ReplayableActivity
implements ListHabitsFragment.OnHabitClickListener
@ -70,6 +75,7 @@ public class MainActivity extends ReplayableActivity
ReminderHelper.createReminderAlarms(MainActivity.this);
DialogHelper.incrementLaunchCount(this);
showTutorial();
updateWidgets(this);
}
private void showTutorial()
@ -127,12 +133,18 @@ public class MainActivity extends ReplayableActivity
public static void updateWidgets(Context context)
{
ComponentName provider = new ComponentName(context, HabitWidgetProvider.class);
updateWidgets(context, CheckmarkWidgetProvider.class);
updateWidgets(context, HistoryWidgetProvider.class);
updateWidgets(context, ScoreWidgetProvider.class);
updateWidgets(context, StreakWidgetProvider.class);
}
Intent intent = new Intent(context, HabitWidgetProvider.class);
private static void updateWidgets(Context context, Class providerClass)
{
ComponentName provider = new ComponentName(context, providerClass);
Intent intent = new Intent(context, providerClass);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
int ids[] = AppWidgetManager.getInstance(context).getAppWidgetIds(provider);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
context.sendBroadcast(intent);
}

@ -660,7 +660,7 @@ public class ListHabitsFragment extends Fragment
LinearLayout.LayoutParams params =
new LinearLayout.LayoutParams(tvNameWidth, LayoutParams.WRAP_CONTENT, 1);
view.findViewById(R.id.tvName).setLayoutParams(params);
view.findViewById(R.id.label).setLayoutParams(params);
inflateCheckmarkButtons(view);
@ -668,7 +668,7 @@ public class ListHabitsFragment extends Fragment
}
TextView tvStar = ((TextView) view.findViewById(R.id.tvStar));
TextView tvName = (TextView) view.findViewById(R.id.tvName);
TextView tvName = (TextView) view.findViewById(R.id.label);
LinearLayout llInner = (LinearLayout) view.findViewById(R.id.llInner);
LinearLayout llButtons = (LinearLayout) view.findViewById(R.id.llButtons);

@ -1,5 +1,4 @@
/*
* Copyright (C) 2016 Alinson Santos Xavier
/* Copyright (C) 2016 Alinson Santos Xavier
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@ -13,8 +12,6 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.isoron.uhabits.views;
@ -25,6 +22,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.Build;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
@ -35,7 +33,7 @@ import org.isoron.helpers.ColorHelper;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
public class SmallWidgetView extends View
public class CheckmarkView extends View
{
private Paint pCard;
private Paint pIcon;
@ -65,13 +63,13 @@ public class SmallWidgetView extends View
private TextPaint textPaint;
private StaticLayout labelLayout;
public SmallWidgetView(Context context)
public CheckmarkView(Context context)
{
super(context);
init(context);
}
public SmallWidgetView(Context context, AttributeSet attrs)
public CheckmarkView(Context context, AttributeSet attrs)
{
super(context, attrs);
init(context);
@ -135,9 +133,16 @@ public class SmallWidgetView extends View
int color = (check_status == 2 ? primaryColor : darkGrey);
pCard.setColor(color);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
canvas.drawRoundRect(leftMargin, topMargin, width - leftMargin, height - topMargin, padding,
padding, pCard);
}
else
{
canvas.drawRect(leftMargin, topMargin, width - leftMargin, height - topMargin, pCard);
}
}
private void drawCheckmark(Canvas canvas)
{
@ -176,8 +181,6 @@ public class SmallWidgetView extends View
{
super.onMeasure(width, height);
setMeasuredDimension(width, height);
updateSize(width, height);
updateLabel();
}
@Override

@ -120,9 +120,12 @@ public class HabitScoreView extends ScrollableDataView
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if(height > 0)
{
int b = height / 9;
height = b * 9;
width = (width / b) * b;
}
setMeasuredDimension(width, height);
}

@ -14,100 +14,107 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits;
package org.isoron.uhabits.widgets;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import org.isoron.helpers.DialogHelper;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.HabitScoreView;
public class HabitWidgetProvider extends AppWidgetProvider
public abstract class BaseWidgetProvider extends AppWidgetProvider
{
protected abstract int getDefaultHeight();
protected abstract int getDefaultWidth();
protected abstract PendingIntent getOnClickPendingIntent(Context context, Habit habit);
protected abstract int getLayoutId();
protected abstract View buildCustomView(Context context, int max_height, int max_width,
Habit habit);
public static String getHabitIdKey(long widgetId)
{
return String.format("widget-%06d-habit", widgetId);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds)
{
Context appContext = context.getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext);
for(Integer id : appWidgetIds)
prefs.edit().remove(getHabitIdKey(id));
}
@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
int appWidgetId, Bundle newOptions)
{
updateWidget(context, appWidgetManager, appWidgetId, newOptions);
}
@Override
public void onUpdate(Context context, AppWidgetManager manager, int[] appWidgetIds)
{
for(int id : appWidgetIds)
{
Bundle options = manager.getAppWidgetOptions(id);
Bundle options = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
options = manager.getAppWidgetOptions(id);
updateWidget(context, manager, id, options);
}
}
private void updateWidget(Context context, AppWidgetManager manager, int widgetId, Bundle options)
{
int max_height = (int) DialogHelper.dpToPixels(context, options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT));
int min_height = (int) DialogHelper.dpToPixels(context, options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT));
int max_width = (int) DialogHelper.dpToPixels(context, options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH));
int min_width = (int) DialogHelper.dpToPixels(context, options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH));
int maxWidth = getDefaultWidth();
int maxHeight = getDefaultHeight();
Log.d("HabitWidgetProvider", String.format("max_h=%d min_h=%d max_w=%d min_w=%d",
max_height, min_height, max_width, min_width));
if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
maxWidth = (int) DialogHelper.dpToPixels(context,
options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH));
maxHeight = (int) DialogHelper.dpToPixels(context,
options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT));
}
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_graph);
Context appContext = context.getApplicationContext();
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), getLayoutId());
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext);
Long habitId = prefs.getLong(getWidgetPrefKey(widgetId), -1L);
Long habitId = prefs.getLong(getHabitIdKey(widgetId), -1L);
if(habitId < 0) return;
Habit habit = Habit.get(habitId);
// SmallWidgetView widgetView = new SmallWidgetView(context);
// HabitHistoryView widgetView = new HabitHistoryView(context, null);
HabitScoreView widgetView = new HabitScoreView(context, null);
// HabitStreakView widgetView = new HabitStreakView(context, null);
widgetView.setIsBackgroundTransparent(true);
widgetView.setHabit(habit);
View widgetView = buildCustomView(context, maxHeight, maxWidth, habit);
widgetView.setDrawingCacheEnabled(true);
widgetView.measure(max_width, max_height);
widgetView.layout(0, 0, max_width, max_height);
int width = widgetView.getMeasuredWidth();
int height = widgetView.getMeasuredHeight();
Log.d("SmallWidgetProvider", String.format("width=%d height=%d\n", width, height));
height -= DialogHelper.dpToPixels(context, 12f);
widgetView.measure(width, height);
widgetView.layout(0, 0, width, height);
widgetView.buildDrawingCache(true);
Bitmap drawingCache = widgetView.getDrawingCache();
remoteViews.setTextViewText(R.id.tvName, habit.name);
remoteViews.setTextViewText(R.id.label, habit.name);
remoteViews.setImageViewBitmap(R.id.imageView, drawingCache);
remoteViews.setOnClickPendingIntent(R.id.imageView,
HabitBroadcastReceiver.buildCheckIntent(context, habit, null));
manager.updateAppWidget(widgetId, remoteViews);
}
public static String getWidgetPrefKey(long widgetId)
{
return String.format("widget-%03d", widgetId);
}
PendingIntent onClickIntent = getOnClickPendingIntent(context, habit);
if(onClickIntent != null) remoteViews.setOnClickPendingIntent(R.id.imageView, onClickIntent);
@Override
public void onDeleted(Context context, int[] appWidgetIds)
{
Context appContext = context.getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext);
for(Integer id : appWidgetIds)
prefs.edit().remove(getWidgetPrefKey(id));
}
@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
int appWidgetId, Bundle newOptions)
{
updateWidget(context, appWidgetManager, appWidgetId, newOptions);
manager.updateAppWidget(widgetId, remoteViews);
}
}

@ -0,0 +1,69 @@
/* Copyright (C) 2016 Alinson Santos Xavier
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.widgets;
import android.app.PendingIntent;
import android.content.Context;
import android.view.View;
import org.isoron.uhabits.HabitBroadcastReceiver;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.CheckmarkView;
public class CheckmarkWidgetProvider extends BaseWidgetProvider
{
@Override
protected View buildCustomView(Context context, int maxHeight, int maxWidth, Habit habit)
{
CheckmarkView widgetView = new CheckmarkView(context);
widgetView.setHabit(habit);
widgetView.measure(maxWidth, maxHeight);
widgetView.layout(0, 0, maxWidth, maxHeight);
int width = widgetView.getMeasuredWidth();
int height = widgetView.getMeasuredHeight();
widgetView.measure(width, height);
widgetView.layout(0, 0, width, height);
return widgetView;
}
@Override
protected PendingIntent getOnClickPendingIntent(Context context, Habit habit)
{
return HabitBroadcastReceiver.buildCheckIntent(context, habit, null);
}
@Override
protected int getDefaultHeight()
{
return 200;
}
@Override
protected int getDefaultWidth()
{
return 160;
}
@Override
protected int getLayoutId()
{
return R.layout.widget_checkmark;
}
}

@ -14,7 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits;
package org.isoron.uhabits.widgets;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
@ -27,20 +27,19 @@ import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import org.isoron.uhabits.MainActivity;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.widgets.BaseWidgetProvider;
import java.util.ArrayList;
import java.util.List;
public class HabitWidgetConfigure extends Activity implements AdapterView.OnItemClickListener
public class HabitPickerDialog extends Activity implements AdapterView.OnItemClickListener
{
private Integer widgetId;
private ListView listView;
private ArrayList<Long> habitIds;
private ArrayList<String> habitNames;
private ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState)
@ -54,10 +53,10 @@ public class HabitWidgetConfigure extends Activity implements AdapterView.OnItem
if (extras != null) widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
listView = (ListView) findViewById(R.id.listView);
ListView listView = (ListView) findViewById(R.id.listView);
habitIds = new ArrayList<>();
habitNames = new ArrayList<>();
ArrayList<String> habitNames = new ArrayList<>();
List<Habit> habits = Habit.getAll(false);
for(Habit h : habits)
@ -66,7 +65,8 @@ public class HabitWidgetConfigure extends Activity implements AdapterView.OnItem
habitNames.add(h.name);
}
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, habitNames);
ArrayAdapter<String> adapter =
new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, habitNames);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
@ -77,7 +77,7 @@ public class HabitWidgetConfigure extends Activity implements AdapterView.OnItem
Long habitId = habitIds.get(position);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(
getApplicationContext());
prefs.edit().putLong(HabitWidgetProvider.getWidgetPrefKey(widgetId), habitId).commit();
prefs.edit().putLong(BaseWidgetProvider.getHabitIdKey(widgetId), habitId).commit();
MainActivity.updateWidgets(this);

@ -0,0 +1,69 @@
/* Copyright (C) 2016 Alinson Santos Xavier
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.widgets;
import android.app.PendingIntent;
import android.content.Context;
import android.view.View;
import org.isoron.helpers.DialogHelper;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.HabitHistoryView;
public class HistoryWidgetProvider extends BaseWidgetProvider
{
@Override
protected View buildCustomView(Context context, int maxHeight, int maxWidth, Habit habit)
{
HabitHistoryView view = new HabitHistoryView(context, null);
view.setHabit(habit);
view.measure(maxWidth, maxHeight);
view.layout(0, 0, maxWidth, maxHeight);
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
height -= DialogHelper.dpToPixels(context, 12);
view.measure(width, height);
view.layout(0, 0, width, height);
return view;
}
@Override
protected PendingIntent getOnClickPendingIntent(Context context, Habit habit)
{
return null;
}
@Override
protected int getDefaultHeight()
{
return 200;
}
@Override
protected int getDefaultWidth()
{
return 200;
}
@Override
protected int getLayoutId()
{
return R.layout.widget_graph;
}
}

@ -0,0 +1,70 @@
/* Copyright (C) 2016 Alinson Santos Xavier
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.widgets;
import android.app.PendingIntent;
import android.content.Context;
import android.view.View;
import org.isoron.helpers.DialogHelper;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.HabitScoreView;
public class ScoreWidgetProvider extends BaseWidgetProvider
{
@Override
protected View buildCustomView(Context context, int maxHeight, int maxWidth, Habit habit)
{
HabitScoreView view = new HabitScoreView(context, null);
view.setIsBackgroundTransparent(true);
view.setHabit(habit);
view.measure(maxWidth, maxHeight);
view.layout(0, 0, maxWidth, maxHeight);
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
height -= DialogHelper.dpToPixels(context, 12);
view.measure(width, height);
view.layout(0, 0, width, height);
return view;
}
@Override
protected PendingIntent getOnClickPendingIntent(Context context, Habit habit)
{
return null;
}
@Override
protected int getDefaultHeight()
{
return 200;
}
@Override
protected int getDefaultWidth()
{
return 200;
}
@Override
protected int getLayoutId()
{
return R.layout.widget_graph;
}
}

@ -0,0 +1,70 @@
/* Copyright (C) 2016 Alinson Santos Xavier
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isoron.uhabits.widgets;
import android.app.PendingIntent;
import android.content.Context;
import android.view.View;
import org.isoron.helpers.DialogHelper;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.views.HabitScoreView;
import org.isoron.uhabits.views.HabitStreakView;
public class StreakWidgetProvider extends BaseWidgetProvider
{
@Override
protected View buildCustomView(Context context, int maxHeight, int maxWidth, Habit habit)
{
HabitStreakView view = new HabitStreakView(context, null);
view.setHabit(habit);
view.measure(maxWidth, maxHeight);
view.layout(0, 0, maxWidth, maxHeight);
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
height -= DialogHelper.dpToPixels(context, 12);
view.measure(width, height);
view.layout(0, 0, width, height);
return view;
}
@Override
protected PendingIntent getOnClickPendingIntent(Context context, Habit habit)
{
return null;
}
@Override
protected int getDefaultHeight()
{
return 200;
}
@Override
protected int getDefaultWidth()
{
return 200;
}
@Override
protected int getLayoutId()
{
return R.layout.widget_graph;
}
}

@ -12,7 +12,7 @@
style="@style/habitsListStarStyle" />
<TextView
android:id="@+id/tvName"
android:id="@+id/label"
style="@style/habitsListNameStyle" />
<LinearLayout

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="4dp">
<org.isoron.uhabits.views.CheckmarkView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
/>
</LinearLayout>

@ -11,7 +11,7 @@
android:paddingRight="0dp">
<TextView
android:id="@+id/tvName"
android:id="@+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"

@ -2,11 +2,11 @@
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="40dp"
android:minWidth="40dp"
android:initialLayout="@layout/widget_small"
android:initialLayout="@layout/widget_checkmark"
android:previewImage="@mipmap/ic_small_widget_preview"
android:resizeMode="horizontal|vertical"
android:resizeMode="none"
android:updatePeriodMillis="3600000"
android:configure="org.isoron.uhabits.HabitWidgetConfigure"
android:configure="org.isoron.uhabits.widgets.HabitPickerDialog"
android:widgetCategory="home_screen">

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="80dp"
android:minWidth="80dp"
android:minResizeWidth="40dp"
android:minResizeHeight="40dp"
android:initialLayout="@layout/widget_graph"
android:previewImage="@mipmap/ic_small_widget_preview"
android:resizeMode="vertical|horizontal"
android:updatePeriodMillis="3600000"
android:configure="org.isoron.uhabits.widgets.HabitPickerDialog"
android:widgetCategory="home_screen">
</appwidget-provider>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="80dp"
android:minWidth="80dp"
android:minResizeWidth="40dp"
android:minResizeHeight="40dp"
android:initialLayout="@layout/widget_graph"
android:previewImage="@mipmap/ic_small_widget_preview"
android:resizeMode="vertical|horizontal"
android:updatePeriodMillis="3600000"
android:configure="org.isoron.uhabits.widgets.HabitPickerDialog"
android:widgetCategory="home_screen">
</appwidget-provider>

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="80dp"
android:minWidth="80dp"
android:minResizeWidth="40dp"
android:minResizeHeight="40dp"
android:initialLayout="@layout/widget_graph"
android:previewImage="@mipmap/ic_small_widget_preview"
android:resizeMode="vertical|horizontal"
android:updatePeriodMillis="3600000"
android:configure="org.isoron.uhabits.widgets.HabitPickerDialog"
android:widgetCategory="home_screen">
</appwidget-provider>
Loading…
Cancel
Save