Skip to content

Commit

Permalink
now that's what i call a workaround
Browse files Browse the repository at this point in the history
grr why can't the item animator not just properly animate the inset items :(
  • Loading branch information
sk22 committed Jun 22, 2023
1 parent 1c98f74 commit 06bd917
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.CacheablePaginatedResponse;
import org.joinmastodon.android.model.Emoji;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.FilterContext;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Markers;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.Status;
Expand All @@ -47,7 +45,6 @@
import java.util.stream.Stream;

import androidx.recyclerview.widget.RecyclerView;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.SimpleCallback;

public class NotificationsListFragment extends BaseStatusListFragment<Notification>{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.joinmastodon.android.ui.displayitems;

import android.content.Context;
import android.view.ViewGroup;
import android.widget.Space;

import org.joinmastodon.android.fragments.BaseStatusListFragment;

import me.grishka.appkit.utils.V;

public class InsetDummyStatusDisplayItem extends StatusDisplayItem {
private final boolean addTopMargin;

/**
* Helps working around issues regarding animations when revealing/closing spoilers.
* Two usages:
* 1. As the first item of an inset section, to provide the top margin I commented out in
* InsetStatusItemDecoration (which caused inset items to not animate properly).
* 2. As the last item of an inset section, preventing the animated content items to clip out
* of the decoration bounds.
*/
public InsetDummyStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, boolean addTopMargin) {
super(parentID, parentFragment);
this.addTopMargin = addTopMargin;
}

@Override
public Type getType() {
return Type.DUMMY;
}

public static class Holder extends StatusDisplayItem.Holder<InsetDummyStatusDisplayItem> {
public Holder(Context context) {
super(new Space(context));

}

@Override
public void onBind(InsetDummyStatusDisplayItem item) {
// BetterItemAnimator appears not to handle InsetStatusItemDecoration's getItemOffsets
// correctly, causing removed inset views to jump while animating. i don't quite
// understand it, but this workaround appears to work.
// see InsetStatusItemDecoration#getItemOffsets
ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
params.setMargins(0, 0, 0, item.addTopMargin ? V.dp(12) : 0);
itemView.setLayoutParams(params);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public void onBind(SpoilerStatusDisplayItem item){
itemView.getPaddingLeft(),
itemView.getPaddingTop(),
itemView.getPaddingRight(),
item.inset && !item.status.spoilerRevealed ? itemView.getPaddingTop() : 0
item.inset ? itemView.getPaddingTop() : 0
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
Expand Down Expand Up @@ -31,14 +30,12 @@
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.PhotoLayoutHelper;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.utils.StatusFilterPredicate;
import org.parceler.Parcels;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -114,6 +111,7 @@ public static BindableViewHolder<? extends StatusDisplayItem> createViewHolder(T
case SPOILER, FILTER_SPOILER -> new SpoilerStatusDisplayItem.Holder(activity, parent, type);
case SECTION_HEADER -> null; // new SectionHeaderStatusDisplayItem.Holder(activity, parent);
case NOTIFICATION_HEADER -> null; // new NotificationHeaderStatusDisplayItem.Holder(activity, parent);
case DUMMY -> new InsetDummyStatusDisplayItem.Holder(activity);
};
}

Expand Down Expand Up @@ -285,10 +283,14 @@ else if(statusForContent.sensitive && GlobalUserPreferences.alwaysExpandContentW
}
int i=1;
boolean inset=(flags & FLAG_INSET)!=0;
// add inset dummy so last content item doesn't clip out of inset bounds
if (inset) items.add(new InsetDummyStatusDisplayItem(parentID, fragment, false));
for(StatusDisplayItem item:items){
item.inset=inset;
item.index=i++;
}
// add dummy item that provides the missing top margin. workarounds, huh
if (inset) items.add(0, new InsetDummyStatusDisplayItem(parentID, fragment, true));
if(items!=contentItems && !statusForContent.spoilerRevealed){
for(StatusDisplayItem item:contentItems){
item.inset=inset;
Expand Down Expand Up @@ -337,7 +339,8 @@ public enum Type{
SECTION_HEADER,
HEADER_CHECKABLE,
NOTIFICATION_HEADER,
FILTER_SPOILER
FILTER_SPOILER,
DUMMY
}

public static abstract class Holder<T extends StatusDisplayItem> extends BindableViewHolder<T> implements UsableRecyclerView.DisableableClickable{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ public Holder(Activity activity, ViewGroup parent){

@Override
public void onBind(TextStatusDisplayItem item){
boolean hasSpoiler = !TextUtils.isEmpty(item.status.spoilerText);
text.setText(item.translationShown
? HtmlParser.parse(item.status.translation.content, item.status.emojis, item.status.mentions, item.status.tags, item.parentFragment.getAccountID())
: item.text);
Expand Down Expand Up @@ -225,14 +226,18 @@ public void onError(ErrorResponse error) {

if (GlobalUserPreferences.collapseLongPosts && !item.status.textExpandable) {
boolean tooBig = text.getMeasuredHeight() > textMaxHeight;
boolean hasSpoiler = !TextUtils.isEmpty(item.status.spoilerText);
boolean expandable = tooBig && !hasSpoiler;
item.parentFragment.onEnableExpandable(Holder.this, expandable);
}

readMore.setVisibility(item.status.textExpandable && !item.status.textExpanded ? View.VISIBLE : View.GONE);
textScrollView.setLayoutParams(item.status.textExpandable && !item.status.textExpanded ? collapseParams : wrapParams);
if (item.status.textExpandable && !translateVisible) spaceBelowText.setVisibility(View.VISIBLE);

// compensate for spoiler's bottom margin
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) itemView.getLayoutParams();
params.setMargins(params.leftMargin, item.inset && hasSpoiler ? V.dp(-16) : 0,
params.rightMargin, params.bottomMargin);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,12 @@ public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull R
outRect.left=pad;
if(insetRight)
outRect.right=pad;
if(!topSiblingInset)
outRect.top=pad;

// had to comment this out because animations with offsets aren't handled properly.
// can be worked around by manually applying top margins to items
// see InsetDummyStatusDisplayItem#onBinds
// if(!topSiblingInset)
// outRect.top=pad;
if(!bottomSiblingInset)
outRect.bottom=pad;
}
Expand Down

0 comments on commit 06bd917

Please sign in to comment.