Configuration activity for Note List Widget

This commit is contained in:
Daniel Bailey 2018-03-19 20:55:24 +00:00 committed by Niedermann IT-Dienstleistungen
parent e851d05f9d
commit d2f4591d4f
10 changed files with 301 additions and 89 deletions

View file

@ -52,9 +52,9 @@ public class NotesListViewActivity extends AppCompatActivity implements ItemAdap
public final static String CREATED_NOTE = "it.niedermann.owncloud.notes.created_notes";
public final static String CREDENTIALS_CHANGED = "it.niedermann.owncloud.notes.CREDENTIALS_CHANGED";
public static final String ADAPTER_KEY_RECENT = "recent";
public static final String ADAPTER_KEY_STARRED = "starred";
private static final String ADAPTER_KEY_RECENT = "recent";
private static final String ADAPTER_KEY_STARRED = "starred";
private static final String SAVED_STATE_NAVIGATION_SELECTION = "navigationSelection";
private static final String SAVED_STATE_NAVIGATION_ADAPTER_SLECTION = "navigationAdapterSelection";
private static final String SAVED_STATE_NAVIGATION_OPEN = "navigationOpen";

View file

@ -6,75 +6,101 @@ import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.widget.RemoteViews;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.android.activity.EditNoteActivity;
import it.niedermann.owncloud.notes.android.activity.NotesListViewActivity;
import static android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE;
public class NoteListWidget extends AppWidgetProvider {
private static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_note_list);
// Launch application when user taps the header icon or app title
Intent intent = new Intent("android.intent.action.MAIN");
intent.setComponent(new ComponentName(context.getPackageName(),
NotesListViewActivity.class.getName()));
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_note_header_icon, pendingIntent);
views.setOnClickPendingIntent(R.id.widget_note_list_title, pendingIntent);
// Launch create note activity if user taps "+" sign in header
intent = new Intent(context, EditNoteActivity.class);
pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_note_list_create_icon, pendingIntent);
Intent templateIntent = new Intent(context, EditNoteActivity.class);
PendingIntent templatePI = PendingIntent.getActivity(
context,
0,
templateIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Intent serviceIntent = new Intent(context, NoteListWidgetService.class);
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)));
views.setPendingIntentTemplate(R.id.note_list_widget_lv, templatePI);
views.setRemoteAdapter(R.id.note_list_widget_lv, serviceIntent);
views.setEmptyView(R.id.note_list_widget_lv, R.id.widget_note_list_placeholder_tv);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
public static final String WIDGET_MODE_KEY = "NLW_mode";
public static final String WIDGET_CATEGORY_KEY = "NLW_cat";
public static final int NLW_DISPLAY_ALL = 0;
public static final int NLW_DISPLAY_STARRED = 1;
public static final int NLW_DISPLAY_CATEGORY = 2;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
int displayMode = sp.getInt(NoteListWidget.WIDGET_MODE_KEY + appWidgetId, -1);
String category = sp.getString(NoteListWidget.WIDGET_CATEGORY_KEY + appWidgetId, null);
Intent serviceIntent = new Intent(context, NoteListWidgetService.class);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_note_list);
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
serviceIntent.putExtra(NoteListWidget.WIDGET_MODE_KEY + appWidgetId, displayMode);
// Launch application when user taps the header icon or app title
Intent intent = new Intent("android.intent.action.MAIN");
intent.setComponent(new ComponentName(context.getPackageName(),
NotesListViewActivity.class.getName()));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_note_header_icon, pendingIntent);
views.setOnClickPendingIntent(R.id.widget_note_list_title_tv, pendingIntent);
// Launch create note activity if user taps "+" sign in header
intent = new Intent(context, EditNoteActivity.class);
pendingIntent = PendingIntent.getActivity(context,0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_note_list_create_icon, pendingIntent);
Intent templateIntent = new Intent(context, EditNoteActivity.class);
PendingIntent templatePI = PendingIntent.getActivity(context,
0, templateIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
if (displayMode == 2) {
serviceIntent.putExtra(NoteListWidget.WIDGET_CATEGORY_KEY + appWidgetId, category);
}
serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)));
views.setPendingIntentTemplate(R.id.note_list_widget_lv, templatePI);
views.setRemoteAdapter(appWidgetId, R.id.note_list_widget_lv, serviceIntent);
views.setEmptyView(R.id.note_list_widget_lv, R.id.widget_note_list_placeholder_tv);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
@Override
public void onReceive(Context context, Intent intent) {
AppWidgetManager awm = AppWidgetManager.getInstance(context);
int appWidgetIds[] = awm.getAppWidgetIds(new ComponentName(context, NoteListWidget.class));
for (int appWidgetId : appWidgetIds) {
if (ACTION_APPWIDGET_UPDATE.equals(intent.getAction())) {
awm.notifyAppWidgetViewDataChanged(appWidgetId, R.id.note_list_widget_lv);
}
}
super.onReceive(context, intent);
}
AppWidgetManager manager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(context, NoteListWidget.class));
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
manager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.note_list_widget_lv);
SharedPreferences.Editor editor = PreferenceManager
.getDefaultSharedPreferences(context).edit();
for (int appWidgetId : appWidgetIds) {
editor.remove(WIDGET_MODE_KEY + appWidgetId);
editor.remove(WIDGET_CATEGORY_KEY + appWidgetId);
}
editor.apply();
}
}

