Attach the reply button y translation to the toolbar collapse

multisite
Floens 10 years ago
parent 4ef7916d68
commit 0566c89093
  1. 3
      Clover/app/src/main/java/org/floens/chan/core/presenter/ImageViewerPresenter.java
  2. 33
      Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java
  3. 27
      Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java
  4. 136
      Clover/app/src/main/java/org/floens/chan/ui/view/HidingFloatingActionButton.java
  5. 5
      Clover/app/src/main/res/layout/layout_thread.xml

@ -25,7 +25,6 @@ import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.PostImage;
import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.ui.view.MultiImageView;
import org.floens.chan.utils.Logger;
import java.util.ArrayList;
import java.util.List;
@ -188,8 +187,6 @@ public class ImageViewerPresenter implements MultiImageView.Callback, ViewPager.
private void onLowResInCenter() {
PostImage postImage = images.get(selectedPosition);
Logger.test("onLowResInCenter " + postImage.imageUrl);
if (imageAutoLoad(postImage) && !postImage.spoiler) {
if (postImage.type == PostImage.Type.STATIC) {
callback.setImageMode(postImage, MultiImageView.Mode.BIGIMAGE);

@ -17,8 +17,6 @@
*/
package org.floens.chan.ui.layout;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
@ -27,14 +25,12 @@ import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
@ -64,6 +60,7 @@ import org.floens.chan.ui.adapter.PostsFilter;
import org.floens.chan.ui.cell.PostCellInterface;
import org.floens.chan.ui.helper.PostPopupHelper;
import org.floens.chan.ui.toolbar.Toolbar;
import org.floens.chan.ui.view.HidingFloatingActionButton;
import org.floens.chan.ui.view.LoadView;
import org.floens.chan.ui.view.ThumbnailView;
import org.floens.chan.utils.AndroidUtils;
@ -92,7 +89,7 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T
private ThreadPresenter presenter;
private LoadView loadView;
private FloatingActionButton replyButton;
private HidingFloatingActionButton replyButton;
private ThreadListLayout threadListLayout;
private LinearLayout errorLayout;
@ -126,10 +123,8 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T
presenter = new ThreadPresenter(this);
loadView = (LoadView) findViewById(R.id.loadview);
replyButton = (FloatingActionButton) findViewById(R.id.reply_button);
replyButton.setOnClickListener(this);
replyButton = (HidingFloatingActionButton) findViewById(R.id.reply_button);
threadListLayout = (ThreadListLayout) LayoutInflater.from(getContext()).inflate(R.layout.layout_thread_list, this, false);
threadListLayout.setCallbacks(presenter, presenter, presenter, presenter, this);
@ -146,6 +141,9 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T
replyButtonEnabled = ChanSettings.enableReplyFab.get();
if (!replyButtonEnabled) {
AndroidUtils.removeFromParentView(replyButton);
} else {
replyButton.setOnClickListener(this);
replyButton.setToolbar(callback.getToolbar());
}
switchVisible(Visible.LOADING);
@ -471,22 +469,11 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T
if (show != showingReplyButton && replyButtonEnabled) {
showingReplyButton = show;
replyButton.animate()
.setInterpolator(new DecelerateInterpolator(2f))
.setStartDelay(show ? 100 : 0)
.setDuration(200)
.alpha(show ? 1f : 0f)
.scaleX(show ? 1f : 0f)
.scaleY(show ? 1f : 0f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
replyButton.setAlpha(show ? 1f : 0f);
replyButton.setScaleX(show ? 1f : 0f);
replyButton.setScaleY(show ? 1f : 0f);
if (show) {
replyButton.show();
} else {
replyButton.hide();
}
})
.start();
}
}

@ -46,6 +46,9 @@ import org.floens.chan.ui.view.FloatingMenu;
import org.floens.chan.ui.view.LoadView;
import org.floens.chan.utils.AndroidUtils;
import java.util.ArrayList;
import java.util.List;
import static org.floens.chan.utils.AndroidUtils.dp;
import static org.floens.chan.utils.AndroidUtils.getAttrColor;
import static org.floens.chan.utils.AndroidUtils.setRoundItemBackground;
@ -83,6 +86,7 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
private boolean openKeyboardAfterSearchViewCreated = false;
private int lastScrollDeltaOffset;
private int scrollOffset;
private List<ToolbarCollapseCallback> collapseCallbacks = new ArrayList<>();
private boolean transitioning = false;
private NavigationItem fromItem;
@ -107,6 +111,14 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
return getHeight() == 0 ? getLayoutParams().height : getHeight();
}
public void addCollapseCallback(ToolbarCollapseCallback callback) {
collapseCallbacks.add(callback);
}
public void removeCollapseCallback(ToolbarCollapseCallback callback) {
collapseCallbacks.remove(callback);
}
public void processScrollCollapse(int offset) {
processScrollCollapse(offset, false);
}
@ -122,9 +134,18 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
if (animated) {
animate().translationY(-scrollOffset).setDuration(300).setInterpolator(new DecelerateInterpolator(2f)).start();
boolean collapse = scrollOffset > 0;
for (ToolbarCollapseCallback c : collapseCallbacks) {
c.onCollapseAnimation(collapse);
}
} else {
animate().cancel();
setTranslationY(-scrollOffset);
for (ToolbarCollapseCallback c : collapseCallbacks) {
c.onCollapseTranslation(scrollOffset / (float) getHeight());
}
}
}
@ -487,4 +508,10 @@ public class Toolbar extends LinearLayout implements View.OnClickListener {
void onSearchEntered(NavigationItem item, String entered);
}
public interface ToolbarCollapseCallback {
void onCollapseTranslation(float offset);
void onCollapseAnimation(boolean collapse);
}
}

