diff --git a/.idea/misc.xml b/.idea/misc.xml index 7158618b..b380e643 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -37,6 +37,9 @@ + + + diff --git a/app/build.gradle b/app/build.gradle index 1f5c53dc..67bc6deb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,7 +5,7 @@ android { buildToolsVersion "24.0.3" defaultConfig { applicationId "us.koller.cameraroll" - minSdkVersion 21 + minSdkVersion 19 targetSdkVersion 25 versionCode 11 versionName "v1.1.1 Beta" diff --git a/app/src/main/java/us/koller/cameraroll/adapter/album/RecyclerViewAdapter.java b/app/src/main/java/us/koller/cameraroll/adapter/album/RecyclerViewAdapter.java index e693793c..95662b2a 100644 --- a/app/src/main/java/us/koller/cameraroll/adapter/album/RecyclerViewAdapter.java +++ b/app/src/main/java/us/koller/cameraroll/adapter/album/RecyclerViewAdapter.java @@ -1,7 +1,5 @@ package us.koller.cameraroll.adapter.album; -import android.animation.ObjectAnimator; -import android.animation.PropertyValuesHolder; import android.app.Activity; import android.content.Intent; import android.graphics.drawable.Drawable; @@ -26,6 +24,7 @@ import us.koller.cameraroll.data.Photo; import us.koller.cameraroll.data.Video; import us.koller.cameraroll.ui.ItemActivity; +import us.koller.cameraroll.util.Util; public class RecyclerViewAdapter extends RecyclerView.Adapter { @@ -104,20 +103,28 @@ public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) ((AlbumItemHolder) holder).setAlbumItem(albumItem); - holder.itemView.findViewById(R.id.image) - .setSelected(selected_items[album.getAlbumItems().indexOf(albumItem)]); - //fade selected indicator - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { - boolean selected = selected_items[album.getAlbumItems() - .indexOf(((AlbumItemHolder) holder).albumItem)]; + boolean selected = selected_items[album.getAlbumItems() + .indexOf(((AlbumItemHolder) holder).albumItem)]; - Drawable foreground = holder.itemView.findViewById(R.id.image).getForeground(); + final View imageView = holder.itemView.findViewById(R.id.image); - ObjectAnimator - .ofPropertyValuesHolder(foreground, - PropertyValuesHolder.ofInt("alpha", - selected ? 0 : 255, - selected ? 255 : 0)).start(); + final Drawable selectorOverlay = Util.getAlbumItemSelectorOverlay(imageView.getContext()); + if (selected) { + imageView.post(new Runnable() { + @Override + public void run() { + imageView.getOverlay().clear(); + selectorOverlay.setBounds(0, 0, imageView.getWidth(), imageView.getHeight()); + imageView.getOverlay().add(selectorOverlay); + } + }); + } else { + imageView.post(new Runnable() { + @Override + public void run() { + imageView.getOverlay().clear(); + } + }); } holder.itemView.setTag(albumItem.getPath()); @@ -202,20 +209,6 @@ private void onItemSelected(AlbumItemHolder holder) { selected_items[album.getAlbumItems().indexOf(holder.albumItem)] = !selected_items[album.getAlbumItems().indexOf(holder.albumItem)]; notifyItemChanged(album.getAlbumItems().indexOf(holder.albumItem)); - /*holder.itemView.findViewById(R.id.image) - .setSelected(selected_items[album.getAlbumItems().indexOf(holder.albumItem)]);*/ - - /*//fade selected indicator - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { - boolean selected = selected_items[album.getAlbumItems().indexOf(holder.albumItem)]; - Drawable foreground = holder.itemView.findViewById(R.id.image).getForeground(); - - ObjectAnimator - .ofPropertyValuesHolder(foreground, - PropertyValuesHolder.ofInt("alpha", - selected ? 0 : 255, - selected ? 255 : 0)).start(); - }*/ callback.onItemSelected(getSelectedItemCount()); checkForNoSelectedItems(); diff --git a/app/src/main/java/us/koller/cameraroll/adapter/fileExplorer/ViewHolder/FileHolder.java b/app/src/main/java/us/koller/cameraroll/adapter/fileExplorer/ViewHolder/FileHolder.java index 141f5322..0890e1c1 100644 --- a/app/src/main/java/us/koller/cameraroll/adapter/fileExplorer/ViewHolder/FileHolder.java +++ b/app/src/main/java/us/koller/cameraroll/adapter/fileExplorer/ViewHolder/FileHolder.java @@ -2,6 +2,7 @@ import android.graphics.drawable.Drawable; import android.support.v4.content.ContextCompat; +import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.ImageView; @@ -59,8 +60,11 @@ public void setSelected(boolean selected) { selected ? R.color.grey_900_translucent : R.color.white_translucent1)); ImageView folderIndicator = (ImageView) itemView.findViewById(R.id.folder_indicator); - Drawable d = folderIndicator.getDrawable().mutate(); - d.setTint(ContextCompat.getColor(itemView.getContext(), + Drawable d = folderIndicator.getDrawable(); + /*d.setTint(ContextCompat.getColor(itemView.getContext(), + selected ? R.color.grey_900_translucent : R.color.white));*/ + d = DrawableCompat.wrap(d); + DrawableCompat.setTint(d.mutate(), ContextCompat.getColor(itemView.getContext(), selected ? R.color.grey_900_translucent : R.color.white)); folderIndicator.setImageDrawable(d); } diff --git a/app/src/main/java/us/koller/cameraroll/data/FileOperations/Copy.java b/app/src/main/java/us/koller/cameraroll/data/FileOperations/Copy.java index 71ff52e6..f4b04d41 100644 --- a/app/src/main/java/us/koller/cameraroll/data/FileOperations/Copy.java +++ b/app/src/main/java/us/koller/cameraroll/data/FileOperations/Copy.java @@ -20,12 +20,12 @@ public Copy(File_POJO[] files) { } @Override - public void execute(Activity context, File_POJO target, Callback callback) { + void executeAsync(final Activity context, File_POJO target, final Callback callback) { if (target == null) { return; } - File_POJO[] files = getFiles(); + final File_POJO[] files = getFiles(); int success_count = 0; for (int i = 0; i < files.length; i++) { @@ -33,13 +33,19 @@ public void execute(Activity context, File_POJO target, Callback callback) { success_count += result ? 1 : 0; } - Toast.makeText(context, context.getString(R.string.successfully_copied) - + String.valueOf(success_count) + "/" - + String.valueOf(files.length), Toast.LENGTH_SHORT).show(); - - if (callback != null) { - callback.done(); - } + final int finalSuccess_count = success_count; + context.runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(context, context.getString(R.string.successfully_copied) + + String.valueOf(finalSuccess_count) + "/" + + String.valueOf(files.length), Toast.LENGTH_SHORT).show(); + + if (callback != null) { + callback.done(); + } + } + }); operation = EMPTY; } diff --git a/app/src/main/java/us/koller/cameraroll/data/FileOperations/Delete.java b/app/src/main/java/us/koller/cameraroll/data/FileOperations/Delete.java index 9965f9ae..3686dbb7 100644 --- a/app/src/main/java/us/koller/cameraroll/data/FileOperations/Delete.java +++ b/app/src/main/java/us/koller/cameraroll/data/FileOperations/Delete.java @@ -3,6 +3,7 @@ import android.app.Activity; import android.content.ContentResolver; import android.content.ContentValues; +import android.os.Build; import android.os.Environment; import android.provider.MediaStore; import android.widget.Toast; @@ -22,8 +23,8 @@ public Delete(File_POJO[] files) { } @Override - public void execute(Activity context, File_POJO target, Callback callback) { - File_POJO[] files = getFiles(); + void executeAsync(final Activity context, File_POJO target, final Callback callback) { + final File_POJO[] files = getFiles(); int success_count = 0; for (int i = 0; i < files.length; i++) { @@ -37,20 +38,27 @@ public void execute(Activity context, File_POJO target, Callback callback) { } } - Toast.makeText(context, context.getString(R.string.successfully_deleted) - + String.valueOf(success_count) + "/" - + String.valueOf(files.length), Toast.LENGTH_SHORT).show(); + final int finalSuccess_count = success_count; + context.runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(context, context.getString(R.string.successfully_deleted) + + String.valueOf(finalSuccess_count) + "/" + + String.valueOf(files.length), Toast.LENGTH_SHORT).show(); - if (callback != null) { - callback.done(); - } + if (callback != null) { + callback.done(); + } + } + }); operation = EMPTY; } private static boolean deleteFile(final Activity context, String path) { boolean success; - if (Environment.isExternalStorageRemovable(new File(path))) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP + && Environment.isExternalStorageRemovable(new File(path))) { //not working try { success = StorageUtil.delete(context, new File(path)); diff --git a/app/src/main/java/us/koller/cameraroll/data/FileOperations/FileOperation.java b/app/src/main/java/us/koller/cameraroll/data/FileOperations/FileOperation.java index a5699411..0873bf29 100644 --- a/app/src/main/java/us/koller/cameraroll/data/FileOperations/FileOperation.java +++ b/app/src/main/java/us/koller/cameraroll/data/FileOperations/FileOperation.java @@ -6,6 +6,7 @@ import android.content.Context; import android.media.MediaScannerConnection; import android.net.Uri; +import android.os.AsyncTask; import android.provider.MediaStore; import java.io.File; @@ -39,7 +40,16 @@ public File_POJO[] getFiles() { return files; } - public abstract void execute(final Activity context, final File_POJO target, final Callback callback); + public void execute(final Activity context, final File_POJO target, final Callback callback) { + AsyncTask.execute(new Runnable() { + @Override + public void run() { + executeAsync(context, target, callback); + } + }); + } + + abstract void executeAsync(final Activity context, final File_POJO target, final Callback callback); public static String getModeString(Context context) { switch (operation) { diff --git a/app/src/main/java/us/koller/cameraroll/data/FileOperations/Move.java b/app/src/main/java/us/koller/cameraroll/data/FileOperations/Move.java index ea286a9f..2eca3f63 100644 --- a/app/src/main/java/us/koller/cameraroll/data/FileOperations/Move.java +++ b/app/src/main/java/us/koller/cameraroll/data/FileOperations/Move.java @@ -15,12 +15,12 @@ public Move(File_POJO[] files) { } @Override - public void execute(Activity context, File_POJO target, Callback callback) { + void executeAsync(final Activity context, File_POJO target, final Callback callback) { if (target == null) { return; } - File_POJO[] files = getFiles(); + final File_POJO[] files = getFiles(); int success_count = 0; for (int i = 0; i < files.length; i++) { @@ -28,13 +28,19 @@ public void execute(Activity context, File_POJO target, Callback callback) { success_count += result ? 1 : 0; } - Toast.makeText(context, context.getString(R.string.successfully_moved) - + String.valueOf(success_count) + "/" - + String.valueOf(files.length), Toast.LENGTH_SHORT).show(); - - if (callback != null) { - callback.done(); - } + final int finalSuccess_count = success_count; + context.runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(context, context.getString(R.string.successfully_moved) + + String.valueOf(finalSuccess_count) + "/" + + String.valueOf(files.length), Toast.LENGTH_SHORT).show(); + + if (callback != null) { + callback.done(); + } + } + }); operation = EMPTY; } diff --git a/app/src/main/java/us/koller/cameraroll/data/FileOperations/NewDirectory.java b/app/src/main/java/us/koller/cameraroll/data/FileOperations/NewDirectory.java index c5761f9f..29865c1b 100644 --- a/app/src/main/java/us/koller/cameraroll/data/FileOperations/NewDirectory.java +++ b/app/src/main/java/us/koller/cameraroll/data/FileOperations/NewDirectory.java @@ -15,8 +15,8 @@ public NewDirectory(File_POJO[] files) { } @Override - public void execute(Activity context, File_POJO target, Callback callback) { - File_POJO[] files = getFiles(); + void executeAsync(final Activity context, File_POJO target, final Callback callback) { + final File_POJO[] files = getFiles(); if (files.length > 0) { File_POJO file = files[0]; boolean result = createNewFolder(file.getPath()); @@ -26,13 +26,23 @@ public void execute(Activity context, File_POJO target, Callback callback) { } } - Toast.makeText(context, context.getString(R.string.successfully_created_new_folder), - Toast.LENGTH_SHORT).show(); + context.runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(context, context.getString(R.string.successfully_created_new_folder), + Toast.LENGTH_SHORT).show(); + } + }); } - if (callback != null) { - callback.done(); - } + context.runOnUiThread(new Runnable() { + @Override + public void run() { + if (callback != null) { + callback.done(); + } + } + }); operation = EMPTY; } diff --git a/app/src/main/java/us/koller/cameraroll/ui/AboutActivity.java b/app/src/main/java/us/koller/cameraroll/ui/AboutActivity.java index a6f71705..5db5a6b6 100644 --- a/app/src/main/java/us/koller/cameraroll/ui/AboutActivity.java +++ b/app/src/main/java/us/koller/cameraroll/ui/AboutActivity.java @@ -6,6 +6,7 @@ import android.os.Bundle; import android.os.Handler; import android.support.annotation.Nullable; +import android.support.annotation.RequiresApi; import android.support.v4.content.ContextCompat; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; @@ -37,8 +38,10 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_about); - getWindow().setEnterTransition(new Slide(Gravity.TOP)); - getWindow().setReturnTransition(new Slide(Gravity.TOP)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + getWindow().setEnterTransition(new Slide(Gravity.TOP)); + getWindow().setReturnTransition(new Slide(Gravity.TOP)); + } SwipeBackCoordinatorLayout swipeBackView = (SwipeBackCoordinatorLayout) findViewById(R.id.swipeBackView); @@ -78,36 +81,39 @@ public boolean onLongClick(View view) { aboutText.setText(Html.fromHtml(getString(R.string.about_text))); aboutText.setMovementMethod(new LinkMovementMethod()); - final View rootView = findViewById(R.id.root_view); - rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { - @Override - public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { - toolbar.setPadding(toolbar.getPaddingStart() /*+ insets.getSystemWindowInsetLeft()*/, - toolbar.getPaddingTop() + insets.getSystemWindowInsetTop(), - toolbar.getPaddingEnd() /*+ insets.getSystemWindowInsetRight()*/, - toolbar.getPaddingBottom()); - - aboutText.setPadding(aboutText.getPaddingStart(), - aboutText.getPaddingTop(), - aboutText.getPaddingEnd(), - aboutText.getPaddingBottom() + insets.getSystemWindowInsetBottom()); - - View viewGroup = findViewById(R.id.swipeBackView); - ViewGroup.MarginLayoutParams viewGroupParams - = (ViewGroup.MarginLayoutParams) viewGroup.getLayoutParams(); - viewGroupParams.leftMargin += insets.getSystemWindowInsetLeft(); - viewGroupParams.rightMargin += insets.getSystemWindowInsetRight(); - viewGroup.setLayoutParams(viewGroupParams); - - // clear this listener so insets aren't re-applied - rootView.setOnApplyWindowInsetsListener(null); - return insets.consumeSystemWindowInsets(); - } - }); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { + final View rootView = findViewById(R.id.root_view); + rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { + @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) + @Override + public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { + toolbar.setPadding(toolbar.getPaddingStart() /*+ insets.getSystemWindowInsetLeft()*/, + toolbar.getPaddingTop() + insets.getSystemWindowInsetTop(), + toolbar.getPaddingEnd() /*+ insets.getSystemWindowInsetRight()*/, + toolbar.getPaddingBottom()); + + aboutText.setPadding(aboutText.getPaddingStart(), + aboutText.getPaddingTop(), + aboutText.getPaddingEnd(), + aboutText.getPaddingBottom() + insets.getSystemWindowInsetBottom()); + + View viewGroup = findViewById(R.id.swipeBackView); + ViewGroup.MarginLayoutParams viewGroupParams + = (ViewGroup.MarginLayoutParams) viewGroup.getLayoutParams(); + viewGroupParams.leftMargin += insets.getSystemWindowInsetLeft(); + viewGroupParams.rightMargin += insets.getSystemWindowInsetRight(); + viewGroup.setLayoutParams(viewGroupParams); + + // clear this listener so insets aren't re-applied + rootView.setOnApplyWindowInsetsListener(null); + return insets.consumeSystemWindowInsets(); + } + }); - //set status bar icon color - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + //set status bar icon color + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + } } for (int i = 0; i < toolbar.getChildCount(); i++) { @@ -187,9 +193,11 @@ public void onSwipeFinish(int dir) { handler = null; runnable = null; - getWindow().setReturnTransition(new TransitionSet() - .addTransition(new Slide(dir > 0 ? Gravity.TOP : Gravity.BOTTOM)) - .setInterpolator(new AccelerateDecelerateInterpolator())); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + getWindow().setReturnTransition(new TransitionSet() + .addTransition(new Slide(dir > 0 ? Gravity.TOP : Gravity.BOTTOM)) + .setInterpolator(new AccelerateDecelerateInterpolator())); + } onBackPressed(); } } diff --git a/app/src/main/java/us/koller/cameraroll/ui/AlbumActivity.java b/app/src/main/java/us/koller/cameraroll/ui/AlbumActivity.java index 992d55b0..ea9e564c 100644 --- a/app/src/main/java/us/koller/cameraroll/ui/AlbumActivity.java +++ b/app/src/main/java/us/koller/cameraroll/ui/AlbumActivity.java @@ -11,15 +11,18 @@ import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.RequiresApi; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.graphics.drawable.AnimatedVectorDrawableCompat; import android.support.v4.app.SharedElementCallback; import android.support.v4.content.ContextCompat; +import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; @@ -45,8 +48,8 @@ import us.koller.cameraroll.adapter.album.RecyclerViewAdapter; import us.koller.cameraroll.data.Album; import us.koller.cameraroll.data.AlbumItem; -import us.koller.cameraroll.data.FileOperations.FileOperation; import us.koller.cameraroll.data.FileOperations.Delete; +import us.koller.cameraroll.data.FileOperations.FileOperation; import us.koller.cameraroll.data.File_POJO; import us.koller.cameraroll.data.Provider.MediaProvider; import us.koller.cameraroll.data.Provider.Provider; @@ -71,6 +74,7 @@ public class AlbumActivity extends AppCompatActivity private final SharedElementCallback mCallback = new SharedElementCallback() { @Override + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void onMapSharedElements(List names, Map sharedElements) { if (sharedElementReturnPosition != -1) { String newTransitionName = album.getAlbumItems().get(sharedElementReturnPosition).getPath(); @@ -126,16 +130,18 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { MediaProvider.checkPermission(this); setExitSharedElementCallback(mCallback); - getWindow().setEnterTransition(new TransitionSet() - .setOrdering(TransitionSet.ORDERING_TOGETHER) - .addTransition(new Slide(Gravity.BOTTOM)) - .addTransition(new Fade()) - .setInterpolator(new AccelerateDecelerateInterpolator())); - getWindow().setReturnTransition(new TransitionSet() - .setOrdering(TransitionSet.ORDERING_TOGETHER) - .addTransition(new Slide(Gravity.BOTTOM)) - .addTransition(new Fade()) - .setInterpolator(new AccelerateDecelerateInterpolator())); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + getWindow().setEnterTransition(new TransitionSet() + .setOrdering(TransitionSet.ORDERING_TOGETHER) + .addTransition(new Slide(Gravity.BOTTOM)) + .addTransition(new Fade()) + .setInterpolator(new AccelerateDecelerateInterpolator())); + getWindow().setReturnTransition(new TransitionSet() + .setOrdering(TransitionSet.ORDERING_TOGETHER) + .addTransition(new Slide(Gravity.BOTTOM)) + .addTransition(new Fade()) + .setInterpolator(new AccelerateDecelerateInterpolator())); + } /*if (savedInstanceState != null && savedInstanceState.containsKey(ALBUM)) { album = savedInstanceState.getParcelable(ALBUM); @@ -164,10 +170,29 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { setSupportActionBar(toolbar); toolbar.setBackgroundColor(ContextCompat.getColor(this, R.color.black_translucent2)); if (!pick_photos) { - toolbar.setNavigationIcon(AnimatedVectorDrawableCompat.create(this, R.drawable.back_to_cancel_animateable)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + toolbar.setNavigationIcon(AnimatedVectorDrawableCompat.create(this, + R.drawable.back_to_cancel_animateable)); + } else { + toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon != null) { + navIcon = DrawableCompat.wrap(navIcon); + DrawableCompat.setTint(navIcon.mutate(), + ContextCompat.getColor(this, R.color.white_translucent1)); + toolbar.setNavigationIcon(navIcon); + } + } } else { toolbar.setNavigationIcon(R.drawable.ic_clear_black_24dp); - toolbar.getNavigationIcon().setTint(ContextCompat.getColor(this, R.color.grey_900_translucent)); + //toolbar.getNavigationIcon().setTint(ContextCompat.getColor(this, R.color.grey_900_translucent)); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon != null) { + navIcon = DrawableCompat.wrap(navIcon); + DrawableCompat.setTint(navIcon.mutate(), + ContextCompat.getColor(this, R.color.grey_900_translucent)); + toolbar.setNavigationIcon(navIcon); + } Util.setDarkStatusBarIcons(findViewById(R.id.root_view)); } @@ -216,45 +241,61 @@ public void onScrolled(RecyclerView recyclerView, int dx, int dy) { final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); if (!pick_photos) { - fab.setImageDrawable(AnimatedVectorDrawableCompat.create(this, R.drawable.ic_delete_vector_animateable)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + fab.setImageDrawable(AnimatedVectorDrawableCompat + .create(this, R.drawable.ic_delete_vector_animateable)); + } else { + fab.setImageResource(R.drawable.ic_delete_white_24dp); + } } else { fab.setImageResource(R.drawable.ic_send_white_24dp); } Drawable d = fab.getDrawable(); - d.setTint(ContextCompat.getColor(this, R.color.grey_900_translucent)); + //AnimatedVectorDrawableCompat.mutate(): + // java.lang.IllegalStateException: Mutate() is not supported for older platform + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + d.setTint(ContextCompat.getColor(this, R.color.grey_900_translucent)); + } else { + d = DrawableCompat.wrap(d); + DrawableCompat.setTint(d.mutate(), + ContextCompat.getColor(this, R.color.grey_900_translucent)); + } fab.setImageDrawable(d); fab.setScaleX(0.0f); fab.setScaleY(0.0f); - rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { - @Override - public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { - toolbar.setPadding(toolbar.getPaddingStart(), - toolbar.getPaddingTop() + insets.getSystemWindowInsetTop(), - toolbar.getPaddingEnd(), - toolbar.getPaddingBottom()); - - ViewGroup.MarginLayoutParams toolbarParams - = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); - toolbarParams.leftMargin += insets.getSystemWindowInsetLeft(); - toolbarParams.rightMargin += insets.getSystemWindowInsetRight(); - toolbar.setLayoutParams(toolbarParams); - - recyclerView.setPadding(recyclerView.getPaddingStart() + insets.getSystemWindowInsetLeft(), - recyclerView.getPaddingTop() /*+ insets.getSystemWindowInsetTop()*/, - recyclerView.getPaddingEnd() + insets.getSystemWindowInsetRight(), - recyclerView.getPaddingBottom() + insets.getSystemWindowInsetBottom()); - - ViewGroup.MarginLayoutParams fabParams - = (ViewGroup.MarginLayoutParams) fab.getLayoutParams(); - fabParams.rightMargin += insets.getSystemWindowInsetRight(); - fabParams.bottomMargin += insets.getSystemWindowInsetBottom(); - fab.setLayoutParams(fabParams); - - rootView.setOnApplyWindowInsetsListener(null); - return insets.consumeSystemWindowInsets(); - } - }); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { + rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { + @Override + @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) + public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { + toolbar.setPadding(toolbar.getPaddingStart(), + toolbar.getPaddingTop() + insets.getSystemWindowInsetTop(), + toolbar.getPaddingEnd(), + toolbar.getPaddingBottom()); + + ViewGroup.MarginLayoutParams toolbarParams + = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); + toolbarParams.leftMargin += insets.getSystemWindowInsetLeft(); + toolbarParams.rightMargin += insets.getSystemWindowInsetRight(); + toolbar.setLayoutParams(toolbarParams); + + recyclerView.setPadding(recyclerView.getPaddingStart() + insets.getSystemWindowInsetLeft(), + recyclerView.getPaddingTop() /*+ insets.getSystemWindowInsetTop()*/, + recyclerView.getPaddingEnd() + insets.getSystemWindowInsetRight(), + recyclerView.getPaddingBottom() + insets.getSystemWindowInsetBottom()); + + ViewGroup.MarginLayoutParams fabParams + = (ViewGroup.MarginLayoutParams) fab.getLayoutParams(); + fabParams.rightMargin += insets.getSystemWindowInsetRight(); + fabParams.bottomMargin += insets.getSystemWindowInsetBottom(); + fab.setLayoutParams(fabParams); + + rootView.setOnApplyWindowInsetsListener(null); + return insets.consumeSystemWindowInsets(); + } + }); + } toolbar.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override @@ -271,7 +312,9 @@ public boolean onPreDraw() { } }); - setupTaskDescription(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + setupTaskDescription(); + } onNewIntent(getIntent()); } @@ -295,6 +338,7 @@ protected void onNewIntent(Intent intent) { } @Override + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void onActivityReenter(int requestCode, Intent data) { super.onActivityReenter(requestCode, data); Bundle tmpReenterState = new Bundle(data.getExtras()); @@ -332,7 +376,10 @@ public boolean onCreateOptionsMenu(Menu menu) { this.menu = menu; Drawable icon = menu.findItem(R.id.share).getIcon().mutate(); - icon.setTint(ContextCompat.getColor(this, R.color.grey_900_translucent)); + //icon.setTint(ContextCompat.getColor(this, R.color.grey_900_translucent)); + icon = DrawableCompat.wrap(icon); + DrawableCompat.setTint(icon.mutate(), + ContextCompat.getColor(this, R.color.grey_900_translucent)); menu.findItem(R.id.share).setIcon(icon); } @@ -573,15 +620,30 @@ public void onSelectorModeEnter() { ContextCompat.getColor(this, R.color.black_translucent2), ContextCompat.getColor(this, R.color.colorAccent)); - ((Animatable) toolbar.getNavigationIcon()).start(); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon instanceof Animatable) { + ((Animatable) navIcon).start(); + } new Handler().postDelayed(new Runnable() { @Override public void run() { - toolbar.setNavigationIcon(AnimatedVectorDrawableCompat - .create(AlbumActivity.this, R.drawable.cancel_to_back_vector_animateable)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + toolbar.setNavigationIcon(AnimatedVectorDrawableCompat + .create(AlbumActivity.this, R.drawable.cancel_to_back_vector_animateable)); + } else { + toolbar.setNavigationIcon(R.drawable.ic_clear_black_24dp); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon != null) { + navIcon = DrawableCompat.wrap(navIcon); + DrawableCompat.setTint(navIcon.mutate(), + ContextCompat.getColor(AlbumActivity.this, R.color.grey_900_translucent)); + toolbar.setNavigationIcon(navIcon); + } + } + toolbar.setTitleTextColor(ContextCompat.getColor(AlbumActivity.this, R.color.grey_900_translucent)); } - }, 300); + }, navIcon instanceof Animatable ? 300 : 0); } else { toolbar.setBackgroundColor(ContextCompat .getColor(this, R.color.colorAccent)); @@ -609,19 +671,34 @@ public void onSelectorModeExit() { ContextCompat.getColor(this, R.color.black_translucent2)); toolbar.setTitle(album.getName()); - ((Animatable) toolbar.getNavigationIcon()).start(); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon instanceof Animatable) { + ((Animatable) navIcon).start(); + } new Handler().postDelayed(new Runnable() { @Override public void run() { - toolbar.setNavigationIcon(AnimatedVectorDrawableCompat - .create(AlbumActivity.this, R.drawable.back_to_cancel_animateable)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + toolbar.setNavigationIcon(AnimatedVectorDrawableCompat + .create(AlbumActivity.this, R.drawable.back_to_cancel_animateable)); + } else { + toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon != null) { + navIcon = DrawableCompat.wrap(navIcon); + DrawableCompat.setTint(navIcon.mutate(), + ContextCompat.getColor(AlbumActivity.this, R.color.white)); + toolbar.setNavigationIcon(navIcon); + } + } + toolbar.setTitleTextColor(ContextCompat.getColor(AlbumActivity.this, R.color.white)); Util.setLightStatusBarIcons(findViewById(R.id.root_view)); menu.findItem(R.id.exclude).setVisible(true); } - }, 300); + }, navIcon instanceof Animatable ? 300 : 0); animateFab(false, false); menu.findItem(R.id.share).setVisible(false); @@ -751,6 +828,7 @@ public void onSaveInstanceState(Bundle outState) { recyclerView.getLayoutManager().onSaveInstanceState()); } + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private void setupTaskDescription() { Bitmap overviewIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); setTaskDescription(new ActivityManager.TaskDescription(getString(R.string.app_name), @@ -775,11 +853,13 @@ public void onSwipeFinish(int dir) { if (((RecyclerViewAdapter) recyclerView.getAdapter()).isSelectorModeActive()) { ((RecyclerViewAdapter) recyclerView.getAdapter()).cancelSelectorMode(); } - getWindow().setReturnTransition(new TransitionSet() - .setOrdering(TransitionSet.ORDERING_TOGETHER) - .addTransition(new Slide(dir > 0 ? Gravity.TOP : Gravity.BOTTOM)) - .addTransition(new Fade()) - .setInterpolator(new AccelerateDecelerateInterpolator())); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + getWindow().setReturnTransition(new TransitionSet() + .setOrdering(TransitionSet.ORDERING_TOGETHER) + .addTransition(new Slide(dir > 0 ? Gravity.TOP : Gravity.BOTTOM)) + .addTransition(new Fade()) + .setInterpolator(new AccelerateDecelerateInterpolator())); + } onBackPressed(); } } diff --git a/app/src/main/java/us/koller/cameraroll/ui/FileExplorerActivity.java b/app/src/main/java/us/koller/cameraroll/ui/FileExplorerActivity.java index 484a784c..1a6ad1f8 100644 --- a/app/src/main/java/us/koller/cameraroll/ui/FileExplorerActivity.java +++ b/app/src/main/java/us/koller/cameraroll/ui/FileExplorerActivity.java @@ -2,17 +2,19 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.os.Handler; +import android.support.annotation.RequiresApi; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.graphics.drawable.AnimatedVectorDrawableCompat; import android.support.v4.content.ContextCompat; +import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; @@ -92,18 +94,22 @@ protected void onCreate(Bundle savedInstanceState) { final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setBackgroundColor(ContextCompat.getColor(this, R.color.black_translucent2)); - toolbar.setNavigationIcon(AnimatedVectorDrawableCompat - .create(this, R.drawable.back_to_cancel_animateable)); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + toolbar.setNavigationIcon(AnimatedVectorDrawableCompat + .create(this, R.drawable.back_to_cancel_animateable)); + } else { + toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon != null) { + navIcon = DrawableCompat.wrap(navIcon); + DrawableCompat.setTint(navIcon.mutate(), + ContextCompat.getColor(this, R.color.white_translucent1)); + toolbar.setNavigationIcon(navIcon); + } + } setSupportActionBar(toolbar); - /*//set Toolbar overflow icon color - Drawable drawable = toolbar.getOverflowIcon(); - if (drawable != null) { - drawable = DrawableCompat.wrap(drawable); - DrawableCompat.setTint(drawable.mutate(), - ContextCompat.getColor(this, R.color.grey_900_translucent)); - toolbar.setOverflowIcon(drawable); - }*/ Util.colorToolbarOverflowMenuIcon(toolbar, ContextCompat.getColor(this, R.color.white_translucent1)); @@ -138,42 +144,48 @@ public void changeDir(String path) { final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setImageResource(R.drawable.ic_create_new_folder_white_24dp); Drawable d = fab.getDrawable(); - d.setTint(ContextCompat.getColor(this, R.color.grey_900_translucent)); + //d.setTint(ContextCompat.getColor(this, R.color.grey_900_translucent)); + d = DrawableCompat.wrap(d); + DrawableCompat.setTint(d.mutate(), + ContextCompat.getColor(this, R.color.grey_900_translucent)); fab.setImageDrawable(d); fab.setScaleX(0.0f); fab.setScaleY(0.0f); //setting window insets manually - rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { - @Override - public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { - toolbar.setPadding(toolbar.getPaddingStart() /*+ insets.getSystemWindowInsetLeft()*/, - toolbar.getPaddingTop() + insets.getSystemWindowInsetTop(), - toolbar.getPaddingEnd() /*+ insets.getSystemWindowInsetRight()*/, - toolbar.getPaddingBottom()); - - ViewGroup.MarginLayoutParams toolbarParams - = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); - toolbarParams.leftMargin += insets.getSystemWindowInsetLeft(); - toolbarParams.rightMargin += insets.getSystemWindowInsetRight(); - toolbar.setLayoutParams(toolbarParams); - - recyclerView.setPadding(recyclerView.getPaddingStart() + insets.getSystemWindowInsetLeft(), - recyclerView.getPaddingTop() /*+ insets.getSystemWindowInsetTop()*/, - recyclerView.getPaddingEnd() + insets.getSystemWindowInsetRight(), - recyclerView.getPaddingBottom() + insets.getSystemWindowInsetBottom()); - - ViewGroup.MarginLayoutParams fabParams - = (ViewGroup.MarginLayoutParams) fab.getLayoutParams(); - fabParams.rightMargin += insets.getSystemWindowInsetRight(); - fabParams.bottomMargin += insets.getSystemWindowInsetBottom(); - fab.setLayoutParams(fabParams); - - // clear this listener so insets aren't re-applied - rootView.setOnApplyWindowInsetsListener(null); - return insets.consumeSystemWindowInsets(); - } - }); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { + rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { + @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) + @Override + public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { + toolbar.setPadding(toolbar.getPaddingStart() /*+ insets.getSystemWindowInsetLeft()*/, + toolbar.getPaddingTop() + insets.getSystemWindowInsetTop(), + toolbar.getPaddingEnd() /*+ insets.getSystemWindowInsetRight()*/, + toolbar.getPaddingBottom()); + + ViewGroup.MarginLayoutParams toolbarParams + = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); + toolbarParams.leftMargin += insets.getSystemWindowInsetLeft(); + toolbarParams.rightMargin += insets.getSystemWindowInsetRight(); + toolbar.setLayoutParams(toolbarParams); + + recyclerView.setPadding(recyclerView.getPaddingStart() + insets.getSystemWindowInsetLeft(), + recyclerView.getPaddingTop() /*+ insets.getSystemWindowInsetTop()*/, + recyclerView.getPaddingEnd() + insets.getSystemWindowInsetRight(), + recyclerView.getPaddingBottom() + insets.getSystemWindowInsetBottom()); + + ViewGroup.MarginLayoutParams fabParams + = (ViewGroup.MarginLayoutParams) fab.getLayoutParams(); + fabParams.rightMargin += insets.getSystemWindowInsetRight(); + fabParams.bottomMargin += insets.getSystemWindowInsetBottom(); + fab.setLayoutParams(fabParams); + + // clear this listener so insets aren't re-applied + rootView.setOnApplyWindowInsetsListener(null); + return insets.consumeSystemWindowInsets(); + } + }); + } //setting recyclerView top padding, so recyclerView starts below the toolbar toolbar.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @@ -334,8 +346,10 @@ public boolean onCreateOptionsMenu(Menu menu) { manageMenuItems(); Drawable icon = menu.findItem(R.id.paste).getIcon().mutate(); - icon.setTint(ContextCompat.getColor(FileExplorerActivity.this, - R.color.grey_900_translucent)); + //icon.setTint(ContextCompat.getColor(FileExplorerActivity.this, R.color.grey_900_translucent)); + icon = DrawableCompat.wrap(icon); + DrawableCompat.setTint(icon.mutate(), + ContextCompat.getColor(this, R.color.grey_900_translucent)); menu.findItem(R.id.paste).setIcon(icon); return super.onCreateOptionsMenu(menu); @@ -561,11 +575,13 @@ public void onSwipeProcess(float percent) { @Override public void onSwipeFinish(int dir) { - getWindow().setReturnTransition(new TransitionSet() - .setOrdering(TransitionSet.ORDERING_TOGETHER) - .addTransition(new Slide(dir > 0 ? Gravity.TOP : Gravity.BOTTOM)) - .addTransition(new Fade()) - .setInterpolator(new AccelerateDecelerateInterpolator())); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + getWindow().setReturnTransition(new TransitionSet() + .setOrdering(TransitionSet.ORDERING_TOGETHER) + .addTransition(new Slide(dir > 0 ? Gravity.TOP : Gravity.BOTTOM)) + .addTransition(new Fade()) + .setInterpolator(new AccelerateDecelerateInterpolator())); + } this.finish(); } @@ -588,12 +604,26 @@ public void onSelectorModeEnter() { ContextCompat.getColor(this, R.color.black_translucent2), ContextCompat.getColor(this, R.color.colorAccent)); - ((Animatable) toolbar.getNavigationIcon()).start(); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon instanceof Animatable) { + ((Animatable) navIcon).start(); + } new Handler().postDelayed(new Runnable() { @Override public void run() { - toolbar.setNavigationIcon(AnimatedVectorDrawableCompat - .create(FileExplorerActivity.this, R.drawable.cancel_to_back_vector_animateable)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + toolbar.setNavigationIcon(AnimatedVectorDrawableCompat + .create(FileExplorerActivity.this, R.drawable.cancel_to_back_vector_animateable)); + } else { + toolbar.setNavigationIcon(R.drawable.ic_clear_black_24dp); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon != null) { + navIcon = DrawableCompat.wrap(navIcon); + DrawableCompat.setTint(navIcon.mutate(), + ContextCompat.getColor(FileExplorerActivity.this, R.color.grey_900_translucent)); + toolbar.setNavigationIcon(navIcon); + } + } //make menu items visible for (int i = 0; i < menu.size(); i++) { @@ -605,7 +635,7 @@ public void run() { } } } - }, 300); + }, navIcon instanceof Animatable ? 300 : 0); } @Override @@ -747,12 +777,26 @@ public void resetToolbar() { ContextCompat.getColor(this, R.color.colorAccent), ContextCompat.getColor(this, R.color.black_translucent2)); - ((Animatable) toolbar.getNavigationIcon()).start(); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon instanceof Animatable) { + ((Animatable) navIcon).start(); + } new Handler().postDelayed(new Runnable() { @Override public void run() { - toolbar.setNavigationIcon(AnimatedVectorDrawableCompat - .create(FileExplorerActivity.this, R.drawable.back_to_cancel_animateable)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + toolbar.setNavigationIcon(AnimatedVectorDrawableCompat + .create(FileExplorerActivity.this, R.drawable.back_to_cancel_animateable)); + } else { + toolbar.setNavigationIcon(R.drawable.ic_arrow_back_white_24dp); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon != null) { + navIcon = DrawableCompat.wrap(navIcon); + DrawableCompat.setTint(navIcon.mutate(), + ContextCompat.getColor(FileExplorerActivity.this, R.color.white_translucent1)); + toolbar.setNavigationIcon(navIcon); + } + } Util.setLightStatusBarIcons(findViewById(R.id.root_view)); @@ -779,6 +823,6 @@ public void setTitle(Toolbar toolbar) { } } } - }, 300); + }, navIcon instanceof Animatable ? 300 : 0); } } diff --git a/app/src/main/java/us/koller/cameraroll/ui/ItemActivity.java b/app/src/main/java/us/koller/cameraroll/ui/ItemActivity.java index 7f4e0a82..321b223e 100644 --- a/app/src/main/java/us/koller/cameraroll/ui/ItemActivity.java +++ b/app/src/main/java/us/koller/cameraroll/ui/ItemActivity.java @@ -8,6 +8,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Animatable; +import android.graphics.drawable.Drawable; import android.media.ExifInterface; import android.net.Uri; import android.os.Build; @@ -15,6 +16,7 @@ import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.RequiresApi; import android.support.design.widget.Snackbar; import android.support.graphics.drawable.AnimatedVectorDrawableCompat; import android.support.v4.app.ShareCompat; @@ -36,6 +38,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.ImageView; @@ -47,6 +50,7 @@ import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -58,12 +62,14 @@ import us.koller.cameraroll.adapter.item.ViewPagerAdapter; import us.koller.cameraroll.data.Album; import us.koller.cameraroll.data.AlbumItem; -import us.koller.cameraroll.data.Provider.MediaProvider; import us.koller.cameraroll.data.Photo; +import us.koller.cameraroll.data.Provider.MediaProvider; import us.koller.cameraroll.data.Video; +import us.koller.cameraroll.util.ColorFade; import us.koller.cameraroll.util.MediaType; import us.koller.cameraroll.util.TransitionListenerAdapter; import us.koller.cameraroll.util.Util; +import us.koller.cameraroll.util.ZoomOutPageTransformer; public class ItemActivity extends AppCompatActivity { @@ -82,6 +88,7 @@ public class ItemActivity extends AppCompatActivity { private boolean isReturning; private final SharedElementCallback sharedElementCallback = new SharedElementCallback() { @Override + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public void onMapSharedElements(List names, Map sharedElements) { if (isReturning) { ViewGroup v = (ViewGroup) viewPager.findViewWithTag(albumItem.getPath()); @@ -168,7 +175,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { view_only = getIntent().getBooleanExtra(VIEW_ONLY, false); - if (!view_only) { + if (!view_only && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { postponeEnterTransition(); setEnterSharedElementCallback(sharedElementCallback); getWindow().getSharedElementEnterTransition().addListener(transitionListener); @@ -225,34 +232,52 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { viewPager.setAdapter(new ViewPagerAdapter(album)); viewPager.setCurrentItem(album.getAlbumItems().indexOf(albumItem), false); viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + private final int color = ContextCompat.getColor(ItemActivity.this, R.color.white); + @Override public void onPageSelected(int position) { - albumItem = album.getAlbumItems().get(position); + /*albumItem = album.getAlbumItems().get(position); if (actionBar != null) { actionBar.setTitle(albumItem.getName() != null ? albumItem.getName() : ""); - } + }*/ + albumItem = album.getAlbumItems().get(position); + ColorFade.fadeToolbarTitleColor(toolbar, color, + new ColorFade.ToolbarTitleFadeCallback() { + @Override + public void setTitle(Toolbar toolbar) { + toolbar.setTitle(albumItem.getName() != null ? albumItem.getName() : ""); + } + }, true); menu.findItem(R.id.set_as).setVisible(albumItem instanceof Photo); } }); + viewPager.setPageTransformer(true, new ZoomOutPageTransformer()); + bottomBar = findViewById(R.id.bottom_bar); ImageView delete_button = (ImageView) bottomBar.findViewById(R.id.delete_button); if (!view_only) { - delete_button.setImageDrawable(AnimatedVectorDrawableCompat - .create(this, R.drawable.ic_delete_vector_animateable)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + delete_button.setImageDrawable(AnimatedVectorDrawableCompat + .create(this, R.drawable.ic_delete_vector_animateable)); + } else { + delete_button.setImageResource(R.drawable.ic_delete_white_24dp); + } } else { ((View) delete_button.getParent()).setVisibility(View.GONE); } final ViewGroup rootView = (ViewGroup) findViewById(R.id.root_view); - rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { - @Override - public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { - toolbar.setPadding(toolbar.getPaddingStart() + insets.getSystemWindowInsetLeft(), - toolbar.getPaddingTop() + insets.getSystemWindowInsetTop(), - toolbar.getPaddingEnd() + insets.getSystemWindowInsetRight(), - toolbar.getPaddingBottom()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { + rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { + @Override + @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) + public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { + toolbar.setPadding(toolbar.getPaddingStart() + insets.getSystemWindowInsetLeft(), + toolbar.getPaddingTop() + insets.getSystemWindowInsetTop(), + toolbar.getPaddingEnd() + insets.getSystemWindowInsetRight(), + toolbar.getPaddingBottom()); /*ViewGroup.MarginLayoutParams toolbarParams = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); @@ -260,10 +285,10 @@ public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { toolbarParams.rightMargin += insets.getSystemWindowInsetRight(); toolbar.setLayoutParams(toolbarParams);*/ - bottomBar.setPadding(bottomBar.getPaddingStart() + insets.getSystemWindowInsetLeft(), - bottomBar.getPaddingTop(), - bottomBar.getPaddingEnd() + insets.getSystemWindowInsetRight(), - bottomBar.getPaddingBottom() + insets.getSystemWindowInsetBottom()); + bottomBar.setPadding(bottomBar.getPaddingStart() + insets.getSystemWindowInsetLeft(), + bottomBar.getPaddingTop(), + bottomBar.getPaddingEnd() + insets.getSystemWindowInsetRight(), + bottomBar.getPaddingBottom() + insets.getSystemWindowInsetBottom()); /*ViewGroup.MarginLayoutParams bottomBarParams = (ViewGroup.MarginLayoutParams) ((View) bottomBar.getParent()).getLayoutParams(); @@ -271,11 +296,40 @@ public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { bottomBarParams.rightMargin += insets.getSystemWindowInsetRight(); ((View) bottomBar.getParent()).setLayoutParams(bottomBarParams);*/ - // clear this listener so insets aren't re-applied - rootView.setOnApplyWindowInsetsListener(null); - return insets.consumeSystemWindowInsets(); - } - }); + // clear this listener so insets aren't re-applied + rootView.setOnApplyWindowInsetsListener(null); + return insets.consumeSystemWindowInsets(); + } + }); + } else { + rootView.getViewTreeObserver() + .addOnGlobalLayoutListener( + new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + //hacky way of getting window insets on pre-Lollipop + int[] screenSize = Util.getScreenSize(ItemActivity.this); + + int[] windowInsets = new int[]{ + screenSize[0] - rootView.getLeft(), + screenSize[1] - rootView.getTop(), + screenSize[2] - rootView.getRight(), + rootView.getBottom() - screenSize[3]}; + + toolbar.setPadding(toolbar.getPaddingStart() + windowInsets[0], + toolbar.getPaddingTop() + windowInsets[1], + toolbar.getPaddingEnd() + windowInsets[2], + toolbar.getPaddingBottom()); + + bottomBar.setPadding(bottomBar.getPaddingStart() + windowInsets[0], + bottomBar.getPaddingTop(), + bottomBar.getPaddingEnd() + windowInsets[2], + bottomBar.getPaddingBottom() + windowInsets[3]); + + rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } + }); + } //needed to achieve transparent navBar getWindow().getDecorView().setSystemUiVisibility( @@ -283,9 +337,11 @@ public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); - setupTaskDescription(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + setupTaskDescription(); + } - if (view_only) { + if (view_only || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { albumItem.isSharedElement = false; } } @@ -431,9 +487,11 @@ public void deletePhoto() { public void showInfoDialog() { ExifInterface exif = null; try { - if (albumItem.contentUri && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + Uri uri = albumItem.getUri(this); + Log.d("ItemActivity", "showInfoDialog: " + uri); exif = new ExifInterface(getContentResolver() - .openInputStream(albumItem.getUri(this))); + .openInputStream(uri)); } else { exif = new ExifInterface(albumItem.getPath()); } @@ -447,7 +505,10 @@ public void showInfoDialog() { String path = file.getPath(); String size = getFileSize(file); - boolean exifSupported = exif != null && MediaType.doesSupportExif(albumItem.getPath()); + boolean exifSupported = exif != null; + if (!albumItem.contentUri) { + exifSupported = exifSupported && MediaType.doesSupportExif(albumItem.getPath()); + } String height = NO_DATA, width = NO_DATA, date = NO_DATA, focal_length = NO_DATA, @@ -545,13 +606,18 @@ public void bottomBarOnClick(View v) { break; case R.id.delete_button: ImageView delete_button = (ImageView) v; - ((Animatable) delete_button.getDrawable()).start(); - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - showDeleteDialog(); - } - }, 400); + Drawable d = delete_button.getDrawable(); + if (d instanceof Animatable) { + ((Animatable) d).start(); + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + showDeleteDialog(); + } + }, 400); + } else { + showDeleteDialog(); + } break; } } @@ -606,6 +672,7 @@ public void run() { showUI(show); } + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private void setupTaskDescription() { Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); setTaskDescription(new ActivityManager.TaskDescription(getString(R.string.app_name), @@ -696,7 +763,11 @@ public void setResultAndFinish() { data.putExtra(AlbumActivity.EXTRA_CURRENT_ALBUM_POSITION, viewPager.getCurrentItem()); setResult(RESULT_OK, data); - finishAfterTransition(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + finishAfterTransition(); + } else { + finish(); + } } public String getFileSize(File file) { diff --git a/app/src/main/java/us/koller/cameraroll/ui/MainActivity.java b/app/src/main/java/us/koller/cameraroll/ui/MainActivity.java index 6b1ed7d4..b89908cd 100644 --- a/app/src/main/java/us/koller/cameraroll/ui/MainActivity.java +++ b/app/src/main/java/us/koller/cameraroll/ui/MainActivity.java @@ -6,8 +6,10 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; +import android.support.annotation.RequiresApi; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityOptionsCompat; import android.support.v4.content.ContextCompat; @@ -98,7 +100,14 @@ protected void onCreate(Bundle savedInstanceState) { toolbar.setTitleTextColor(ContextCompat.getColor(this, R.color.grey_900_translucent)); toolbar.setActivated(true); toolbar.setNavigationIcon(R.drawable.ic_clear_black_24dp); - toolbar.getNavigationIcon().setTint(ContextCompat.getColor(this, R.color.grey_900_translucent)); + //toolbar.getNavigationIcon().setTint(ContextCompat.getColor(this, R.color.grey_900_translucent)); + Drawable navIcon = toolbar.getNavigationIcon(); + if (navIcon != null) { + navIcon = DrawableCompat.wrap(navIcon); + DrawableCompat.setTint(navIcon.mutate(), + ContextCompat.getColor(this, R.color.grey_900_translucent)); + toolbar.setNavigationIcon(navIcon); + } toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -106,14 +115,8 @@ public void onClick(View view) { } }); - //set Toolbar overflow icon color - Drawable drawable = toolbar.getOverflowIcon(); - if (drawable != null) { - drawable = DrawableCompat.wrap(drawable); - DrawableCompat.setTint(drawable.mutate(), - ContextCompat.getColor(this, R.color.grey_900_translucent)); - toolbar.setOverflowIcon(drawable); - } + Util.colorToolbarOverflowMenuIcon(toolbar, + ContextCompat.getColor(this, R.color.grey_900_translucent)); Util.setDarkStatusBarIcons(findViewById(R.id.root_view)); } @@ -144,31 +147,34 @@ public void onScrolled(RecyclerView recyclerView, int dx, int dy) { }); //setting window insets manually - final ViewGroup rootView = (ViewGroup) findViewById(R.id.root_view); - rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { - @Override - public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { - toolbar.setPadding(toolbar.getPaddingStart() /*+ insets.getSystemWindowInsetLeft()*/, - toolbar.getPaddingTop() + insets.getSystemWindowInsetTop(), - toolbar.getPaddingEnd() /*+ insets.getSystemWindowInsetRight()*/, - toolbar.getPaddingBottom()); - - ViewGroup.MarginLayoutParams toolbarParams - = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); - toolbarParams.leftMargin += insets.getSystemWindowInsetLeft(); - toolbarParams.rightMargin += insets.getSystemWindowInsetRight(); - toolbar.setLayoutParams(toolbarParams); - - recyclerView.setPadding(recyclerView.getPaddingStart() + insets.getSystemWindowInsetLeft(), - recyclerView.getPaddingTop() + (pick_photos ? 0 : +insets.getSystemWindowInsetTop()), - recyclerView.getPaddingEnd() + insets.getSystemWindowInsetRight(), - recyclerView.getPaddingBottom() + insets.getSystemWindowInsetBottom()); - - // clear this listener so insets aren't re-applied - rootView.setOnApplyWindowInsetsListener(null); - return insets.consumeSystemWindowInsets(); - } - }); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { + final ViewGroup rootView = (ViewGroup) findViewById(R.id.root_view); + rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { + @Override + @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) + public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { + toolbar.setPadding(toolbar.getPaddingStart() /*+ insets.getSystemWindowInsetLeft()*/, + toolbar.getPaddingTop() + insets.getSystemWindowInsetTop(), + toolbar.getPaddingEnd() /*+ insets.getSystemWindowInsetRight()*/, + toolbar.getPaddingBottom()); + + ViewGroup.MarginLayoutParams toolbarParams + = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); + toolbarParams.leftMargin += insets.getSystemWindowInsetLeft(); + toolbarParams.rightMargin += insets.getSystemWindowInsetRight(); + toolbar.setLayoutParams(toolbarParams); + + recyclerView.setPadding(recyclerView.getPaddingStart() + insets.getSystemWindowInsetLeft(), + recyclerView.getPaddingTop() + (pick_photos ? 0 : +insets.getSystemWindowInsetTop()), + recyclerView.getPaddingEnd() + insets.getSystemWindowInsetRight(), + recyclerView.getPaddingBottom() + insets.getSystemWindowInsetBottom()); + + // clear this listener so insets aren't re-applied + rootView.setOnApplyWindowInsetsListener(null); + return insets.consumeSystemWindowInsets(); + } + }); + } //setting recyclerView top padding, so recyclerView starts below the toolbar toolbar.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @@ -186,7 +192,9 @@ public boolean onPreDraw() { } }); - setupTaskDescription(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + setupTaskDescription(); + } } @Override @@ -320,6 +328,7 @@ public boolean onOptionsItemSelected(MenuItem item) { return super.onOptionsItemSelected(item); } + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private void setupTaskDescription() { Bitmap overviewIcon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); setTaskDescription(new ActivityManager.TaskDescription(getString(R.string.app_name), diff --git a/app/src/main/java/us/koller/cameraroll/util/AnimUtils.java b/app/src/main/java/us/koller/cameraroll/util/AnimUtils.java index c3375450..05339084 100644 --- a/app/src/main/java/us/koller/cameraroll/util/AnimUtils.java +++ b/app/src/main/java/us/koller/cameraroll/util/AnimUtils.java @@ -1,29 +1,24 @@ package us.koller.cameraroll.util; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; -import android.annotation.TargetApi; import android.content.Context; import android.graphics.ColorMatrix; import android.os.Build; +import android.support.annotation.RequiresApi; import android.util.Property; -import android.view.View; import android.view.animation.AnimationUtils; -import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; // see: https://github.com/nickbutcher/plaid/blob/master/app/src/main/java/io/plaidapp/util/AnimUtils.java -public class AnimUtils { +class AnimUtils { private AnimUtils() { } private static Interpolator fastOutSlowIn; - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public static Interpolator getFastOutSlowInInterpolator(Context context) { + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + static Interpolator getFastOutSlowInInterpolator(Context context) { if (fastOutSlowIn == null) { fastOutSlowIn = AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in); @@ -61,11 +56,11 @@ final public void set(T object, Float value) { * An extension to {@link ColorMatrix} which caches the saturation value for animation * purposes. */ - public static class ObservableColorMatrix extends ColorMatrix { + static class ObservableColorMatrix extends ColorMatrix { private float saturation = 1f; - public ObservableColorMatrix() { + ObservableColorMatrix() { super(); } @@ -79,7 +74,7 @@ public void setSaturation(float saturation) { super.setSaturation(saturation); } - public static final Property SATURATION + static final Property SATURATION = new FloatProperty("saturation") { @Override diff --git a/app/src/main/java/us/koller/cameraroll/util/ColorFade.java b/app/src/main/java/us/koller/cameraroll/util/ColorFade.java index 1605ff97..42baedf3 100644 --- a/app/src/main/java/us/koller/cameraroll/util/ColorFade.java +++ b/app/src/main/java/us/koller/cameraroll/util/ColorFade.java @@ -7,6 +7,7 @@ import android.animation.ValueAnimator; import android.graphics.Color; import android.graphics.ColorMatrixColorFilter; +import android.os.Build; import android.support.v4.content.ContextCompat; import android.support.v7.widget.Toolbar; import android.view.View; @@ -64,7 +65,9 @@ public void onAnimationUpdate(ValueAnimator valueAnimator) { } }); saturation.setDuration(2000L); - saturation.setInterpolator(AnimUtils.getFastOutSlowInInterpolator(imageView.getContext())); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + saturation.setInterpolator(AnimUtils.getFastOutSlowInInterpolator(imageView.getContext())); + } saturation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { diff --git a/app/src/main/java/us/koller/cameraroll/util/ItemViewUtil.java b/app/src/main/java/us/koller/cameraroll/util/ItemViewUtil.java index 34189137..b4230a7f 100644 --- a/app/src/main/java/us/koller/cameraroll/util/ItemViewUtil.java +++ b/app/src/main/java/us/koller/cameraroll/util/ItemViewUtil.java @@ -2,7 +2,9 @@ import android.app.Activity; import android.graphics.Bitmap; +import android.os.Build; import android.os.Handler; +import android.support.annotation.RequiresApi; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -65,15 +67,20 @@ public static View bindTransitionView(final ImageView imageView, Util.getVideoDimensions(albumItem.getPath()) : Util.getImageDimensions(imageView.getContext(), albumItem.getPath()); - int screenWidth = Util.getScreenWidth((Activity) imageView.getContext()); - float scale = ((float) screenWidth) / (float) imageDimens[0]; - scale = scale > 1.0f ? 1.0f : scale == 0.0f ? 1.0f : scale; - imageDimens[0] = - (int) (imageDimens[0] * scale * 0.5f) > 0 - ? (int) (imageDimens[0] * scale * 0.5f) : 1; - imageDimens[1] = - (int) (imageDimens[1] * scale * 0.5f) > 0 - ? (int) (imageDimens[1] * scale * 0.5f) : 1; + if (imageView.getContext() instanceof Activity) { + int screenWidth = Util.getScreenWidth((Activity) imageView.getContext()); + float scale = ((float) screenWidth) / (float) imageDimens[0]; + scale = scale > 1.0f ? 1.0f : scale == 0.0f ? 1.0f : scale; + imageDimens[0] = + (int) (imageDimens[0] * scale * 0.5f) > 0 + ? (int) (imageDimens[0] * scale * 0.5f) : 1; + imageDimens[1] = + (int) (imageDimens[1] * scale * 0.5f) > 0 + ? (int) (imageDimens[1] * scale * 0.5f) : 1; + } else { + imageDimens[0] = imageDimens[0] / 2; + imageDimens[1] = imageDimens[1] / 2; + } Glide.with(imageView.getContext()) .load(albumItem.getPath()) @@ -93,7 +100,7 @@ public boolean onException(Exception e, String model, public boolean onResourceReady(Bitmap resource, String model, Target target, boolean isFromMemoryCache, boolean isFirstResource) { - if (albumItem.isSharedElement) { + if (albumItem.isSharedElement && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { albumItem.isSharedElement = false; ((ItemActivity) imageView.getContext()).startPostponedEnterTransition(); } @@ -102,14 +109,17 @@ public boolean onResourceReady(Bitmap resource, String model, }) .into(imageView); - //Handle timeout - imageView.setTransitionName(albumItem.getPath()); - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - ((ItemActivity) imageView.getContext()).startPostponedEnterTransition(); - } - }, 200); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + //Handle timeout + imageView.setTransitionName(albumItem.getPath()); + new Handler().postDelayed(new Runnable() { + @Override + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public void run() { + ((ItemActivity) imageView.getContext()).startPostponedEnterTransition(); + } + }, 200); + } return imageView; } @@ -141,7 +151,9 @@ public boolean onResourceReady(GifDrawable resource, String model, } }) .into(imageView); - imageView.setTransitionName(albumItem.getPath()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + imageView.setTransitionName(albumItem.getPath()); + } return imageView; } @@ -166,7 +178,10 @@ public static ViewGroup bindImageViewForVideo(final ImageView imageView, .skipMemoryCache(true) .error(R.drawable.error_placeholder_tinted) .into(imageView); - imageView.setTransitionName(albumItem.getPath()); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + imageView.setTransitionName(albumItem.getPath()); + } ImageView playButton = new ImageView(imageView.getContext()); playButton.setTag(VIDEO_PLAY_BUTTON_TAG); diff --git a/app/src/main/java/us/koller/cameraroll/util/Util.java b/app/src/main/java/us/koller/cameraroll/util/Util.java index 2a835b95..f86b341d 100644 --- a/app/src/main/java/us/koller/cameraroll/util/Util.java +++ b/app/src/main/java/us/koller/cameraroll/util/Util.java @@ -7,6 +7,7 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.media.MediaMetadataRetriever; @@ -21,6 +22,7 @@ import android.util.DisplayMetrics; import android.util.Log; import android.view.View; +import android.view.Window; import android.widget.TextView; import android.widget.Toast; @@ -139,4 +141,27 @@ public static void colorToolbarOverflowMenuIcon(Toolbar toolbar, int color) { toolbar.setOverflowIcon(drawable); } } + + private static Drawable selectorOverlay; + + public static Drawable getAlbumItemSelectorOverlay(Context context) { + if (selectorOverlay == null) { + selectorOverlay = ContextCompat.getDrawable(context, + R.drawable.albumitem_selected_indicator); + selectorOverlay = DrawableCompat.wrap(selectorOverlay); + DrawableCompat.setTint(selectorOverlay, + ContextCompat.getColor(context, + R.color.colorAccent_translucent)); + } + return selectorOverlay; + } + + //int[left, top, right, bottom] + public static int[] getScreenSize(Activity context) { + Rect displayRect = new Rect(); + context.getWindow().getDecorView().getWindowVisibleDisplayFrame(displayRect); + return new int[]{ + displayRect.left, displayRect.top, + displayRect.right, displayRect.bottom}; + } } diff --git a/app/src/main/java/us/koller/cameraroll/util/ZoomOutPageTransformer.java b/app/src/main/java/us/koller/cameraroll/util/ZoomOutPageTransformer.java new file mode 100644 index 00000000..7fcd814a --- /dev/null +++ b/app/src/main/java/us/koller/cameraroll/util/ZoomOutPageTransformer.java @@ -0,0 +1,44 @@ +package us.koller.cameraroll.util; + +import android.support.v4.view.ViewPager; +import android.view.View; + +//heavily by: https://developer.android.com/training/animation/screen-slide.html#pagetransformer +public class ZoomOutPageTransformer implements ViewPager.PageTransformer { + private static final float MIN_SCALE = 0.85f; + private static final float MIN_ALPHA = 0.5f; + + public void transformPage(View view, float position) { + int pageWidth = view.getWidth(); + int pageHeight = view.getHeight(); + + if (position < -1) { // [-Infinity,-1) + // This page is way off-screen to the left. + view.setAlpha(0); + + } else if (position <= 1) { // [-1,1] + // Modify the default slide transition to shrink the page as well + float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)); + float vertMargin = pageHeight * (1 - scaleFactor) / 2; + float horzMargin = pageWidth * (1 - scaleFactor) / 2; + if (position < 0) { + view.setTranslationX(horzMargin - vertMargin / 2); + } else { + view.setTranslationX(-horzMargin + vertMargin / 2); + } + + // Scale the page down (between MIN_SCALE and 1) + view.setScaleX(scaleFactor); + view.setScaleY(scaleFactor); + + // Fade the page relative to its size. + view.setAlpha(MIN_ALPHA + + (scaleFactor - MIN_SCALE) / + (1 - MIN_SCALE) * (1 - MIN_ALPHA)); + + } else { // (1,+Infinity] + // This page is way off-screen to the right. + view.setAlpha(0); + } + } +} diff --git a/app/src/main/res/animator/albumitem_foreground.xml b/app/src/main/res/animator/albumitem_foreground.xml index 5ae93783..5202ff76 100644 --- a/app/src/main/res/animator/albumitem_foreground.xml +++ b/app/src/main/res/animator/albumitem_foreground.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 00000000..cd197267 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_arrow_back_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_arrow_back_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 00000000..4ef72eec Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_arrow_back_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 00000000..832f5a36 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_arrow_back_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_share_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_share_white_24dp.png new file mode 100644 index 00000000..22a8783e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_share_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png new file mode 100644 index 00000000..32a6d91c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_arrow_back_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_share_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_share_white_24dp.png new file mode 100644 index 00000000..a35b3cd1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_share_white_24dp.png differ diff --git a/app/src/main/res/drawable/ic_delete_white_24dp.png b/app/src/main/res/drawable/ic_delete_white_24dp.png deleted file mode 100644 index 8d322aa9..00000000 Binary files a/app/src/main/res/drawable/ic_delete_white_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable/ic_info_white_24dp.png b/app/src/main/res/drawable/ic_info_white_24dp.png deleted file mode 100644 index 7d11d1ea..00000000 Binary files a/app/src/main/res/drawable/ic_info_white_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable/ic_mode_edit_white_24dp.png b/app/src/main/res/drawable/ic_mode_edit_white_24dp.png deleted file mode 100644 index d6668a05..00000000 Binary files a/app/src/main/res/drawable/ic_mode_edit_white_24dp.png and /dev/null differ diff --git a/app/src/main/res/layout-v21/activity_file_explorer.xml b/app/src/main/res/layout-v21/activity_file_explorer.xml new file mode 100644 index 00000000..6d67957d --- /dev/null +++ b/app/src/main/res/layout-v21/activity_file_explorer.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-v21/recycler_view_layout.xml b/app/src/main/res/layout-v21/recycler_view_layout.xml new file mode 100644 index 00000000..03033e49 --- /dev/null +++ b/app/src/main/res/layout-v21/recycler_view_layout.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index d8abbf78..e39779b0 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -3,7 +3,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/swipeBackView" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:fitsSystemWindows="@bool/belowLollipop"> + android:background="@color/dark_bg" + android:fitsSystemWindows="@bool/belowLollipop"> diff --git a/app/src/main/res/layout/activity_file_explorer.xml b/app/src/main/res/layout/activity_file_explorer.xml index 6d67957d..c100bf04 100644 --- a/app/src/main/res/layout/activity_file_explorer.xml +++ b/app/src/main/res/layout/activity_file_explorer.xml @@ -4,7 +4,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/swipeBackView" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:fitsSystemWindows="@bool/belowLollipop"> + android:layout_height="wrap_content"/> + + android:layout_height="match_parent" + android:fitsSystemWindows="@bool/belowLollipop"> \ No newline at end of file diff --git a/app/src/main/res/layout/albumitem_cover.xml b/app/src/main/res/layout/albumitem_cover.xml index d038bf3b..c18a8cb0 100644 --- a/app/src/main/res/layout/albumitem_cover.xml +++ b/app/src/main/res/layout/albumitem_cover.xml @@ -9,8 +9,8 @@ android:id="@+id/image" android:layout_height="match_parent" android:layout_width="match_parent" - android:foreground="@animator/albumitem_foreground" android:contentDescription="@string/photo" + android:foreground="@animator/albumitem_foreground" android:scaleType="centerCrop"/> - + android:background="@android:color/transparent"> + android:background="@drawable/transparent_to_dark_gradient" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:paddingBottom="16dp"> + + - \ No newline at end of file + + diff --git a/app/src/main/res/layout/recycler_view_layout.xml b/app/src/main/res/layout/recycler_view_layout.xml index 03033e49..cef3824e 100644 --- a/app/src/main/res/layout/recycler_view_layout.xml +++ b/app/src/main/res/layout/recycler_view_layout.xml @@ -16,7 +16,5 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/toolbar" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:stateListAnimator="@animator/toolbar_raise" - android:transitionName="@string/toolbar_transition_name"/> + android:layout_height="wrap_content"/> diff --git a/app/src/main/res/layout/simple_spinner_dropdown_item.xml b/app/src/main/res/layout/simple_spinner_dropdown_item.xml deleted file mode 100644 index 54fa6280..00000000 --- a/app/src/main/res/layout/simple_spinner_dropdown_item.xml +++ /dev/null @@ -1,10 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/layout/simple_spinner_item.xml b/app/src/main/res/layout/simple_spinner_item.xml deleted file mode 100644 index 48a54ed2..00000000 --- a/app/src/main/res/layout/simple_spinner_item.xml +++ /dev/null @@ -1,10 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/values-land/styles.xml b/app/src/main/res/values-land/styles.xml deleted file mode 100644 index 66e1dfe8..00000000 --- a/app/src/main/res/values-land/styles.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - diff --git a/app/src/main/res/values-v21/bools.xml b/app/src/main/res/values-v21/bools.xml new file mode 100644 index 00000000..7a8470f1 --- /dev/null +++ b/app/src/main/res/values-v21/bools.xml @@ -0,0 +1,4 @@ + + + true + \ No newline at end of file diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml new file mode 100644 index 00000000..7161d0f8 --- /dev/null +++ b/app/src/main/res/values-v21/styles.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/bools.xml b/app/src/main/res/values/bools.xml index 7ca8f2ec..81fcd068 100644 --- a/app/src/main/res/values/bools.xml +++ b/app/src/main/res/values/bools.xml @@ -2,4 +2,5 @@ false true + true \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d941d3ed..2fc04e17 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -3,13 +3,6 @@ @color/colorPrimary @color/colorPrimaryDark @color/colorAccent - - @bool/show_nav_bar - @android:color/transparent - - true - - true