View file

@ -3,46 +3,162 @@ package it.niedermann.owncloud.notes.android.appwidget;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.android.activity.NotesListViewActivity;
import it.niedermann.owncloud.notes.model.NavigationAdapter;
import it.niedermann.owncloud.notes.persistence.NoteSQLiteOpenHelper;
import it.niedermann.owncloud.notes.persistence.NoteServerSyncHelper;
public class NoteListWidgetConfiguration extends AppCompatActivity {
private static final String TAG = Activity.class.getSimpleName();
private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private NavigationAdapter adapterCategories;
private NavigationAdapter.NavigationItem itemRecent, itemFavorites;
private NoteSQLiteOpenHelper db = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setResult(RESULT_CANCELED);
Intent intent = getIntent();
if (intent.getExtras() == null) {
finish();
return;
}
int mAppWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
setContentView(R.layout.activity_note_list_configuration);
if (!(NoteServerSyncHelper.isConfigured(this))) {
Toast.makeText(this, R.string.widget_not_logged_in, Toast.LENGTH_LONG).show();
// TODO Present user with app login screen
Log.w(TAG, "onCreate: user not logged in");
} else {
Intent retIntent = new Intent(this, NoteListWidget.class);
retIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
retIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
sendBroadcast(retIntent);
setResult(RESULT_OK, retIntent);
finish();
}
finish();
db = NoteSQLiteOpenHelper.getInstance(this);
final Bundle extras = getIntent().getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}
itemRecent = new NavigationAdapter.NavigationItem(NotesListViewActivity.ADAPTER_KEY_RECENT,
getString(R.string.label_all_notes),
null,
R.drawable.ic_access_time_grey600_24dp);
itemFavorites = new NavigationAdapter.NavigationItem(NotesListViewActivity.ADAPTER_KEY_STARRED,
getString(R.string.label_favorites),
null,
R.drawable.ic_star_grey600_24dp);
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
adapterCategories = new NavigationAdapter(new NavigationAdapter.ClickListener() {
@Override
public void onItemClick(NavigationAdapter.NavigationItem item) {
SharedPreferences.Editor sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit();
if (item == itemRecent) {
sp.putInt(NoteListWidget.WIDGET_MODE_KEY +
mAppWidgetId, NoteListWidget.NLW_DISPLAY_ALL);
} else if (item == itemFavorites) {
sp.putInt(NoteListWidget.WIDGET_MODE_KEY +
mAppWidgetId, NoteListWidget.NLW_DISPLAY_STARRED);
} else {
String category = "";
if (!item.label.equals(getString(R.string.action_uncategorized))) {
category = item.label;
}
sp.putInt(NoteListWidget.WIDGET_MODE_KEY +
mAppWidgetId, NoteListWidget.NLW_DISPLAY_CATEGORY);
sp.putString(NoteListWidget.WIDGET_CATEGORY_KEY +
mAppWidgetId, category);
}
sp.apply();
Intent updateIntent = new Intent(getApplicationContext(), NoteListWidget.class);
updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
updateIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
sendBroadcast(updateIntent);
setResult(RESULT_OK, updateIntent);
finish();
}
public void onIconClick(NavigationAdapter.NavigationItem item) {
onItemClick(item);
}
}, false);
recyclerView = findViewById(R.id.nlw_config_recyclerv);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapterCategories);
}
@Override
protected void onResume() {
super.onResume();
new LoadCategoryListTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private class LoadCategoryListTask extends AsyncTask<Void, Void, List<NavigationAdapter.NavigationItem>> {
@Override
protected List<NavigationAdapter.NavigationItem> doInBackground(Void... voids) {
NavigationAdapter.NavigationItem itemUncategorized;
List<NavigationAdapter.NavigationItem> categories = db.getCategories();
if (!categories.isEmpty() && categories.get(0).label.isEmpty()) {
itemUncategorized = categories.get(0);
itemUncategorized.label = getString(R.string.action_uncategorized);
itemUncategorized.icon = NavigationAdapter.ICON_NOFOLDER;
}
Map<String, Integer> favorites = db.getFavoritesCount();
int numFavorites = favorites.containsKey("1") ? favorites.get("1") : 0;
int numNonFavorites = favorites.containsKey("0") ? favorites.get("0") : 0;
itemFavorites.count = numFavorites;
itemRecent.count = numFavorites + numNonFavorites;
ArrayList<NavigationAdapter.NavigationItem> items = new ArrayList<>();
items.add(itemRecent);
items.add(itemFavorites);
for (NavigationAdapter.NavigationItem item : categories) {
int slashIndex = item.label.indexOf('/');
item.label = slashIndex < 0 ? item.label : item.label.substring(0, slashIndex);
item.id = "category:" + item.label;
items.add(item);
}
return items;
}
@Override
protected void onPostExecute(List<NavigationAdapter.NavigationItem> items) {
adapterCategories.setItems(items);
}
}
}

