Skip to content
This repository was archived by the owner on Nov 18, 2024. It is now read-only.

Commit f6ca501

Browse files
committed
Added widget + Bug fixes
1 parent 9a8c5e2 commit f6ca501

16 files changed

Lines changed: 340 additions & 12 deletions

File tree

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ android {
77
applicationId "apps.jizzu.simpletodo"
88
minSdkVersion 19
99
targetSdkVersion 26
10-
versionCode 1
11-
versionName "0.5"
10+
versionCode 2
11+
versionName "0.7"
1212
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
1313
}
1414
buildTypes {

app/src/main/AndroidManifest.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
android:theme="@style/AppTheme">
1313
<activity
1414
android:name=".activity.MainActivity"
15+
android:launchMode="singleTop"
1516
android:screenOrientation="portrait">
1617
<intent-filter>
1718
<action android:name="android.intent.action.MAIN" />
@@ -43,6 +44,18 @@
4344
android:name=".settings.LicensesActivity"
4445
android:screenOrientation="portrait"
4546
android:theme="@style/PreferenceScreen" />
47+
48+
<service
49+
android:name=".widget.WidgetService"
50+
android:permission="android.permission.BIND_REMOTEVIEWS"></service>
51+
<receiver android:name=".widget.WidgetProvider">
52+
<intent-filter>
53+
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
54+
</intent-filter>
55+
<meta-data
56+
android:name="android.appwidget.provider"
57+
android:resource="@xml/widget_metadata"></meta-data>
58+
</receiver>
4659
</application>
4760

4861
</manifest>

app/src/main/java/apps/jizzu/simpletodo/activity/MainActivity.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package apps.jizzu.simpletodo.activity;
22

3+
import android.appwidget.AppWidgetManager;
4+
import android.content.ComponentName;
35
import android.content.Context;
46
import android.content.Intent;
57
import android.os.Bundle;
@@ -34,6 +36,7 @@
3436
import apps.jizzu.simpletodo.utils.Interpolator;
3537
import apps.jizzu.simpletodo.utils.MyApplication;
3638
import apps.jizzu.simpletodo.utils.PreferenceHelper;
39+
import apps.jizzu.simpletodo.widget.WidgetProvider;
3740
import top.wefor.circularanim.CircularAnim;
3841

3942
import static android.content.ContentValues.TAG;
@@ -150,6 +153,19 @@ public void addTasksFromDB() {
150153
}
151154
}
152155

156+
/**
157+
* Updates widget data.
158+
*/
159+
public void updateWidget() {
160+
Log.d(TAG, "WIDGET IS UPDATED!");
161+
Intent intent = new Intent(this, WidgetProvider.class);
162+
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
163+
int[] ids = AppWidgetManager.getInstance(MainActivity.this)
164+
.getAppWidgetIds(new ComponentName(MainActivity.this, WidgetProvider.class));
165+
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
166+
sendBroadcast(intent);
167+
}
168+
153169
@Override
154170
public boolean onCreateOptionsMenu(Menu menu) {
155171
getMenuInflater().inflate(R.menu.menu, menu);
@@ -190,6 +206,7 @@ protected void onStop() {
190206
mHelper.saveTask(task);
191207
}
192208
}
209+
updateWidget();
193210
}
194211

195212
@Override

