Skip to content

Commit

Permalink
Apply better coordinatorlayout animation and RTL support.
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-signal committed Jun 2, 2020
1 parent f4a152b commit 6102e9a
Show file tree
Hide file tree
Showing 3 changed files with 254 additions and 50 deletions.
@@ -0,0 +1,129 @@
package org.thoughtcrime.securesms.groups.ui.creategroup;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.TextView;

import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

import com.google.android.material.appbar.AppBarLayout;

import org.thoughtcrime.securesms.R;

import java.lang.ref.WeakReference;

public final class GroupSettingsCoordinatorLayoutBehavior extends CoordinatorLayout.Behavior<View> {

private static final Interpolator INTERPOLATOR = new DecelerateInterpolator();

private final ViewRef avatarTargetRef = new ViewRef(R.id.avatar_target);
private final ViewRef groupNameRef = new ViewRef(R.id.group_name);
private final ViewRef groupNameTargetRef = new ViewRef(R.id.group_name_target);
private final Rect targetRect = new Rect();
private final Rect childRect = new Rect();

public GroupSettingsCoordinatorLayoutBehavior(@NonNull Context context, @Nullable AttributeSet attrs) {
}

@Override
public boolean layoutDependsOn(@NonNull CoordinatorLayout parent, @NonNull View child, @NonNull View dependency) {
return dependency instanceof AppBarLayout;
}

@Override
public boolean onDependentViewChanged(@NonNull CoordinatorLayout parent, @NonNull View child, @NonNull View dependency) {
AppBarLayout appBarLayout = (AppBarLayout) dependency;
int range = appBarLayout.getTotalScrollRange();
float factor = INTERPOLATOR.getInterpolation(-appBarLayout.getY() / range);

updateAvatarPositionAndScale(parent, child, factor);
updateNamePosition(parent, factor);

return true;
}

private void updateAvatarPositionAndScale(@NonNull CoordinatorLayout parent, @NonNull View child, float factor) {
View target = avatarTargetRef.require(parent);

targetRect.set(target.getLeft(), target.getTop(), target.getRight(), target.getBottom());
childRect.set(child.getLeft(), child.getTop(), child.getRight(), child.getBottom());

float widthScale = 1f - (1f - (targetRect.width() / (float) childRect.width())) * factor;
float heightScale = 1f - (1f - (targetRect.height() / (float) childRect.height())) * factor;

float superimposedLeft = childRect.left + (childRect.width() - targetRect.width()) / 2f;
float superimposedTop = childRect.top + (childRect.height() - targetRect.height()) / 2f;

float xTranslation = (targetRect.left - superimposedLeft) * factor;
float yTranslation = (targetRect.top - superimposedTop) * factor;

child.setScaleX(widthScale);
child.setScaleY(heightScale);
child.setTranslationX(xTranslation);
child.setTranslationY(yTranslation);
}

private void updateNamePosition(@NonNull CoordinatorLayout parent, float factor) {
TextView child = (TextView) groupNameRef.require(parent);
View target = groupNameTargetRef.require(parent);

targetRect.set(target.getLeft(), target.getTop(), target.getRight(), target.getBottom());
childRect.set(child.getLeft(), child.getTop(), child.getRight(), child.getBottom());

if (child.getMaxWidth() != targetRect.width()) {
child.setMaxWidth(targetRect.width());
}

float deltaTop = targetRect.top - childRect.top;
float deltaStart = getStart(parent, targetRect) - getStart(parent, childRect);

float yTranslation = deltaTop * factor;
float xTranslation = deltaStart * factor;

child.setTranslationY(yTranslation);
child.setTranslationX(xTranslation);
}

private static int getStart(@NonNull CoordinatorLayout parent, @NonNull Rect rect) {
return parent.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR ? rect.left : rect.right;
}

private static final class ViewRef {

private WeakReference<View> ref = new WeakReference<>(null);

private final @IdRes int idRes;

private ViewRef(@IdRes int idRes) {
this.idRes = idRes;
}

private @NonNull View require(@NonNull View parent) {
View view = ref.get();

if (view == null) {
view = getChildOrThrow(parent, idRes);
ref = new WeakReference<>(view);
}

return view;
}

private static @NonNull View getChildOrThrow(@NonNull View parent, @IdRes int id) {
View child = parent.findViewById(id);

if (child == null) {
throw new AssertionError("Can't find view with ID " + R.id.avatar_target);
} else {
return child;
}
}
}
}
Expand Up @@ -64,6 +64,7 @@ public class ManageGroupFragment extends Fragment {
private View pendingMembersRow;
private TextView pendingMembersCount;
private Toolbar toolbar;
private TextView groupName;
private TextView memberCountUnderAvatar;
private TextView memberCountAboveList;
private AvatarImageView avatar;
Expand Down Expand Up @@ -115,6 +116,7 @@ static ManageGroupFragment newInstance(@NonNull String groupId) {

avatar = view.findViewById(R.id.group_avatar);
toolbar = view.findViewById(R.id.toolbar);
groupName = view.findViewById(R.id.group_name);
memberCountUnderAvatar = view.findViewById(R.id.member_count);
memberCountAboveList = view.findViewById(R.id.member_count_2);
groupMemberList = view.findViewById(R.id.group_members);
Expand Down Expand Up @@ -185,7 +187,7 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
toolbar.inflateMenu(R.menu.manage_group_fragment);

viewModel.getCanEditGroupAttributes().observe(getViewLifecycleOwner(), canEdit -> toolbar.getMenu().findItem(R.id.action_edit).setVisible(canEdit));
viewModel.getTitle().observe(getViewLifecycleOwner(), toolbar::setTitle);
viewModel.getTitle().observe(getViewLifecycleOwner(), groupName::setText);
viewModel.getMemberCountSummary().observe(getViewLifecycleOwner(), memberCountUnderAvatar::setText);
viewModel.getFullMemberCountSummary().observe(getViewLifecycleOwner(), memberCountAboveList::setText);
viewModel.getGroupRecipient().observe(getViewLifecycleOwner(), groupRecipient -> {
Expand Down

0 comments on commit 6102e9a

Please sign in to comment.