View file

@ -1,9 +1,12 @@
package it.niedermann.owncloud.notes.android.appwidget;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
@ -16,24 +19,58 @@ import it.niedermann.owncloud.notes.model.DBNote;
import it.niedermann.owncloud.notes.persistence.NoteSQLiteOpenHelper;
public class NoteListWidgetFactory implements RemoteViewsService.RemoteViewsFactory {
private final Context mContext;
private final Context context;
private final int displayMode;
private final int appWidgetId;
private String category;
private final SharedPreferences sp;
private NoteSQLiteOpenHelper db;
private List<DBNote> dbNotes;
NoteListWidgetFactory(Context context, Intent intent) {
mContext = context;
this.context = context;
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
sp = PreferenceManager.getDefaultSharedPreferences(this.context);
displayMode = sp.getInt(NoteListWidget.WIDGET_MODE_KEY + appWidgetId, -1);
}
@Override
public void onCreate() {
db = NoteSQLiteOpenHelper.getInstance(mContext);
db = NoteSQLiteOpenHelper.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_note_list);
AppWidgetManager awm = AppWidgetManager.getInstance(context);
switch (displayMode)
{
case 0:
views.setTextViewText(R.id.widget_note_list_title_tv, context.getString(R.string.app_name));
break;
case 1:
views.setTextViewText(R.id.widget_note_list_title_tv, "Starred");
break;
case 2:
category = sp.getString(NoteListWidget.WIDGET_CATEGORY_KEY + appWidgetId, null);
if (category.equals("")) {
views.setTextViewText(R.id.widget_note_list_title_tv, context.getString(R.string.action_uncategorized));
} else {
views.setTextViewText(R.id.widget_note_list_title_tv, category);
}
break;
}
awm.updateAppWidget(appWidgetId, views);
}
@Override
public void onDataSetChanged() {
// Stores all db notes using the default sort order (starred, modified)
// which is how they are displayed by the widget
dbNotes = db.getNotes();
if (displayMode == NoteListWidget.NLW_DISPLAY_ALL) {
dbNotes = db.getNotes();
} else if (displayMode == NoteListWidget.NLW_DISPLAY_STARRED) {
dbNotes = db.searchNotes(null,null, true);
} else if (displayMode == NoteListWidget.NLW_DISPLAY_CATEGORY) {
dbNotes = db.searchNotes(null, category, null);
}
}
@Override
@ -61,8 +98,8 @@ public class NoteListWidgetFactory implements RemoteViewsService.RemoteViewsFact
return null;
}
RemoteViews note_content = new RemoteViews(mContext.getPackageName(),
R.layout.widget_entry);
RemoteViews note_content = new RemoteViews(context.getPackageName(),
R.layout.widget_entry);
DBNote note = dbNotes.get(i);
final Intent fillInIntent = new Intent();
final Bundle extras = new Bundle();