@ -0,0 +1,136 @@
/*
* Clover - 4chan browser https://github.com/Floens/Clover/
* Copyright (C) 2014 Floens
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.floens.chan.ui.view;
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import org.floens.chan.ui.toolbar.Toolbar;
public class HidingFloatingActionButton extends FloatingActionButton implements Toolbar.ToolbarCollapseCallback {
private boolean attachedToWindow;
private Toolbar toolbar;
private boolean attachedToToolbar;
private CoordinatorLayout coordinatorLayout;
private int currentCollapseTranslation;
public HidingFloatingActionButton(Context context) {
super(context);
}
public HidingFloatingActionButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HidingFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setToolbar(Toolbar toolbar) {
this.toolbar = toolbar;
if (attachedToWindow && !attachedToToolbar) {
toolbar.addCollapseCallback(this);
attachedToToolbar = true;
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
attachedToWindow = true;
if (!(getParent() instanceof CoordinatorLayout)) {
throw new IllegalArgumentException("HidingFloatingActionButton must be a parent of CoordinatorLayout");
}
coordinatorLayout = (CoordinatorLayout) getParent();
if (toolbar != null && !attachedToToolbar) {
toolbar.addCollapseCallback(this);
attachedToToolbar = true;
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
attachedToWindow = false;
if (attachedToToolbar) {
toolbar.removeCollapseCallback(this);
attachedToToolbar = false;
}
coordinatorLayout = null;
}
@Override
public void onCollapseTranslation(float offset) {
if (isSnackbarShowing()) {
currentCollapseTranslation = -1;
return;
}
// Logger.test("onCollapseTranslation " + offset);
int translation = (int) (getTotalHeight() * offset);
if (translation != currentCollapseTranslation) {
currentCollapseTranslation = translation;
float diff = Math.abs(translation - getTranslationY());
if (diff >= getHeight()) {
animate().translationY(translation).setDuration(300).setStartDelay(0).setInterpolator(new DecelerateInterpolator(2f)).start();
} else {
setTranslationY(translation);
}
}
}
@Override
public void onCollapseAnimation(boolean collapse) {
if (isSnackbarShowing()) {
currentCollapseTranslation = -1;
return;
}
// Logger.test("onCollapseAnimation " + collapse);
int translation = collapse ? getTotalHeight() : 0;
if (translation != currentCollapseTranslation) {
currentCollapseTranslation = translation;
animate().translationY(translation).setDuration(300).setStartDelay(0).setInterpolator(new DecelerateInterpolator(2f)).start();
}
}
private int getTotalHeight() {
return getHeight() + ((ViewGroup.MarginLayoutParams) getLayoutParams()).bottomMargin;
}
private boolean isSnackbarShowing() {
for (int i = 0; i < coordinatorLayout.getChildCount(); i++) {
if (coordinatorLayout.getChildAt(i) instanceof Snackbar.SnackbarLayout) {
return true;
}
}
return false;
}
}

@ -25,15 +25,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.FloatingActionButton
<org.floens.chan.ui.view.HidingFloatingActionButton
android:id="@+id/reply_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_margin="16dp"
android:alpha="0"
android:scaleX="0"
android:scaleY="0"
android:src="@drawable/ic_create_white_24dp"
tools:ignore="RtlHardcoded" />

Loading…
Cancel
Save