diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml index d6d9d06..442e57c 100644 --- a/.idea/assetWizardSettings.xml +++ b/.idea/assetWizardSettings.xml @@ -33,9 +33,10 @@ diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 83720df..9d83ed6 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..8b7f4af --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index cc51e58..dc34569 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -25,7 +25,7 @@ - + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b38076d..f3a69bc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -28,6 +28,7 @@ android:name=".Activities.RecipeDetailViewActivity" android:parentActivityName=".Activities.RecipeDetailActivity" /> + @@ -35,10 +36,30 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/ml/medyas/bakingapp/Activities/RecipeDetailActivity.java b/app/src/main/java/ml/medyas/bakingapp/Activities/RecipeDetailActivity.java index a25f9f7..f23b704 100644 --- a/app/src/main/java/ml/medyas/bakingapp/Activities/RecipeDetailActivity.java +++ b/app/src/main/java/ml/medyas/bakingapp/Activities/RecipeDetailActivity.java @@ -33,8 +33,9 @@ protected void onCreate(Bundle savedInstanceState) { if (savedInstanceState != null) { recipe = savedInstanceState.getParcelable(RECIPE_ITEM); + } else { - recipe = AppSingleton.getSelectedRecipe(); + recipe = AppSingleton.getSelectedRecipe(); } if (findViewById(R.id.right_container) != null) { diff --git a/app/src/main/java/ml/medyas/bakingapp/Activities/RecipeDetailViewActivity.java b/app/src/main/java/ml/medyas/bakingapp/Activities/RecipeDetailViewActivity.java index 30c240e..417826a 100644 --- a/app/src/main/java/ml/medyas/bakingapp/Activities/RecipeDetailViewActivity.java +++ b/app/src/main/java/ml/medyas/bakingapp/Activities/RecipeDetailViewActivity.java @@ -1,5 +1,6 @@ package ml.medyas.bakingapp.Activities; +import android.annotation.SuppressLint; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.app.AppCompatActivity; @@ -23,6 +24,7 @@ public class RecipeDetailViewActivity extends AppCompatActivity implements Recip private RecipeClass recipe; private int position; + @SuppressLint("ClickableViewAccessibility") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -50,7 +52,7 @@ protected void onCreate(Bundle savedInstanceState) { public void onSwipeTop() { } public void onSwipeRight() { - if(0 SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCI } return result; } + } + public void onSwipeRight() { } diff --git a/app/src/main/java/ml/medyas/bakingapp/Classes/RecipeClass.java b/app/src/main/java/ml/medyas/bakingapp/Classes/RecipeClass.java index a069da3..8738b78 100644 --- a/app/src/main/java/ml/medyas/bakingapp/Classes/RecipeClass.java +++ b/app/src/main/java/ml/medyas/bakingapp/Classes/RecipeClass.java @@ -8,8 +8,11 @@ import java.util.List; -@Entity(tableName = "recipes") +@Entity(tableName = RecipeClass.TABLE_NAME) public class RecipeClass implements Parcelable { + /** The name of the Cheese table. */ + public static final String TABLE_NAME = "recipes"; + @PrimaryKey private int id; private int servings; diff --git a/app/src/main/java/ml/medyas/bakingapp/Database/DaoClass.java b/app/src/main/java/ml/medyas/bakingapp/Database/DaoClass.java index 19c9b0c..ea6d48e 100644 --- a/app/src/main/java/ml/medyas/bakingapp/Database/DaoClass.java +++ b/app/src/main/java/ml/medyas/bakingapp/Database/DaoClass.java @@ -5,6 +5,7 @@ import android.arch.persistence.room.Insert; import android.arch.persistence.room.OnConflictStrategy; import android.arch.persistence.room.Query; +import android.database.Cursor; import java.util.List; @@ -16,6 +17,12 @@ public interface DaoClass { @Insert(onConflict = OnConflictStrategy.REPLACE) void insert(List recipes); - @Query("select * from recipes ORDER BY id ASC") + @Query("select * from "+ RecipeClass.TABLE_NAME+" ORDER BY id ASC") LiveData> getRecipes(); + + @Query("select * from "+ RecipeClass.TABLE_NAME+" ORDER BY id ASC") + List getRecipesList(); + + @Query("select * from "+ RecipeClass.TABLE_NAME+" ORDER BY id ASC") + Cursor getRecipesCursor(); } diff --git a/app/src/main/java/ml/medyas/bakingapp/Database/RecipeContentProvider.java b/app/src/main/java/ml/medyas/bakingapp/Database/RecipeContentProvider.java new file mode 100644 index 0000000..7307141 --- /dev/null +++ b/app/src/main/java/ml/medyas/bakingapp/Database/RecipeContentProvider.java @@ -0,0 +1,78 @@ +package ml.medyas.bakingapp.Database; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Context; +import android.content.UriMatcher; +import android.database.Cursor; +import android.net.Uri; + +import ml.medyas.bakingapp.Classes.RecipeClass; + +public class RecipeContentProvider extends ContentProvider { + + public static final String AUTHORITY = "ml.medyas.baknigApp.RecipeContentProvider.provider"; + public static final Uri URI_RECIPE = Uri.parse( + "content://" + AUTHORITY + "/" + RecipeClass.TABLE_NAME); + + private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH); + + private DaoClass mDao; + private Context context; + /** The match code for some items in the Cheese table. */ + private static final int CODE_RECIPE_DIR = 1; + + static { + MATCHER.addURI(AUTHORITY, RecipeClass.TABLE_NAME, CODE_RECIPE_DIR); + } + + public RecipeContentProvider() { + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + // Implement this to handle requests to delete one or more rows. + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public String getType(Uri uri) { + // TODO: Implement this to handle requests for the MIME type of the data + // at the given URI. + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + // TODO: Implement this to handle requests to insert a new row. + throw new UnsupportedOperationException("Not yet implemented"); + } + + @Override + public boolean onCreate() { + context = getContext(); + mDao = RecipesRoomDB.getDatabase(context).recipeDao(); + return true; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, + String[] selectionArgs, String sortOrder) { + final int code = MATCHER.match(uri); + if (code == CODE_RECIPE_DIR) { + final Cursor cursor; + cursor = mDao.getRecipesCursor(); + cursor.setNotificationUri(context.getContentResolver(), uri); + return cursor; + } else { + throw new IllegalArgumentException("Unknown URI: " + uri); + } + } + + @Override + public int update(Uri uri, ContentValues values, String selection, + String[] selectionArgs) { + // TODO: Implement this to handle requests to update one or more rows. + throw new UnsupportedOperationException("Not yet implemented"); + } +} diff --git a/app/src/main/java/ml/medyas/bakingapp/Database/RecipesRoomDB.java b/app/src/main/java/ml/medyas/bakingapp/Database/RecipesRoomDB.java index f53d20b..df227ac 100644 --- a/app/src/main/java/ml/medyas/bakingapp/Database/RecipesRoomDB.java +++ b/app/src/main/java/ml/medyas/bakingapp/Database/RecipesRoomDB.java @@ -14,7 +14,7 @@ public abstract class RecipesRoomDB extends RoomDatabase { private static volatile RecipesRoomDB INSTANCE; - static RecipesRoomDB getDatabase(final Context context) { + public static RecipesRoomDB getDatabase(final Context context) { if (INSTANCE == null) { synchronized (RecipesRoomDB.class) { if (INSTANCE == null) { diff --git a/app/src/main/java/ml/medyas/bakingapp/Widget/ListWidgetService.java b/app/src/main/java/ml/medyas/bakingapp/Widget/ListWidgetService.java new file mode 100644 index 0000000..474db6e --- /dev/null +++ b/app/src/main/java/ml/medyas/bakingapp/Widget/ListWidgetService.java @@ -0,0 +1,85 @@ +package ml.medyas.bakingapp.Widget; + +import android.content.Context; +import android.content.Intent; +import android.widget.RemoteViews; +import android.widget.RemoteViewsService; + +import ml.medyas.bakingapp.R; + +import static ml.medyas.bakingapp.Widget.RecipesWidget.INGRED_LIST; +import static ml.medyas.bakingapp.Widget.RecipesWidget.ingred; + +public class ListWidgetService extends RemoteViewsService { + + + private String[] mIngred = null; + + @Override + public RemoteViewsFactory onGetViewFactory(final Intent intent) { + return new ListWidgetRemoteViewsFactory(this.getApplicationContext(), intent); + } + + + class ListWidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { + + private Context mContext; + + public ListWidgetRemoteViewsFactory(Context applicationContext, Intent intent) { + mContext = applicationContext; + mIngred = intent.getStringArrayExtra(INGRED_LIST); + } + + @Override + public void onCreate() { + } + + @Override + public void onDataSetChanged() { + mIngred = ingred; + } + + @Override + public void onDestroy() { + + } + + @Override + public int getCount() { + return mIngred.length; + } + + @Override + public RemoteViews getViewAt(int i) { + RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_list_item_layout); + rv.setTextViewText(R.id.widget_ingred_text, mIngred[i]); + + // Return the remote views object. + return rv; + + } + + @Override + public RemoteViews getLoadingView() { + return new RemoteViews(mContext.getPackageName(), R.layout.widget_list_item_loading_layout); + } + + @Override + public int getViewTypeCount() { + return 1; + } + + @Override + public long getItemId(int i) { + return 0; + } + + @Override + public boolean hasStableIds() { + return false; + } + + } +} + + diff --git a/app/src/main/java/ml/medyas/bakingapp/Widget/RecipesWidget.java b/app/src/main/java/ml/medyas/bakingapp/Widget/RecipesWidget.java index 3747a79..110cd6e 100644 --- a/app/src/main/java/ml/medyas/bakingapp/Widget/RecipesWidget.java +++ b/app/src/main/java/ml/medyas/bakingapp/Widget/RecipesWidget.java @@ -1,10 +1,21 @@ package ml.medyas.bakingapp.Widget; +import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.os.AsyncTask; import android.widget.RemoteViews; +import java.util.List; + +import ml.medyas.bakingapp.Activities.RecipeDetailActivity; +import ml.medyas.bakingapp.AppSingleton; +import ml.medyas.bakingapp.Classes.IngredientsClass; +import ml.medyas.bakingapp.Classes.RecipeClass; +import ml.medyas.bakingapp.Database.RecipesRoomDB; import ml.medyas.bakingapp.R; /** @@ -12,16 +23,100 @@ */ public class RecipesWidget extends AppWidgetProvider { - static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, - int appWidgetId) { + public static final String ACTION_UPDATE_SHOW_NEXT = "ACTION_UPDATE_SHOW_NEXT"; + public static final String ACTION_UPDATE_SHOW_PREV = "ACTION_UPDATE_SHOW_PREV"; + public static final String INGRED_LIST = "INGRED_LIST"; + public static final String INGRED_LIST_POS = "INGRED_LIST_POS"; + + public static int position = 0; + public static String[] ingred; + private static int size = 0; + private static List recipes = null; + + static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager, + final int appWidgetId) { + + new AsyncTask() { + @Override + protected Void doInBackground(Void... voids) { + Intent intent = null; + + if(recipes == null) { + recipes = RecipesRoomDB.getDatabase(context).recipeDao().getRecipesList(); + size = recipes.size(); + } + + // Construct the RemoteViews object + RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.recipes_widget); + views.setTextViewText(R.id.widget_recipe_title, recipes.get(position).getName()); + + Intent intentPrev = new Intent(context, RecipesWidget.class); + intentPrev.setAction(ACTION_UPDATE_SHOW_PREV); + PendingIntent pendingIntentPrev = PendingIntent.getBroadcast(context, 0, intentPrev, 0); + views.setOnClickPendingIntent(R.id.widget_prev_recipe, pendingIntentPrev); + + Intent intentNext = new Intent(context, RecipesWidget.class); + intentNext.setAction(ACTION_UPDATE_SHOW_NEXT); + PendingIntent pendingIntentNext = PendingIntent.getBroadcast(context, 0, intentNext, 0); + views.setOnClickPendingIntent(R.id.widget_next_recipe, pendingIntentNext); + + ingred = new String[recipes.get(position).getIngredients().size()]; + for (int i = 0; i <= recipes.get(position).getIngredients().size()-1 ; i++) { + IngredientsClass ing = recipes.get(position).getIngredients().get(i); + ingred[i] = ing.getQuantity()+" "+ing.getMeasure()+(ing.getQuantity()>1?"'s":"")+" of "+ing.getIngredient(); + } + + intent = new Intent(context, ListWidgetService.class); + intent.putExtra(INGRED_LIST, ingred); + views.setRemoteAdapter(R.id.widget_ingred_list, intent); + + Intent intentViews = new Intent(context, RecipeDetailActivity.class); + AppSingleton.setSelectedRecipe(recipes.get(position)); + PendingIntent pendingIntentViews = PendingIntent.getActivity(context, 0, intentViews, 0); + views.setOnClickPendingIntent(R.id.widget_layout, pendingIntentViews); - CharSequence widgetText = context.getString(R.string.appwidget_text); - // Construct the RemoteViews object - RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.recipes_widget); - views.setTextViewText(R.id.appwidget_text, widgetText); + appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_ingred_list); + // Instruct the widget manager to update the widget + appWidgetManager.updateAppWidget(appWidgetId, views); + + return null; + } + }.execute(); + + + } + + @Override + public void onReceive(Context context, Intent intent) { + super.onReceive(context, intent); + if(intent.getAction().equals(AppWidgetManager.ACTION_APPWIDGET_UPDATE)) { + AppWidgetManager widgetManager = AppWidgetManager.getInstance(context); + int[] ids = widgetManager.getAppWidgetIds(new ComponentName(context, RecipesWidget.class)); + onUpdate(context, widgetManager, ids); + + } else if(intent.getAction().equals(ACTION_UPDATE_SHOW_NEXT)) { + if(position+1 >= size) { + position = 0; + } else { + position++ ; + } + + AppWidgetManager widgetManager = AppWidgetManager.getInstance(context); + int[] ids = widgetManager.getAppWidgetIds(new ComponentName(context, RecipesWidget.class)); + onUpdate(context, widgetManager, ids); + + } else if(intent.getAction().equals(ACTION_UPDATE_SHOW_PREV)) { + if(position-1 > -1) { + position--; + } else { + position = size-1; + } + + AppWidgetManager widgetManager = AppWidgetManager.getInstance(context); + int[] ids = widgetManager.getAppWidgetIds(new ComponentName(context, RecipesWidget.class)); + onUpdate(context, widgetManager, ids); + } - // Instruct the widget manager to update the widget - appWidgetManager.updateAppWidget(appWidgetId, views); } @Override diff --git a/app/src/main/res/drawable/ic_navigate_before_black_24dp.xml b/app/src/main/res/drawable/ic_navigate_before_black_24dp.xml index 9ecb7b3..3669c37 100644 --- a/app/src/main/res/drawable/ic_navigate_before_black_24dp.xml +++ b/app/src/main/res/drawable/ic_navigate_before_black_24dp.xml @@ -1,4 +1,4 @@ - diff --git a/app/src/main/res/drawable/ic_navigate_next_black_24dp.xml b/app/src/main/res/drawable/ic_navigate_next_black_24dp.xml index 6fb106f..442236b 100644 --- a/app/src/main/res/drawable/ic_navigate_next_black_24dp.xml +++ b/app/src/main/res/drawable/ic_navigate_next_black_24dp.xml @@ -1,4 +1,4 @@ - diff --git a/app/src/main/res/drawable/ic_recipe_book.xml b/app/src/main/res/drawable/ic_recipe_book.xml new file mode 100644 index 0000000..9c23e92 --- /dev/null +++ b/app/src/main/res/drawable/ic_recipe_book.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/layout/recipes_widget.xml b/app/src/main/res/layout/recipes_widget.xml index bdd13ce..8dbedf8 100644 --- a/app/src/main/res/layout/recipes_widget.xml +++ b/app/src/main/res/layout/recipes_widget.xml @@ -1,21 +1,58 @@ - - - - \ No newline at end of file + android:orientation="horizontal" + android:id="@+id/widget_layout" + android:background="@color/colorAccent" + android:elevation="4dp"> + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/widget_list_item_layout.xml b/app/src/main/res/layout/widget_list_item_layout.xml new file mode 100644 index 0000000..87f0304 --- /dev/null +++ b/app/src/main/res/layout/widget_list_item_layout.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/widget_list_item_loading_layout.xml b/app/src/main/res/layout/widget_list_item_loading_layout.xml new file mode 100644 index 0000000..ba38e1e --- /dev/null +++ b/app/src/main/res/layout/widget_list_item_loading_layout.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index eb04e81..72b9936 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,4 +12,6 @@ false EXAMPLE Add widget + next recipe ingred + previous recipe ingre diff --git a/build.gradle b/build.gradle index 4e8009d..8d3ef8e 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.0' + classpath 'com.android.tools.build:gradle:3.2.1' // NOTE: Do not place your application dependencies here; they belong