View file

@ -39,7 +39,7 @@ public class PreferencesFragment extends PreferenceFragment {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Boolean darkTheme = (Boolean) newValue;
Notes.setTheme(darkTheme);
Notes.setAppTheme(darkTheme);
getActivity().setResult(Activity.RESULT_OK);
getActivity().finish();

View file

@ -1,8 +1,6 @@
package it.niedermann.owncloud.notes.model;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.preference.PreferenceManager;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@ -20,6 +18,7 @@ import butterknife.BindView;
import butterknife.ButterKnife;
import it.niedermann.owncloud.notes.R;
import it.niedermann.owncloud.notes.util.NoteUtil;
import it.niedermann.owncloud.notes.util.Notes;
public class NavigationAdapter extends RecyclerView.Adapter<NavigationAdapter.ViewHolder> {
@ -100,13 +99,9 @@ public class NavigationAdapter extends RecyclerView.Adapter<NavigationAdapter.Vi
icon.setVisibility(View.GONE);
}
view.setBackgroundColor(isSelected ? view.getResources().getColor(R.color.bg_highlighted) : Color.TRANSPARENT);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(view.getContext());
boolean darkTheme = sp.getBoolean(view.getContext().getString(R.string.pref_key_theme), false);
int textColor = view.getResources().getColor(isSelected ? R.color.primary_dark : R.color.fg_default);
if(darkTheme) {
// TODO dirty. Fix if statement.
if (enableHighlighting && Notes.getAppTheme(view.getContext())) {
if((item.label != view.getContext().getString(R.string.action_settings)) &&
(item.label != view.getContext().getString(R.string.simple_about))) {
textColor = view.getResources().getColor(isSelected ? R.color.fg_default :
@ -134,11 +129,17 @@ public class NavigationAdapter extends RecyclerView.Adapter<NavigationAdapter.Vi
private String selectedItem = null;
@NonNull
private ClickListener clickListener;
private boolean enableHighlighting = true;
public NavigationAdapter(@NonNull ClickListener clickListener) {
this.clickListener = clickListener;
}
public NavigationAdapter(@NonNull ClickListener clickListener, boolean enableHighlighting) {
this.clickListener = clickListener;
this.enableHighlighting = enableHighlighting;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

View file

@ -1,24 +1,30 @@
package it.niedermann.owncloud.notes.util;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatDelegate;
public class Notes extends Application {
private static final String DARK_THEME = "darkTheme";
@Override
public void onCreate() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
Notes.setTheme(prefs.getBoolean("darkTheme", false));
setAppTheme(getAppTheme(getApplicationContext()));
super.onCreate();
}
public static void setTheme(Boolean darkTheme) {
public static void setAppTheme(Boolean darkTheme) {
if (darkTheme) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
}
public static boolean getAppTheme(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean(DARK_THEME, false);
}
}

View file

@ -0,0 +1,24 @@
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.RecyclerView
android:id="@+id/nlw_config_recyclerv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
/>
<!--
<Switch
android:id="@+id/nlw_config_theme_sw"
android:layout_width="match_parent"
android:layout_height="61dp"
android:padding="@dimen/widget_note_list_outer_padding"
android:text="Dark theme"
android:layout_alignParentBottom="true"
/>
-->
</RelativeLayout>

View file

@ -8,6 +8,7 @@
<!-- Widget header -->
<RelativeLayout
android:layout_width="match_parent"
android:id="@+id/widget_note_list_hdr"
android:layout_height="@dimen/widget_note_list_header_height"
android:background="@color/primary"
android:padding="@dimen/widget_note_list_hdr_padding">
@ -27,10 +28,9 @@
android:contentDescription="@string/widget_app_launcher_contentDescription" />
<TextView
android:id="@+id/widget_note_list_title"
android:id="@+id/widget_note_list_title_tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/app_name"
android:textColor="@color/fg_contrast"
android:textStyle="bold"
android:textSize="18sp"

View file

@ -125,6 +125,8 @@
<string name="widget_not_logged_in">Please login to Notes before using this widget</string>
<string name="widget_entry_fav_contentDescription">Star icon is used to denote an item as a favourite</string>
<string name="widget_app_launcher_contentDescription">Launches app</string>
<string name="nlw_display_all">@string/label_all_notes</string>
<string name="nlw_display_starred">@string/label_favorites</string>
<string name="activity_select_single_note">Select note</string>