Merge upstream redesign (#714)
* merge toolbar fragment * Fix store screenshot generator * Fix alert color * Fix #609 * Fix crash * bigger hitbox for chips * support mastodon languages * merge ui utils * merge stuff * fix icon * ensure 48dp touch target * init local prefs, add helper function for enum values * update compose action layout * merge compose-adj files * update extended footer * fix poll wrong option checked closes sk22#641 * no border when disabled closes sk22#640 * Fix #610 * Minor fixes * Fix alert color * Fix #609 * Fix crash * Fix #610 * Minor fixes * add resources * more compatible mastodon language * fix html parser * mark as read on refresh * update tab bar * tweak m3 buttons * update compose-adj files * tweak and update styles * m3 expand button * flag icon should be 18dp, actually * More minor fixes closes #612 * More minor fixes closes #612 * Bump version * fix no create status event when redrafting * add material 3 assets * New translations strings.xml (Greek) * New translations strings.xml (Greek) * New translations strings.xml (Italian) * New translations strings.xml (Greek) * New translations strings.xml (Italian) * New translations strings.xml (Thai) * New translations strings.xml (Thai) * New translations strings.xml (Italian) * New translations strings.xml (Thai) * use new buttons for profile fragment * merge compose fragment * merge all the styles! oh dear * New translations full_description.txt (Indonesian) * New translations full_description.txt (Chinese Simplified) * New translations strings.xml (Chinese Simplified) * New translations full_description.txt (Chinese Simplified) * Fix #615 * Minor fixes * Fix #611 * A bunch of crash fixes * New translations strings.xml (Greek) * Make the default server configurable * Pass the system timezone to server when signing up * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Japanese) * Fix #615 * Minor fixes * Fix #611 * A bunch of crash fixes * Make the default server configurable * Pass the system timezone to server when signing up * oops. accidentally pasted the commit message in the code * Remove unused code that caused a crash for some users ¯\_(ツ)_/¯ * New translations strings.xml (Japanese) * New translations strings.xml (Japanese) * Remove unused code that caused a crash for some users ¯\_(ツ)_/¯ * New translations strings.xml (Polish) * New translations strings.xml (Polish) * New translations strings.xml (Turkish) * New translations strings.xml (Belarusian) * prepare merging profile fragment * merge profile fragment * New translations strings.xml (Belarusian) * New translations strings.xml (Greek) * fix icon padding * apply post header changes * minor margin tweaks * fix footer buttons * fix header announcement buttons * New translations strings.xml (Japanese) * New translations strings.xml (Japanese) * New translations strings.xml (Japanese) * New translations strings.xml (Japanese) * New translations strings.xml (Japanese) * New translations strings.xml (Japanese) * New translations full_description.txt (Japanese) * New translations strings.xml (Icelandic) * New translations strings.xml (Icelandic) * New translations strings.xml (Icelandic) * fix replying * New translations strings.xml (Icelandic) * fix translate button * fix more button visibility * fix counts label styling * fix disabled boost button opacity * fix tab layouts * fix notification icon color crash * New translations strings.xml (Greek) * implement elevation listener in home tab * fix elevation and listener in home tab * add elevation scroll listener to notifications * New translations strings.xml (Scottish Gaelic) * Add editorconfig So that PRs like #625 don't happen again * Crash fix * 🤔 * New translations strings.xml (Greek) * New translations strings.xml (Japanese) * New translations strings.xml (French) * New translations strings.xml (French) * New translations strings.xml (French) * fix notification elevation and integrate divider * 🤔 * Crash fix * Add editorconfig So that PRs like #625 don't happen again * New translations strings.xml (Turkish) * save interactions in cache * New translations strings.xml (Turkish) * merge new discover/search * New translations strings.xml (Bengali) * New translations strings.xml (Scottish Gaelic) * New translations strings.xml (Bengali) * merge new settings fragments * fix no auth callback always being executed * allow opening server info from profile closes sk22#593 * fix hide boosts icon color closes sk22#676 * New translations strings.xml (Turkish) * New translations strings.xml (Turkish) * New translations strings.xml (Turkish) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (Turkish) * New translations strings.xml (Chinese Simplified) * New translations strings.xml (German) * New translations strings.xml (German) * New translations strings.xml (Turkish) * update fedinuke list from source; doesn't contain any modifications regarding a recent issue * New translations strings.xml (Turkish) * remove unused class * fix crash * darken m3 outline color a bit * use m3 outline again * fix misalignment closes sk22#682 * New translations strings.xml (Turkish) * New translations full_description.txt (Turkish) * New translations short_description.txt (Turkish) * fix crash * fix metadata sorting * show pronouns in header/account lists * fix broken divider line closes sk22#679 * trim pronouns * improve pronoun display * New translations strings.xml (French) * New translations strings.xml (Japanese) * fix broken federated timeline closes sk22#685 * fix broken -1 fallback behavior closes sk22#681 * don't display nothing if server about request fails closes sk22#678 * New translations strings.xml (Ukrainian) * migrate global prefs to local prefs * do confirm unfollow by default * New translations strings.xml (Ukrainian) * New translations strings.xml (Ukrainian) * New translations full_description.txt (Ukrainian) * New translations strings.xml (Ukrainian) * New translations strings.xml (Ukrainian) * New translations strings.xml (Ukrainian) * New translations strings.xml (Ukrainian) * New translations strings.xml (Ukrainian) * New translations strings.xml (Russian) * New translations strings.xml (Vietnamese) * New translations strings.xml (Ukrainian) * New translations strings.xml (Vietnamese) * New translations full_description.txt (Ukrainian) * New translations strings.xml (Ukrainian) * New translations strings.xml (Vietnamese) * New translations strings.xml (Ukrainian) * New translations strings.xml (Ukrainian) * make sure list in prefs are always mutable and nut null * New translations strings.xml (Ukrainian) * New translations strings.xml (Ukrainian) * New translations strings.xml (Russian) * fix pronouns edge case * add back fix for stretched images closes sk22#636 * fix null pointer on missing default posting language * fix default posting language not being applied * bigger username hitbox closes sk22#688 * fix rtl header username alignment closes sk22#689 * New translations strings.xml (Ukrainian) * New translations strings.xml (Ukrainian) * hopefully fix crashes closes sk22#692 * New translations strings.xml (Ukrainian) * New translations full_description.txt (Ukrainian) * fix pronoun crash * New translations strings.xml (Persian) * New translations strings.xml (Ukrainian) * re-add true black mode * asterisk can be a pronoun * New translations strings.xml (Persian) * true black mode fixes and clean-ups * material 3 button background for switcher * darker tab bar selected background * better align follow/following button widths * restore rainbow refresh colors * fix search transition * fix min width issue with switcher button * fix no elevation when true black is enabled in light theme * use statusForContent to determine spoilerRevealed closes sk22#694 * New translations strings.xml (Persian) * New translations strings.xml (Persian) * New translations strings.xml (Persian) * New translations strings.xml (Persian) * New translations strings.xml (Persian) * New translations strings.xml (Persian) * fix profile tab bar in true black theme * fix m3 default button style closes sk22#697 * prettier role badges closes sk22#663 * fix translate button spacing closes sk22#655 * use m3 switches in dialogs closes sk22#653 * implement color palette switcher * fix color palettes being overwritten * add display and notification settings * clean up code * per-account single notification setting * add missing items to notification types * add prefix replies setting * add show replies/boosts and reply visibility * add load/see new posts settings * fix spectator mode missing spoiler padding * add a bunch of display settings * update fedinuke * add content type settings * add settings for local-onlu * add missing settings items * fix visibility button icon tint * hopefully fix some crashes * normalize padding above edit text * apparently, some people don't like pills closes sk22#706 * fix play button color closes sk22#705
This commit is contained in:
@@ -5,7 +5,7 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.view.View;
|
||||
@@ -26,15 +26,21 @@ import me.grishka.appkit.views.FragmentRootLinearLayout;
|
||||
public class ElevationOnScrollListener extends RecyclerView.OnScrollListener implements View.OnScrollChangeListener{
|
||||
private boolean isAtTop;
|
||||
private Animator currentPanelsAnim;
|
||||
private View[] views;
|
||||
private List<View> views;
|
||||
private View divider;
|
||||
private FragmentRootLinearLayout fragmentRootLayout;
|
||||
private Rect tmpRect=new Rect();
|
||||
|
||||
public ElevationOnScrollListener(FragmentRootLinearLayout fragmentRootLayout, View... views){
|
||||
this(fragmentRootLayout, Arrays.asList(views));
|
||||
}
|
||||
|
||||
public ElevationOnScrollListener(FragmentRootLinearLayout fragmentRootLayout, List<View> views){
|
||||
isAtTop=true;
|
||||
this.fragmentRootLayout=fragmentRootLayout;
|
||||
this.views=views;
|
||||
for(View v:views){
|
||||
Drawable bg=v.getBackground().mutate();
|
||||
Drawable bg=v.getContext().getDrawable(R.drawable.bg_onboarding_panel).mutate();
|
||||
v.setBackground(bg);
|
||||
if(bg instanceof LayerDrawable ld){
|
||||
Drawable overlay=ld.findDrawableByLayerId(R.id.color_overlay);
|
||||
@@ -45,13 +51,21 @@ public class ElevationOnScrollListener extends RecyclerView.OnScrollListener imp
|
||||
}
|
||||
}
|
||||
|
||||
public void setDivider(View divider) {
|
||||
this.divider = divider;
|
||||
}
|
||||
|
||||
public void setViews(View... views){
|
||||
List<View> oldViews=Arrays.asList(this.views);
|
||||
setViews(Arrays.asList(views));
|
||||
}
|
||||
|
||||
public void setViews(List<View> views){
|
||||
List<View> oldViews=this.views;
|
||||
this.views=views;
|
||||
for(View v:views){
|
||||
if(oldViews.contains(v))
|
||||
continue;
|
||||
Drawable bg=v.getBackground().mutate();
|
||||
Drawable bg=v.getContext().getDrawable(R.drawable.bg_onboarding_panel).mutate();
|
||||
v.setBackground(bg);
|
||||
if(bg instanceof LayerDrawable ld){
|
||||
Drawable overlay=ld.findDrawableByLayerId(R.id.color_overlay);
|
||||
@@ -63,9 +77,14 @@ public class ElevationOnScrollListener extends RecyclerView.OnScrollListener imp
|
||||
}
|
||||
}
|
||||
|
||||
private int getRecyclerChildDecoratedTop(RecyclerView rv, View child){
|
||||
rv.getDecoratedBoundsWithMargins(child, tmpRect);
|
||||
return tmpRect.top;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){
|
||||
boolean newAtTop=recyclerView.getChildCount()==0 || (recyclerView.getChildAdapterPosition(recyclerView.getChildAt(0))==0 && recyclerView.getChildAt(0).getTop()==recyclerView.getPaddingTop());
|
||||
boolean newAtTop=recyclerView.getChildCount()==0 || (recyclerView.getChildAdapterPosition(recyclerView.getChildAt(0))==0 && getRecyclerChildDecoratedTop(recyclerView, recyclerView.getChildAt(0))==recyclerView.getPaddingTop());
|
||||
handleScroll(recyclerView.getContext(), newAtTop);
|
||||
}
|
||||
|
||||
@@ -74,7 +93,8 @@ public class ElevationOnScrollListener extends RecyclerView.OnScrollListener imp
|
||||
handleScroll(v.getContext(), scrollY<=0);
|
||||
}
|
||||
|
||||
private void handleScroll(Context context, boolean newAtTop){
|
||||
public void handleScroll(Context context, boolean newAtTop){
|
||||
if(UiUtils.isTrueBlackTheme()) newAtTop=true;
|
||||
if(newAtTop!=isAtTop){
|
||||
isAtTop=newAtTop;
|
||||
if(currentPanelsAnim!=null)
|
||||
@@ -86,20 +106,23 @@ public class ElevationOnScrollListener extends RecyclerView.OnScrollListener imp
|
||||
if(v.getBackground() instanceof LayerDrawable ld){
|
||||
Drawable overlay=ld.findDrawableByLayerId(R.id.color_overlay);
|
||||
if(overlay!=null){
|
||||
anims.add(ObjectAnimator.ofInt(overlay, "alpha", isAtTop ? 0 : 20));
|
||||
anims.add(ObjectAnimator.ofInt(overlay, "alpha", newAtTop ? 0 : 20));
|
||||
}
|
||||
}
|
||||
anims.add(ObjectAnimator.ofFloat(v, View.TRANSLATION_Z, isAtTop ? 0 : V.dp(3)));
|
||||
anims.add(ObjectAnimator.ofFloat(v, View.TRANSLATION_Z, newAtTop ? 0 : V.dp(3)));
|
||||
}
|
||||
if(fragmentRootLayout!=null){
|
||||
int color;
|
||||
if(isAtTop){
|
||||
color=UiUtils.getThemeColor(context, R.attr.toolbarBackground);
|
||||
if(newAtTop){
|
||||
color=UiUtils.getThemeColor(context, R.attr.colorM3Background);
|
||||
}else{
|
||||
color=UiUtils.alphaBlendColors(UiUtils.getThemeColor(context, R.attr.toolbarBackground), UiUtils.getThemeColor(context, R.attr.colorWindowBackground), 0.07843137f);
|
||||
color=UiUtils.alphaBlendColors(UiUtils.getThemeColor(context, R.attr.colorM3Background), UiUtils.getThemeColor(context, R.attr.colorM3Primary), 0.07843137f);
|
||||
}
|
||||
anims.add(ObjectAnimator.ofArgb(fragmentRootLayout, "statusBarColor", color));
|
||||
}
|
||||
if(divider!=null){
|
||||
anims.add(ObjectAnimator.ofFloat(divider, View.ALPHA, newAtTop ? 1 : 0));
|
||||
}
|
||||
set.playTogether(anims);
|
||||
set.setDuration(150);
|
||||
set.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
@@ -113,4 +136,8 @@ public class ElevationOnScrollListener extends RecyclerView.OnScrollListener imp
|
||||
currentPanelsAnim=set;
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentStatusBarColor(){
|
||||
return fragmentRootLayout.getStatusBarColor();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,14 @@ package org.joinmastodon.android.utils;
|
||||
|
||||
import static org.joinmastodon.android.api.MastodonAPIController.gson;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Build;
|
||||
import android.os.LocaleList;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.model.Instance;
|
||||
import org.parceler.Parcel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -16,8 +18,10 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Parcel
|
||||
public class MastodonLanguage {
|
||||
// On an up-to-date Mastodon instance:
|
||||
// copy(JSON.stringify(JSON.stringify(JSON.parse(document.getElementById('initial-state').textContent).languages)))
|
||||
@@ -50,10 +54,12 @@ public class MastodonLanguage {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public final String languageTag, name, englishName;
|
||||
public final Locale locale;
|
||||
public String languageTag, name, englishName;
|
||||
public Locale locale;
|
||||
|
||||
private MastodonLanguage(String languageTag, String englishName, String name) {
|
||||
protected MastodonLanguage() {}
|
||||
|
||||
protected MastodonLanguage(String languageTag, String englishName, String name) {
|
||||
this.locale = new Locale(languageTag);
|
||||
this.languageTag = languageTag.toLowerCase(Locale.ROOT);
|
||||
this.name = name;
|
||||
@@ -69,6 +75,10 @@ public class MastodonLanguage {
|
||||
|
||||
public String getLanguage() { return languageTag; }
|
||||
|
||||
public String getDisplayName(Context context) {
|
||||
return context.getString(R.string.sk_language_name, getDefaultName(), getLanguageName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -91,14 +101,18 @@ public class MastodonLanguage {
|
||||
.orElse(ENGLISH);
|
||||
}
|
||||
|
||||
public MastodonLanguage from(String language) {
|
||||
public MastodonLanguage fromOrFallback(String language) {
|
||||
return from(language).orElse(fallbackLanguage);
|
||||
}
|
||||
|
||||
public Optional<MastodonLanguage> from(String language) {
|
||||
return allLanguages.stream()
|
||||
.filter(l->l.locale.equals(new Locale(language))).findAny()
|
||||
.orElse(fallbackLanguage);
|
||||
.filter(l->l.locale.equals(new Locale(language)))
|
||||
.findAny();
|
||||
}
|
||||
|
||||
public MastodonLanguage getDefault() {
|
||||
return from(Locale.getDefault().getLanguage());
|
||||
return fromOrFallback(Locale.getDefault().getLanguage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.joinmastodon.android.utils;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class ObjectIdComparator implements Comparator<String>{
|
||||
public static final ObjectIdComparator INSTANCE=new ObjectIdComparator();
|
||||
|
||||
@Override
|
||||
public int compare(String o1, String o2){
|
||||
int l1=o1==null ? 0 : o1.length();
|
||||
int l2=o2==null ? 0 : o2.length();
|
||||
if(l1!=l2)
|
||||
return Integer.compare(l1, l2);
|
||||
if(l1==0)
|
||||
return 0;
|
||||
return o1.compareTo(o2);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package org.joinmastodon.android.utils;
|
||||
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.model.Filter;
|
||||
import org.joinmastodon.android.model.LegacyFilter;
|
||||
import org.joinmastodon.android.model.FilterAction;
|
||||
import org.joinmastodon.android.model.FilterContext;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import java.time.Instant;
|
||||
@@ -12,24 +14,24 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class StatusFilterPredicate implements Predicate<Status>{
|
||||
private final List<Filter> filters;
|
||||
private final Filter.FilterContext context;
|
||||
private final Filter.FilterAction action;
|
||||
private Filter applyingFilter;
|
||||
private final List<LegacyFilter> filters;
|
||||
private final FilterContext context;
|
||||
private final FilterAction action;
|
||||
private LegacyFilter applyingFilter;
|
||||
|
||||
/**
|
||||
* @param context null makes the predicate pass automatically
|
||||
* @param action defines what the predicate should check:
|
||||
* status should not be hidden or should not display with warning
|
||||
*/
|
||||
public StatusFilterPredicate(List<Filter> filters, Filter.FilterContext context, Filter.FilterAction action){
|
||||
public StatusFilterPredicate(List<LegacyFilter> filters, FilterContext context, FilterAction action){
|
||||
this.filters = filters;
|
||||
this.context = context;
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public StatusFilterPredicate(List<Filter> filters, Filter.FilterContext context){
|
||||
this(filters, context, Filter.FilterAction.HIDE);
|
||||
public StatusFilterPredicate(List<LegacyFilter> filters, FilterContext context){
|
||||
this(filters, context, FilterAction.HIDE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +39,7 @@ public class StatusFilterPredicate implements Predicate<Status>{
|
||||
* @param action defines what the predicate should check:
|
||||
* status should not be hidden or should not display with warning
|
||||
*/
|
||||
public StatusFilterPredicate(String accountID, Filter.FilterContext context, Filter.FilterAction action){
|
||||
public StatusFilterPredicate(String accountID, FilterContext context, FilterAction action){
|
||||
filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(context)).collect(Collectors.toList());
|
||||
this.context = context;
|
||||
this.action = action;
|
||||
@@ -46,8 +48,8 @@ public class StatusFilterPredicate implements Predicate<Status>{
|
||||
/**
|
||||
* @param context null makes the predicate pass automatically
|
||||
*/
|
||||
public StatusFilterPredicate(String accountID, Filter.FilterContext context){
|
||||
this(accountID, context, Filter.FilterAction.HIDE);
|
||||
public StatusFilterPredicate(String accountID, FilterContext context){
|
||||
this(accountID, context, FilterAction.HIDE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,26 +62,26 @@ public class StatusFilterPredicate implements Predicate<Status>{
|
||||
public boolean test(Status status){
|
||||
if (context == null) return true;
|
||||
|
||||
Stream<Filter> matchingFilters = status.filtered != null
|
||||
Stream<LegacyFilter> matchingFilters = status.filtered != null
|
||||
// use server-provided per-status info (status.filtered) if available
|
||||
? status.filtered.stream().map(f -> f.filter)
|
||||
// or fall back to cached filters
|
||||
: filters.stream().filter(filter -> filter.matches(status));
|
||||
|
||||
Optional<Filter> applyingFilter = matchingFilters
|
||||
Optional<LegacyFilter> applyingFilter = matchingFilters
|
||||
// discard expired filters
|
||||
.filter(filter -> filter.expiresAt == null || filter.expiresAt.isAfter(Instant.now()))
|
||||
// only apply filters for given context
|
||||
.filter(filter -> filter.context.contains(context))
|
||||
// treating filterAction = null (from filters list) as FilterAction.HIDE
|
||||
.filter(filter -> filter.filterAction == null ? action == Filter.FilterAction.HIDE : filter.filterAction == action)
|
||||
.filter(filter -> filter.filterAction == null ? action == FilterAction.HIDE : filter.filterAction == action)
|
||||
.findAny();
|
||||
|
||||
this.applyingFilter = applyingFilter.orElse(null);
|
||||
return applyingFilter.isEmpty();
|
||||
}
|
||||
|
||||
public Filter getApplyingFilter() {
|
||||
public LegacyFilter getApplyingFilter() {
|
||||
return applyingFilter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.joinmastodon.android.utils;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||
import me.grishka.appkit.imageloader.ViewImageLoader;
|
||||
|
||||
public class ViewImageLoaderHolderTarget implements ViewImageLoader.Target{
|
||||
private final ImageLoaderViewHolder holder;
|
||||
private final int imageIndex;
|
||||
|
||||
public ViewImageLoaderHolderTarget(ImageLoaderViewHolder holder, int imageIndex){
|
||||
this.holder=holder;
|
||||
this.imageIndex=imageIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImageDrawable(Drawable d){
|
||||
if(d==null)
|
||||
holder.clearImage(imageIndex);
|
||||
else
|
||||
holder.setImage(imageIndex, d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(){
|
||||
return ((RecyclerView.ViewHolder)holder).itemView;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user