app/src/main/java/apps/jizzu/simpletodo/adapter/RecyclerViewAdapter.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,12 @@
3636
*/
3737
public class RecyclerViewAdapter extends RecyclerViewEmptySupport.Adapter<RecyclerView.ViewHolder> {
3838

39-
public List<ModelTask> mItems = new ArrayList<>();
39+
public static List<ModelTask> mItems = new ArrayList<>();
4040
private DBHelper mHelper = DBHelper.getInstance(MainActivity.mContext);
4141
private AlarmHelper mAlarmHelper = AlarmHelper.getInstance();
4242
private Context mContext;
4343
private static RecyclerViewAdapter mInstance;
44+
private boolean mCancelButtonIsClicked;
4445

4546
/**
4647
* Constructor is private to prevent direct instantiation.
@@ -110,6 +111,7 @@ public void removeItem(int position, RecyclerView recyclerView) {
110111
final long taskID = mItems.get(position).getId();
111112
final boolean[] isRemoved = {true};
112113
final long timeStamp = mItems.get(position).getTimeStamp();
114+
mCancelButtonIsClicked = false;
113115

114116
mItems.remove(position);
115117
notifyItemRemoved(position);
@@ -118,10 +120,13 @@ public void removeItem(int position, RecyclerView recyclerView) {
118120
snackbar.setAction(R.string.snackbar_cancel_removing, new CustomOnClickListener(taskID) {
119121

120122
public void onClick(View view) {
121-
ModelTask task = mHelper.getTask(taskID);
122-
addItem(task, task.getPosition());
123+
if (!mCancelButtonIsClicked) {
124+
mCancelButtonIsClicked = true;
125+
ModelTask task = mHelper.getTask(taskID);
126+
addItem(task, task.getPosition());
123127

124-
isRemoved[0] = false;
128+
isRemoved[0] = false;
129+
}
125130
}
126131
});
127132

app/src/main/java/apps/jizzu/simpletodo/alarm/AlarmReceiver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public void onReceive(Context context, Intent intent) {
2828
String title = intent.getStringExtra("title");
2929
int timeStamp = (int) intent.getLongExtra("time_stamp", 0);
3030

31-
// Intent to launch the application when you click on a notification
31+
// Intent to launch the application when you click on notification
3232
Intent resultIntent = new Intent(context, MainActivity.class);
3333

3434
if (MyApplication.isActivityVisible()) {
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package apps.jizzu.simpletodo.widget;
2+
3+
import android.content.Context;
4+
import android.support.v4.content.ContextCompat;
5+
import android.text.format.DateUtils;
6+
import android.util.Log;
7+
import android.view.Display;
8+
import android.view.View;
9+
import android.view.WindowManager;
10+
import android.widget.RemoteViews;
11+
import android.widget.RemoteViewsService;
12+
13+
import java.util.ArrayList;
14+
import java.util.Calendar;
15+
16+
import apps.jizzu.simpletodo.R;
17+
import apps.jizzu.simpletodo.adapter.RecyclerViewAdapter;
18+
import apps.jizzu.simpletodo.model.ModelTask;
19+
import apps.jizzu.simpletodo.utils.Utils;
20+
21+
import static android.content.ContentValues.TAG;
22+
23+
/**
24+
* Class that will fill the list with values.
25+
* It's methods are very similar to the standard adapter methods.
26+
*/
27+
public class ViewFactory implements RemoteViewsService.RemoteViewsFactory {
28+
29+
private ArrayList<ModelTask> mListData;
30+
private Context mContext;
31+
32+
ViewFactory(Context context) {
33+
mContext = context;
34+
}
35+
36+
/**
37+
* Called when factory is first constructed.
38+
*/
39+
@Override
40+
public void onCreate() {
41+
mListData = new ArrayList<>();
42+
}
43+
44+
/**
45+
* Called when notifyDataSetChanged() is triggered on the remote adapter.
46+
*/
47+
@Override
48+
public void onDataSetChanged() {
49+
mListData.clear();
50+
mListData.addAll(RecyclerViewAdapter.mItems);
51+
}
52+
53+
/**
54+
* Called when the last RemoteViewsAdapter that is associated with this factory is unbound.
55+
*/
56+
@Override
57+
public void onDestroy() {
58+
59+
}
60+
61+
@Override
62+
public int getCount() {
63+
return mListData.size();
64+
}
65+
66+
/**
67+
* Get a View that displays the data at the specified position in the data set.
68+
*/
69+
@Override
70+
public RemoteViews getViewAt(int position) {
71+
RemoteViews remoteViews = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
72+
remoteViews.setTextViewText(R.id.item_title, mListData.get(position).getTitle());
73+
74+
if (mListData.get(position).getDate() != 0) {
75+
remoteViews.setViewPadding(R.id.item_title, 0, 0, 0, 0);
76+
remoteViews.setViewVisibility(R.id.item_date, View.VISIBLE);
77+
78+
if (DateUtils.isToday(mListData.get(position).getDate())) {
79+
remoteViews.setTextViewText(R.id.item_date, mContext.getString(R.string.reminder_today) + " " + Utils.getTime(mListData.get(position).getDate()));
80+
} else if (DateUtils.isToday(mListData.get(position).getDate() + DateUtils.DAY_IN_MILLIS)) {
81+
remoteViews.setTextColor(R.id.item_date, ContextCompat.getColor(mContext, R.color.red));
82+
remoteViews.setTextViewText(R.id.item_date, mContext.getString(R.string.reminder_yesterday) + " " + Utils.getTime(mListData.get(position).getDate()));
83+
} else if (DateUtils.isToday(mListData.get(position).getDate() - DateUtils.DAY_IN_MILLIS)) {
84+
remoteViews.setTextViewText(R.id.item_date, mContext.getString(R.string.reminder_tomorrow) + " " + Utils.getTime(mListData.get(position).getDate()));
85+
} else if (mListData.get(position).getDate() < Calendar.getInstance().getTimeInMillis()) {
86+
remoteViews.setTextColor(R.id.item_date, ContextCompat.getColor(mContext, R.color.red));
87+
remoteViews.setTextViewText(R.id.item_date, Utils.getFullDate(mListData.get(position).getDate()));
88+
} else {
89+
remoteViews.setTextViewText(R.id.item_date, Utils.getFullDate(mListData.get(position).getDate()));
90+
}
91+
} else {
92+
Display d = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
93+
int width = d.getWidth();
94+
int height = d.getHeight();
95+
Log.d(TAG, "width = " + width + ", height = " + height);
96+
97+
remoteViews.setViewVisibility(R.id.item_date, View.GONE);
98+
if (width >= 1080 || height >= 1776) {
99+
remoteViews.setViewPadding(R.id.item_title, 0, 27, 0, 27);
100+
} else if (width >= 720 || height >= 1184) {
101+
remoteViews.setViewPadding(R.id.item_title, 0, 20, 0, 20);
102+
} else if (width >= 480 || height >= 800) {
103+
remoteViews.setViewPadding(R.id.item_title, 0, 15, 0, 15);
104+
}
105+
}
106+
return remoteViews;
107+
}
108+
109+
/**
110+
* This allows for the use of a custom loading view which appears between the time that getViewAt(int) is called and returns.
111+
*/
112+
@Override
113+
public RemoteViews getLoadingView() {
114+
return null;
115+
}
116+
117+
/**
118+
* Returns the number of types of Views that will be created by getView().
119+
* This adapter always returns the same type of View for all items.
120+
*/
121+
@Override
122+
public int getViewTypeCount() {
123+
return 1;
124+
}
125+
126+
@Override
127+
public long getItemId(int position) {
128+
return position;
129+
}
130+
131+
/**
132+
* Indicates whether the item ids are stable across changes to the underlying data..
133+
* Returns true if the same id always refers to the same object.
134+
*/
135+
@Override
136+
public boolean hasStableIds() {
137+
return true;
138+
}
139+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package apps.jizzu.simpletodo.widget;
2+
3+
import android.app.PendingIntent;
4+
import android.appwidget.AppWidgetManager;
5+
import android.appwidget.AppWidgetProvider;
6+
import android.content.Context;
7+
import android.content.Intent;
8+
import android.net.Uri;
9+
import android.widget.RemoteViews;
10+
11+
import apps.jizzu.simpletodo.R;
12+
import apps.jizzu.simpletodo.activity.MainActivity;
13+
14+
/**
15+
* Class for implementing lifecycle methods of widget.
16+
*/
17+
public class WidgetProvider extends AppWidgetProvider {
18+
19+
/**
20+
* Called in response to the ACTION_APPWIDGET_UPDATE and ACTION_APPWIDGET_RESTORED broadcasts
21+
* when this AppWidget provider is being asked to provide RemoteViews for a set of AppWidgets.
22+
*/
23+
@Override
24+
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
25+
26+
PendingIntent clickPI = PendingIntent.getActivity(context, 0,
27+
new Intent(context, MainActivity.class)
28+
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP),
29+
PendingIntent.FLAG_UPDATE_CURRENT);
30+
31+
for (int appWidgetId : appWidgetIds) {
32+
33+
// Intent that contains the data for calling the WidgetService class
34+
// When the system wants to update the data in the list, it takes out this intent, binds to the specified service
35+
// and takes the adapter. This adapter is used for filling and forming list items.
36+
Intent adapter = new Intent(context, WidgetService.class);
37+
adapter.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
38+
// In this case, we will have extra data in the data and Intents will be different.
39+
adapter.setData(Uri.parse(adapter.toUri(Intent.URI_INTENT_SCHEME)));
40+
41+
RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.widget_list);
42+
widget.setRemoteAdapter(R.id.widget_list, adapter);
43+
widget.setOnClickPendingIntent(R.id.toolbar_textView, clickPI);
44+
45+
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_list);
46+
appWidgetManager.updateAppWidget(appWidgetId, widget);
47+
}
48+
super.onUpdate(context, appWidgetManager, appWidgetIds);
49+
}
50+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package apps.jizzu.simpletodo.widget;
2+
3+
4+
import android.content.Intent;
5+
import android.widget.RemoteViewsService;
6+
7+
/**
8+
* The service to be connected to for a remote adapter to request RemoteViews.
9+
*/
10+
public class WidgetService extends RemoteViewsService {
11+
12+
/**
13+
* Method to be implemented by the derived service to generate appropriate factories for the data.
14+
*/
15+
@Override
16+
public RemoteViewsFactory onGetViewFactory(Intent intent) {
17+
return new ViewFactory(getApplicationContext());
18+
}
19+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
3+
<stroke
4+
android:width="1dp"
5+
android:color="@color/white" />
6+
7+
<solid android:color="#ffffff" />
8+
9+
<padding
10+
android:left="1dp"
11+
android:right="1dp"
12+
android:top="1dp" />
13+
14+
<corners android:radius="4dp" />
15+
</shape>
75.1 KB
Loading

0 commit comments

Comments
 (0)