Thread fragment tweaks part 2
This commit is contained in:
parent
5c9ad9286d
commit
45cc531eec
|
@ -1,5 +1,8 @@
|
|||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.ClipData;
|
||||
|
@ -90,12 +93,14 @@ import java.util.stream.Collectors;
|
|||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.fragments.CustomTransitionsFragment;
|
||||
import me.grishka.appkit.fragments.OnBackPressedListener;
|
||||
import me.grishka.appkit.imageloader.ViewImageLoader;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class ComposeFragment extends MastodonToolbarFragment implements OnBackPressedListener, ComposeEditText.SelectionListener{
|
||||
public class ComposeFragment extends MastodonToolbarFragment implements OnBackPressedListener, ComposeEditText.SelectionListener, CustomTransitionsFragment{
|
||||
|
||||
private static final int MEDIA_RESULT=717;
|
||||
public static final int IMAGE_DESCRIPTION_RESULT=363;
|
||||
|
@ -1124,4 +1129,35 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||
private void setPostLanguage(ComposeLanguageAlertViewController.SelectedOption language){
|
||||
postLang=language;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator onCreateEnterTransition(View prev, View container){
|
||||
AnimatorSet anim=new AnimatorSet();
|
||||
if(getArguments().getBoolean("fromThreadFragment")){
|
||||
anim.playTogether(
|
||||
ObjectAnimator.ofFloat(container, View.ALPHA, 0f, 1f),
|
||||
ObjectAnimator.ofFloat(container, View.TRANSLATION_Y, V.dp(200), 0)
|
||||
);
|
||||
}else{
|
||||
anim.playTogether(
|
||||
ObjectAnimator.ofFloat(container, View.ALPHA, 0f, 1f),
|
||||
ObjectAnimator.ofFloat(container, View.TRANSLATION_X, V.dp(100), 0)
|
||||
);
|
||||
}
|
||||
anim.setDuration(300);
|
||||
anim.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
return anim;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator onCreateExitTransition(View prev, View container){
|
||||
AnimatorSet anim=new AnimatorSet();
|
||||
anim.playTogether(
|
||||
ObjectAnimator.ofFloat(container, View.TRANSLATION_X, V.dp(100)),
|
||||
ObjectAnimator.ofFloat(container, View.ALPHA, 0)
|
||||
);
|
||||
anim.setDuration(200);
|
||||
anim.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
return anim;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,19 +2,24 @@ package org.joinmastodon.android.fragments;
|
|||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.GlobalUserPreferences;
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.requests.statuses.GetStatusContext;
|
||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||
import org.joinmastodon.android.events.StatusCreatedEvent;
|
||||
import org.joinmastodon.android.model.Account;
|
||||
import org.joinmastodon.android.model.FilterContext;
|
||||
import org.joinmastodon.android.model.LegacyFilter;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.model.StatusContext;
|
||||
import org.joinmastodon.android.ui.OutlineProviders;
|
||||
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.SpoilerStatusDisplayItem;
|
||||
|
@ -26,10 +31,12 @@ import org.parceler.Parcels;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
import me.grishka.appkit.imageloader.ViewImageLoader;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.MergeRecyclerAdapter;
|
||||
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
@ -37,10 +44,16 @@ import me.grishka.appkit.utils.V;
|
|||
public class ThreadFragment extends StatusListFragment{
|
||||
private Status mainStatus;
|
||||
private ImageView endMark;
|
||||
private FrameLayout replyContainer;
|
||||
private LinearLayout replyButton;
|
||||
private ImageView replyButtonAva;
|
||||
private TextView replyButtonText;
|
||||
private int lastBottomInset;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
setLayout(R.layout.fragment_thread);
|
||||
mainStatus=Parcels.unwrap(getArguments().getParcelable("status"));
|
||||
Account inReplyToAccount=Parcels.unwrap(getArguments().getParcelable("inReplyToAccount"));
|
||||
if(inReplyToAccount!=null)
|
||||
|
@ -126,6 +139,20 @@ public class ThreadFragment extends StatusListFragment{
|
|||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState){
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
replyContainer=view.findViewById(R.id.reply_button_wrapper);
|
||||
replyButton=replyContainer.findViewById(R.id.reply_button);
|
||||
replyButtonText=replyButton.findViewById(R.id.reply_btn_text);
|
||||
replyButtonAva=replyButton.findViewById(R.id.avatar);
|
||||
replyButton.setOutlineProvider(OutlineProviders.roundedRect(20));
|
||||
replyButton.setClipToOutline(true);
|
||||
replyButtonText.setText(getString(R.string.reply_to_user, mainStatus.account.displayName));
|
||||
replyButtonAva.setOutlineProvider(OutlineProviders.OVAL);
|
||||
replyButtonAva.setClipToOutline(true);
|
||||
replyButton.setOnClickListener(v->openReply());
|
||||
Account self=AccountSessionManager.get(accountID).self;
|
||||
if(!TextUtils.isEmpty(self.avatar)){
|
||||
ViewImageLoader.loadWithoutAnimation(replyButtonAva, getResources().getDrawable(R.drawable.image_placeholder), new UrlImageLoaderRequest(self.avatar, V.dp(24), V.dp(24)));
|
||||
}
|
||||
UiUtils.loadCustomEmojiInTextView(toolbarTitleView);
|
||||
showContent();
|
||||
if(!loaded)
|
||||
|
@ -175,4 +202,22 @@ public class ThreadFragment extends StatusListFragment{
|
|||
}
|
||||
super.onErrorRetryClick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplyWindowInsets(WindowInsets insets){
|
||||
lastBottomInset=insets.getSystemWindowInsetBottom();
|
||||
super.onApplyWindowInsets(UiUtils.applyBottomInsetToFixedView(replyContainer, insets));
|
||||
}
|
||||
|
||||
private void openReply(){
|
||||
Bundle args=new Bundle();
|
||||
args.putString("account", accountID);
|
||||
args.putParcelable("replyTo", Parcels.wrap(mainStatus));
|
||||
args.putBoolean("fromThreadFragment", true);
|
||||
Nav.go(getActivity(), ComposeFragment.class, args);
|
||||
}
|
||||
|
||||
public int getSnackbarOffset(){
|
||||
return replyContainer.getHeight()-lastBottomInset;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
package org.joinmastodon.android.ui;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.StringRes;
|
||||
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class Snackbar{
|
||||
private static Snackbar current;
|
||||
|
||||
private final Context context;
|
||||
private int bottomOffset;
|
||||
private FrameLayout windowView;
|
||||
private LinearLayout contentView;
|
||||
private boolean hasAction;
|
||||
private AnimatableOutlineProvider outlineProvider;
|
||||
private Animator currentAnim;
|
||||
private Runnable dismissRunnable=this::dismiss;
|
||||
|
||||
private Snackbar(Context context, String text, String action, Runnable onActionClick, int bottomOffset){
|
||||
this.context=context;
|
||||
this.bottomOffset=bottomOffset;
|
||||
hasAction=onActionClick!=null;
|
||||
|
||||
windowView=new FrameLayout(context);
|
||||
windowView.setClipToPadding(false);
|
||||
contentView=new LinearLayout(context);
|
||||
contentView.setOrientation(LinearLayout.HORIZONTAL);
|
||||
contentView.setBaselineAligned(false);
|
||||
contentView.setBackgroundColor(UiUtils.getThemeColor(context, R.attr.colorM3SurfaceInverse));
|
||||
contentView.setOutlineProvider(outlineProvider=new AnimatableOutlineProvider(contentView));
|
||||
contentView.setClipToOutline(true);
|
||||
contentView.setElevation(V.dp(6));
|
||||
contentView.setPaddingRelative(V.dp(16), 0, V.dp(8), 0);
|
||||
FrameLayout.LayoutParams lp=new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
lp.leftMargin=lp.topMargin=lp.rightMargin=lp.bottomMargin=V.dp(16);
|
||||
windowView.addView(contentView, lp);
|
||||
|
||||
TextView textView=new TextView(context);
|
||||
textView.setTextAppearance(R.style.m3_body_medium);
|
||||
textView.setTextColor(UiUtils.getThemeColor(context, R.attr.colorM3OnSurfaceInverse));
|
||||
textView.setMaxLines(2);
|
||||
textView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
textView.setText(text);
|
||||
textView.setMinHeight(V.dp(48));
|
||||
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
|
||||
textView.setPadding(0, V.dp(14), 0, V.dp(14));
|
||||
contentView.addView(textView, new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
|
||||
|
||||
if(action!=null){
|
||||
Button button=new Button(context);
|
||||
int primaryInverse=UiUtils.getThemeColor(context, R.attr.colorM3PrimaryInverse);
|
||||
button.setTextColor(primaryInverse);
|
||||
button.setBackgroundResource(R.drawable.bg_rect_4dp_ripple);
|
||||
button.setBackgroundTintList(ColorStateList.valueOf(primaryInverse));
|
||||
button.setText(action);
|
||||
button.setPadding(V.dp(8), 0, V.dp(8), 0);
|
||||
button.setOnClickListener(v->onActionClick.run());
|
||||
LinearLayout.LayoutParams blp=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, V.dp(40));
|
||||
blp.leftMargin=blp.topMargin=blp.rightMargin=blp.bottomMargin=V.dp(4);
|
||||
contentView.addView(button, blp);
|
||||
}
|
||||
}
|
||||
|
||||
public void show(){
|
||||
if(current!=null)
|
||||
current.dismiss();
|
||||
current=this;
|
||||
WindowManager.LayoutParams lp=new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, PixelFormat.TRANSLUCENT);
|
||||
lp.width=ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
lp.height=ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
lp.gravity=Gravity.BOTTOM;
|
||||
lp.y=bottomOffset;
|
||||
WindowManager wm=context.getSystemService(WindowManager.class);
|
||||
wm.addView(windowView, lp);
|
||||
windowView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){
|
||||
@Override
|
||||
public boolean onPreDraw(){
|
||||
windowView.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
|
||||
AnimatorSet set=new AnimatorSet();
|
||||
set.playTogether(
|
||||
ObjectAnimator.ofFloat(outlineProvider, "fraction", 0, 1),
|
||||
ObjectAnimator.ofFloat(contentView, View.ALPHA, 0, 1)
|
||||
);
|
||||
set.setInterpolator(AnimationUtils.loadInterpolator(context, R.interpolator.m3_sys_motion_easing_standard_decelerate));
|
||||
set.setDuration(350);
|
||||
set.addListener(new AnimatorListenerAdapter(){
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation){
|
||||
currentAnim=null;
|
||||
}
|
||||
});
|
||||
currentAnim=set;
|
||||
set.start();
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
windowView.postDelayed(dismissRunnable, 4000);
|
||||
}
|
||||
|
||||
public void dismiss(){
|
||||
current=null;
|
||||
if(currentAnim!=null){
|
||||
currentAnim.cancel();
|
||||
}
|
||||
windowView.removeCallbacks(dismissRunnable);
|
||||
ObjectAnimator anim=ObjectAnimator.ofFloat(contentView, View.ALPHA, 0);
|
||||
anim.setInterpolator(CubicBezierInterpolator.DEFAULT);
|
||||
anim.setDuration(200);
|
||||
anim.addListener(new AnimatorListenerAdapter(){
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation){
|
||||
WindowManager wm=context.getSystemService(WindowManager.class);
|
||||
wm.removeView(windowView);
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
}
|
||||
|
||||
private static class AnimatableOutlineProvider extends ViewOutlineProvider{
|
||||
private float fraction=1f;
|
||||
private final View view;
|
||||
|
||||
private AnimatableOutlineProvider(View view){
|
||||
this.view=view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline){
|
||||
outline.setRoundRect(0, Math.round(view.getHeight()*(1f-fraction)), view.getWidth(), view.getHeight(), V.dp(4));
|
||||
}
|
||||
|
||||
@Keep
|
||||
public float getFraction(){
|
||||
return fraction;
|
||||
}
|
||||
|
||||
@Keep
|
||||
public void setFraction(float fraction){
|
||||
this.fraction=fraction;
|
||||
view.invalidateOutline();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder{
|
||||
private final Context context;
|
||||
private String text;
|
||||
private String action;
|
||||
private Runnable onActionClick;
|
||||
private int bottomOffset;
|
||||
|
||||
public Builder(Context context){
|
||||
this.context=context;
|
||||
}
|
||||
|
||||
public Builder setText(String text){
|
||||
this.text=text;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setText(@StringRes int res){
|
||||
text=context.getString(res);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAction(String action, Runnable onActionClick){
|
||||
this.action=action;
|
||||
this.onActionClick=onActionClick;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAction(@StringRes int action, Runnable onActionClick){
|
||||
this.action=context.getString(action);
|
||||
this.onActionClick=onActionClick;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setBottomOffset(int offset){
|
||||
bottomOffset=offset;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Snackbar create(){
|
||||
return new Snackbar(context, text, action, onActionClick, bottomOffset);
|
||||
}
|
||||
|
||||
public void show(){
|
||||
create().show();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,14 +13,17 @@ import android.text.style.TypefaceSpan;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.fragments.StatusEditHistoryFragment;
|
||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||
import org.joinmastodon.android.fragments.account_list.StatusFavoritesListFragment;
|
||||
import org.joinmastodon.android.fragments.account_list.StatusReblogsListFragment;
|
||||
import org.joinmastodon.android.fragments.account_list.StatusRelatedAccountListFragment;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.Snackbar;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
|
@ -34,11 +37,13 @@ import java.util.Locale;
|
|||
import androidx.annotation.PluralsRes;
|
||||
import androidx.annotation.StringRes;
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
|
||||
public final Status status;
|
||||
|
||||
private static final DateTimeFormatter TIME_FORMATTER=DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
|
||||
private static final DateTimeFormatter TIME_FORMATTER_LONG=DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
|
||||
private static final DateTimeFormatter DATE_FORMATTER=DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
|
||||
|
||||
public ExtendedFooterStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Status status){
|
||||
|
@ -160,7 +165,14 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
|
|||
}
|
||||
|
||||
private void showTimeSnackbar(){
|
||||
|
||||
int bottomOffset=0;
|
||||
if(item.parentFragment instanceof ThreadFragment tf){
|
||||
bottomOffset=tf.getSnackbarOffset();
|
||||
}
|
||||
new Snackbar.Builder(itemView.getContext())
|
||||
.setText(itemView.getContext().getString(R.string.posted_at, TIME_FORMATTER_LONG.format(item.status.createdAt.atZone(ZoneId.systemDefault()))))
|
||||
.setBottomOffset(bottomOffset)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/m3_on_surface_overlay">
|
||||
<item android:id="@android:id/mask">
|
||||
<shape>
|
||||
<solid android:color="#000"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<me.grishka.appkit.views.FragmentRootLinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:id="@+id/appkit_loader_root"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="?colorM3Surface">
|
||||
|
||||
<include layout="@layout/appkit_toolbar"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/appkit_loader_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<include layout="@layout/loading"
|
||||
android:id="@+id/loading"/>
|
||||
|
||||
<ViewStub android:layout="?errorViewLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/error"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/content_stub"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:background="?colorM3OutlineVariant"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/reply_button_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_m3_surface2">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/reply_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginVertical="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:background="?colorM3SurfaceVariant"
|
||||
android:foreground="@drawable/bg_rect_4dp_ripple"
|
||||
android:foregroundTint="?colorM3OnSurfaceVariant"
|
||||
android:padding="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/avatar"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reply_btn_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:textAppearance="@style/m3_body_medium"
|
||||
android:textColor="?colorM3OnSurfaceVariant"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
tools:text="Reply to ..."/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</me.grishka.appkit.views.FragmentRootLinearLayout>
|
|
@ -15,7 +15,9 @@
|
|||
<attr name="colorM3Background" format="color"/>
|
||||
<attr name="colorM3OnBackground" format="color"/>
|
||||
<attr name="colorM3Surface" format="color"/>
|
||||
<attr name="colorM3SurfaceInverse" format="color"/>
|
||||
<attr name="colorM3OnSurface" format="color"/>
|
||||
<attr name="colorM3OnSurfaceInverse" format="color"/>
|
||||
<attr name="colorM3SurfaceVariant" format="color"/>
|
||||
<attr name="colorM3OnSurfaceVariant" format="color"/>
|
||||
<attr name="colorM3Outline" format="color"/>
|
||||
|
|
|
@ -656,4 +656,6 @@
|
|||
<string name="manage_list_members">Manage list members</string>
|
||||
<string name="list_no_members">No members yet</string>
|
||||
<string name="list_find_users">Find users to add</string>
|
||||
<string name="reply_to_user">Reply to %s</string>
|
||||
<string name="posted_at">Posted at %s</string>
|
||||
</resources>
|
|
@ -53,6 +53,8 @@
|
|||
<item name="colorM3ErrorContainer">#F9DEDC</item>
|
||||
<item name="colorM3OnErrorContainer">#410E0B</item>
|
||||
<item name="colorM3PrimaryInverse">@color/m3_sys_dark_primary</item>
|
||||
<item name="colorM3SurfaceInverse">@color/m3_sys_dark_surface</item>
|
||||
<item name="colorM3OnSurfaceInverse">@color/m3_sys_dark_on_surface</item>
|
||||
<item name="colorWhite">#FFF</item>
|
||||
<item name="colorFavorite">#8b5000</item>
|
||||
<item name="colorBoost">#ab332a</item>
|
||||
|
@ -120,6 +122,8 @@
|
|||
<item name="colorM3ErrorContainer">#8C1D18</item>
|
||||
<item name="colorM3OnErrorContainer">#F9DEDC</item>
|
||||
<item name="colorM3PrimaryInverse">@color/m3_sys_light_primary</item>
|
||||
<item name="colorM3SurfaceInverse">@color/m3_sys_light_surface</item>
|
||||
<item name="colorM3OnSurfaceInverse">@color/m3_sys_light_on_surface</item>
|
||||
<item name="colorWhite">#000</item>
|
||||
<item name="colorFavorite">#ffb871</item>
|
||||
<item name="colorBoost">#ffb4aa</item>
|
||||
|
|
Loading…
Reference in New Issue