diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml index c0e358843..b8c4a22fb 100644 --- a/briar-android/src/main/AndroidManifest.xml +++ b/briar-android/src/main/AndroidManifest.xml @@ -116,7 +116,7 @@ + android:theme="@style/BriarTheme.Transparent.NoActionBar"> diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ImageActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ImageActivity.java index 6c489d710..abdf9cd33 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ImageActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ImageActivity.java @@ -24,6 +24,7 @@ import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BriarActivity; import org.briarproject.briar.android.conversation.glide.GlideApp; +import org.briarproject.briar.android.view.PullDownLayout; import static android.graphics.Color.TRANSPARENT; import static android.os.Build.VERSION.SDK_INT; @@ -37,12 +38,14 @@ import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE; import static java.util.Objects.requireNonNull; import static org.briarproject.briar.android.util.UiUtils.formatDateAbsolute; -public class ImageActivity extends BriarActivity { +public class ImageActivity extends BriarActivity + implements PullDownLayout.Callback { final static String ATTACHMENT = "attachment"; final static String NAME = "name"; final static String DATE = "date"; + private PullDownLayout layout; private AppBarLayout appBarLayout; @Override @@ -64,6 +67,9 @@ public class ImageActivity extends BriarActivity { // inflate layout setContentView(R.layout.activity_image); + layout = findViewById(R.id.layout); + layout.getBackground().setAlpha(255); + layout.setCallback(this); // Status Bar if (SDK_INT >= 21) { @@ -142,6 +148,30 @@ public class ImageActivity extends BriarActivity { } } + @Override + public void onPullStart() { + appBarLayout.animate() + .alpha(0f) + .start(); + } + + @Override + public void onPull(float progress) { + layout.getBackground().setAlpha(Math.round((1 - progress) * 255)); + } + + @Override + public void onPullCancel() { + appBarLayout.animate() + .alpha(1f) + .start(); + } + + @Override + public void onPullComplete() { + supportFinishAfterTransition(); + } + @RequiresApi(api = 16) private void toggleSystemUi() { View decorView = getWindow().getDecorView(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/PullDownLayout.java b/briar-android/src/main/java/org/briarproject/briar/android/view/PullDownLayout.java new file mode 100644 index 000000000..a32659a07 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/PullDownLayout.java @@ -0,0 +1,161 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 XiNGRZ + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.briarproject.briar.android.view; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.support.v4.view.ViewCompat; +import android.support.v4.widget.ViewDragHelper; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.widget.FrameLayout; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +@NotNullByDefault +public class PullDownLayout extends FrameLayout { + + private final ViewDragHelper dragger; + + private final int minimumFlingVelocity; + + @Nullable + private Callback callback; + + public PullDownLayout(Context context) { + this(context, null); + } + + public PullDownLayout(Context context, @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public PullDownLayout(Context context, @Nullable AttributeSet attrs, + int defStyleAttr) { + super(context, attrs, defStyleAttr); + dragger = ViewDragHelper.create(this, 1f / 8f, new ViewDragCallback()); + minimumFlingVelocity = + ViewConfiguration.get(context).getScaledMinimumFlingVelocity(); + } + + public void setCallback(@Nullable Callback callback) { + this.callback = callback; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return dragger.shouldInterceptTouchEvent(ev); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + dragger.processTouchEvent(event); + return true; + } + + @Override + public void computeScroll() { + if (dragger.continueSettling(true)) { + ViewCompat.postInvalidateOnAnimation(this); + } + } + + public interface Callback { + + void onPullStart(); + + void onPull(float progress); + + void onPullCancel(); + + void onPullComplete(); + + } + + private class ViewDragCallback extends ViewDragHelper.Callback { + + @Override + public boolean tryCaptureView(View child, int pointerId) { + return true; + } + + @Override + public int clampViewPositionHorizontal(View child, int left, int dx) { + return 0; + } + + @Override + public int clampViewPositionVertical(View child, int top, int dy) { + return Math.max(0, top); + } + + @Override + public int getViewHorizontalDragRange(View child) { + return 0; + } + + @Override + public int getViewVerticalDragRange(View child) { + return getHeight(); + } + + @Override + public void onViewCaptured(View capturedChild, int activePointerId) { + if (callback != null) { + callback.onPullStart(); + } + } + + @Override + public void onViewPositionChanged(View changedView, int left, int top, + int dx, int dy) { + if (callback != null) { + callback.onPull((float) top / (float) getHeight()); + } + } + + @Override + public void onViewReleased(View releasedChild, float xvel, float yvel) { + int slop = yvel > minimumFlingVelocity ? getHeight() / 6 : + getHeight() / 3; + if (releasedChild.getTop() > slop) { + if (callback != null) { + callback.onPullComplete(); + } + } else { + if (callback != null) { + callback.onPullCancel(); + } + + dragger.settleCapturedViewAt(0, 0); + invalidate(); + } + } + + } + +} diff --git a/briar-android/src/main/res/layout/activity_image.xml b/briar-android/src/main/res/layout/activity_image.xml index 2be562fbd..03fa7f3ca 100644 --- a/briar-android/src/main/res/layout/activity_image.xml +++ b/briar-android/src/main/res/layout/activity_image.xml @@ -1,5 +1,5 @@ - + + - - - + diff --git a/briar-android/src/main/res/values/themes.xml b/briar-android/src/main/res/values/themes.xml index 806783e3a..8f54152ce 100644 --- a/briar-android/src/main/res/values/themes.xml +++ b/briar-android/src/main/res/values/themes.xml @@ -18,6 +18,12 @@ @style/BriarToolbar + +