Thread view M3 redesign

This commit is contained in:
Grishka 2023-04-30 23:04:45 +03:00
parent 4b4c88d44d
commit 0434cda2da
11 changed files with 138 additions and 147 deletions

View File

@ -324,6 +324,10 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
c.drawLine(0, y, parent.getWidth(), y, paint); c.drawLine(0, y, parent.getWidth(), y, paint);
} }
protected boolean needDividerForExtraItem(View child, View bottomSibling, RecyclerView.ViewHolder holder, RecyclerView.ViewHolder siblingHolder){
return false;
}
public abstract void onItemClick(String id); public abstract void onItemClick(String id);
protected void updatePoll(String itemID, Status status, Poll poll){ protected void updatePoll(String itemID, Status status, Poll poll){
@ -596,7 +600,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
private Paint dividerPaint=new Paint(); private Paint dividerPaint=new Paint();
{ {
dividerPaint.setColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3Outline)); dividerPaint.setColor(UiUtils.getThemeColor(getActivity(), R.attr.colorM3OutlineVariant));
dividerPaint.setStyle(Paint.Style.STROKE); dividerPaint.setStyle(Paint.Style.STROKE);
dividerPaint.setStrokeWidth(V.dp(0.5f)); dividerPaint.setStrokeWidth(V.dp(0.5f));
} }
@ -608,8 +612,9 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
View bottomSibling=parent.getChildAt(i+1); View bottomSibling=parent.getChildAt(i+1);
RecyclerView.ViewHolder holder=parent.getChildViewHolder(child); RecyclerView.ViewHolder holder=parent.getChildViewHolder(child);
RecyclerView.ViewHolder siblingHolder=parent.getChildViewHolder(bottomSibling); RecyclerView.ViewHolder siblingHolder=parent.getChildViewHolder(bottomSibling);
if(holder instanceof StatusDisplayItem.Holder<?> ih && siblingHolder instanceof StatusDisplayItem.Holder<?> sh if((holder instanceof StatusDisplayItem.Holder<?> ih && siblingHolder instanceof StatusDisplayItem.Holder<?> sh
&& (!ih.getItemID().equals(sh.getItemID()) || sh instanceof ExtendedFooterStatusDisplayItem.Holder) && ih.getItem().getType()!=StatusDisplayItem.Type.GAP){ && (!ih.getItemID().equals(sh.getItemID()) || sh instanceof ExtendedFooterStatusDisplayItem.Holder) && ih.getItem().getType()!=StatusDisplayItem.Type.GAP)
|| needDividerForExtraItem(child, bottomSibling, holder, siblingHolder)){
drawDivider(child, bottomSibling, holder, siblingHolder, parent, c, dividerPaint); drawDivider(child, bottomSibling, holder, siblingHolder, parent, c, dividerPaint);
} }
} }

View File

@ -1,7 +1,12 @@
package org.joinmastodon.android.fragments; package org.joinmastodon.android.fragments;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import org.joinmastodon.android.R; import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.statuses.GetStatusContext; import org.joinmastodon.android.api.requests.statuses.GetStatusContext;
@ -23,10 +28,15 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import androidx.recyclerview.widget.RecyclerView;
import me.grishka.appkit.api.SimpleCallback; import me.grishka.appkit.api.SimpleCallback;
import me.grishka.appkit.utils.MergeRecyclerAdapter;
import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
import me.grishka.appkit.utils.V;
public class ThreadFragment extends StatusListFragment{ public class ThreadFragment extends StatusListFragment{
private Status mainStatus; private Status mainStatus;
private ImageView endMark;
@Override @Override
public void onCreate(Bundle savedInstanceState){ public void onCreate(Bundle savedInstanceState){
@ -132,4 +142,24 @@ public class ThreadFragment extends StatusListFragment{
public boolean isItemEnabled(String id){ public boolean isItemEnabled(String id){
return !id.equals(mainStatus.id); return !id.equals(mainStatus.id);
} }
@Override
protected RecyclerView.Adapter getAdapter(){
MergeRecyclerAdapter a=new MergeRecyclerAdapter();
a.addAdapter(super.getAdapter());
endMark=new ImageView(getActivity());
endMark.setScaleType(ImageView.ScaleType.CENTER);
endMark.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(getActivity(), R.attr.colorM3OutlineVariant)));
endMark.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, V.dp(25)));
endMark.setImageResource(R.drawable.thread_end_mark);
a.addAdapter(new SingleViewRecyclerAdapter(endMark));
return a;
}
@Override
protected boolean needDividerForExtraItem(View child, View bottomSibling, RecyclerView.ViewHolder holder, RecyclerView.ViewHolder siblingHolder){
return bottomSibling==endMark;
}
} }

View File

@ -45,8 +45,8 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
} }
public static class Holder extends StatusDisplayItem.Holder<ExtendedFooterStatusDisplayItem>{ public static class Holder extends StatusDisplayItem.Holder<ExtendedFooterStatusDisplayItem>{
private final TextView time, favoritesCount, reblogsCount, lastEditTime; private final TextView time;
private final View favorites, reblogs, editHistory; private final TextView favorites, reblogs, editHistory;
public Holder(Context context, ViewGroup parent){ public Holder(Context context, ViewGroup parent){
super(context, R.layout.display_item_extended_footer, parent); super(context, R.layout.display_item_extended_footer, parent);
@ -54,9 +54,6 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
favorites=findViewById(R.id.favorites); favorites=findViewById(R.id.favorites);
editHistory=findViewById(R.id.edit_history); editHistory=findViewById(R.id.edit_history);
time=findViewById(R.id.timestamp); time=findViewById(R.id.timestamp);
favoritesCount=findViewById(R.id.favorites_count);
reblogsCount=findViewById(R.id.reblogs_count);
lastEditTime=findViewById(R.id.last_edited);
reblogs.setOnClickListener(v->startAccountListFragment(StatusReblogsListFragment.class)); reblogs.setOnClickListener(v->startAccountListFragment(StatusReblogsListFragment.class));
favorites.setOnClickListener(v->startAccountListFragment(StatusFavoritesListFragment.class)); favorites.setOnClickListener(v->startAccountListFragment(StatusFavoritesListFragment.class));
@ -67,11 +64,11 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
@Override @Override
public void onBind(ExtendedFooterStatusDisplayItem item){ public void onBind(ExtendedFooterStatusDisplayItem item){
Status s=item.status; Status s=item.status;
favoritesCount.setText(String.format("%,d", s.favouritesCount)); favorites.setText(itemView.getResources().getQuantityString(R.plurals.x_favorites, (int)item.status.favouritesCount, item.status.favouritesCount));
reblogsCount.setText(String.format("%,d", s.reblogsCount)); reblogs.setText(itemView.getResources().getQuantityString(R.plurals.x_reblogs, (int)item.status.reblogsCount, item.status.reblogsCount));
if(s.editedAt!=null){ if(s.editedAt!=null){
editHistory.setVisibility(View.VISIBLE); editHistory.setVisibility(View.VISIBLE);
lastEditTime.setText(item.parentFragment.getString(R.string.last_edit_at_x, UiUtils.formatRelativeTimestampAsMinutesAgo(itemView.getContext(), s.editedAt))); editHistory.setText(item.parentFragment.getString(R.string.last_edit_at_x, UiUtils.formatRelativeTimestampAsMinutesAgo(itemView.getContext(), s.editedAt)));
}else{ }else{
editHistory.setVisibility(View.GONE); editHistory.setVisibility(View.GONE);
} }

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:start="16dp">
<shape>
<solid android:color="?colorM3OutlineVariant"/>
<size android:height="0.5dp"/>
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M7,22 L3,18 7,14 8.4,15.45 6.85,17H17V13H19V19H6.85L8.4,20.55ZM5,11V5H17.15L15.6,3.45L17,2L21,6L17,10L15.6,8.55L17.15,7H7V11Z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="9dp"
android:viewportWidth="16"
android:viewportHeight="9">
<path
android:pathData="M3.362,9C4.169,9 4.671,8.291 4.671,7.797C4.671,7.346 4.409,6.959 3.995,6.959C3.733,6.959 3.558,7.045 3.471,7.217C3.383,7.389 3.231,7.475 3.034,7.475C2.641,7.475 2.336,7.067 2.248,6.358C3.995,6.1 5.042,5.069 5.042,3.587C5.326,3.673 5.697,3.845 6.134,4.103C6.57,4.36 6.941,4.511 7.247,4.597C6.352,4.919 6.003,5.52 6.003,6.401C6.003,7.947 7.924,8.828 9.735,8.828C10.761,8.828 11.765,8.592 12.704,8.098C14.581,7.11 16,5.177 16,3.458V3.372C16,1.697 14.974,0.752 13.817,0.752C13.184,0.752 12.857,1.01 12.857,1.504C12.857,1.804 13.097,2.126 13.49,2.298C13.948,2.126 14.254,2.019 14.428,2.019C14.974,2.019 15.367,2.427 15.367,2.986C15.367,3.458 14.887,3.995 14.297,3.995C13.686,3.995 13.184,3.523 12.311,2.363L11.591,1.396C11.001,0.623 10.085,0.086 9.211,0.086C7.465,0.086 6.548,0.795 6.548,2.084C6.548,2.857 6.789,3.48 7.269,3.995C7.05,3.952 6.679,3.78 6.177,3.501C5.697,3.243 5.282,3.072 4.977,3.05C4.911,2.642 4.54,2.234 3.885,1.847C3.231,1.461 2.903,1.095 2.903,0.752C2.903,0.301 3.056,0.172 3.383,0.172H3.536C3.362,0.064 3.121,0 2.838,0C2.183,0 1.55,0.601 1.55,1.267C1.55,2.062 2.161,2.492 3.383,2.578C3.885,2.621 4.191,2.792 4.322,3.072C2.838,3.179 1.659,4.06 1.332,5.477C0.437,5.542 0,5.95 0,6.68C0,6.895 0.065,7.131 0.218,7.389C0.218,6.831 0.568,6.637 1.244,6.551C1.31,7.819 2.314,9 3.362,9ZM2.205,5.477C2.401,4.403 3.231,3.673 4.518,3.544V3.695C4.518,4.811 3.689,5.434 2.205,5.477Z"
android:fillColor="#CAC4D0"/>
</vector>

View File

@ -3,149 +3,74 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:divider="@drawable/divider_inset_16dp_start"
<RelativeLayout android:showDividers="middle">
android:id="@+id/reblogs"
android:layout_width="match_parent"
android:layout_height="64dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:background="?android:selectableItemBackground">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_fluent_arrow_repeat_all_24_regular"
android:tint="?android:textColorSecondary"
android:importantForAccessibility="no"/>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_toEndOf="@id/icon"
android:minHeight="22dp"
android:singleLine="true"
android:text="@string/post_info_reblogs"
android:textAppearance="@style/m3_body_large" />
<TextView
android:id="@+id/reblogs_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_alignStart="@id/title"
android:singleLine="true"
android:textAppearance="@style/m3_body_medium"
android:textColor="?android:textColorSecondary"
tools:text="123 456"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/favorites"
android:layout_width="match_parent"
android:layout_height="64dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:background="?android:selectableItemBackground">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_fluent_star_24_regular"
android:tint="?android:textColorSecondary"
android:importantForAccessibility="no"/>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_toEndOf="@id/icon"
android:minHeight="22dp"
android:singleLine="true"
android:text="@string/post_info_favorites"
android:textAppearance="@style/m3_body_large" />
<TextView
android:id="@+id/favorites_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_alignStart="@id/title"
android:singleLine="true"
android:textAppearance="@style/m3_body_medium"
android:textColor="?android:textColorSecondary"
tools:text="123 456"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/edit_history"
android:layout_width="match_parent"
android:layout_height="64dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:background="?android:selectableItemBackground">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_fluent_edit_24_regular"
android:tint="?android:textColorSecondary"
android:importantForAccessibility="no"/>
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_toEndOf="@id/icon"
android:minHeight="22dp"
android:singleLine="true"
android:text="@string/edit_history"
android:textAppearance="@style/m3_body_large" />
<TextView
android:id="@+id/last_edited"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_alignStart="@id/title"
android:singleLine="true"
android:textAppearance="@style/m3_body_medium"
android:textColor="?android:textColorSecondary"
tools:text="123 456"/>
</RelativeLayout>
<TextView <TextView
android:id="@+id/timestamp" android:id="@+id/timestamp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="20dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:minHeight="20dp" android:minHeight="20dp"
android:gravity="center_vertical" android:gravity="center_vertical"
android:textSize="14sp" android:textAppearance="@style/m3_body_large"
android:textColor="?android:textColorSecondary" android:textSize="16sp"
android:textColor="?colorM3OnSurfaceVariant"
tools:text="Dec 12, 2021, 12:42 PM via Mastodon for Android"/> tools:text="Dec 12, 2021, 12:42 PM via Mastodon for Android"/>
<TextView
android:id="@+id/edit_history"
android:layout_width="match_parent"
android:layout_height="48dp"
android:paddingStart="16dp"
android:paddingEnd="24dp"
android:background="?android:selectableItemBackground"
android:textAppearance="@style/m3_body_large"
android:textColor="?colorM3OnSurface"
android:singleLine="true"
android:ellipsize="end"
android:gravity="center_vertical"
android:drawableStart="@drawable/ic_edit_24px"
android:drawableTint="?colorM3OnSurfaceVariant"
android:drawablePadding="16dp"
tools:text="Last edit bla bla"/>
<TextView
android:id="@+id/reblogs"
android:layout_width="match_parent"
android:layout_height="48dp"
android:paddingStart="16dp"
android:paddingEnd="24dp"
android:background="?android:selectableItemBackground"
android:textAppearance="@style/m3_body_large"
android:textColor="?colorM3OnSurface"
android:singleLine="true"
android:ellipsize="end"
android:gravity="center_vertical"
android:drawableStart="@drawable/ic_repeat_24px"
android:drawableTint="?colorM3OnSurfaceVariant"
android:drawablePadding="16dp"
tools:text="123 boosts"/>
<TextView
android:id="@+id/favorites"
android:layout_width="match_parent"
android:layout_height="48dp"
android:paddingStart="16dp"
android:paddingEnd="24dp"
android:background="?android:selectableItemBackground"
android:textAppearance="@style/m3_body_large"
android:textColor="?colorM3OnSurface"
android:singleLine="true"
android:ellipsize="end"
android:gravity="center_vertical"
android:drawableStart="@drawable/ic_star_24px"
android:drawableTint="?colorM3OnSurfaceVariant"
android:drawablePadding="16dp"
tools:text="123 favorites"/>
</LinearLayout> </LinearLayout>

View File

@ -22,6 +22,7 @@
<color name="m3_sys_light_surface_variant">@android:color/system_neutral2_100</color> <color name="m3_sys_light_surface_variant">@android:color/system_neutral2_100</color>
<color name="m3_sys_light_on_surface_variant">@android:color/system_neutral2_700</color> <color name="m3_sys_light_on_surface_variant">@android:color/system_neutral2_700</color>
<color name="m3_sys_light_outline">@android:color/system_neutral2_500</color> <color name="m3_sys_light_outline">@android:color/system_neutral2_500</color>
<color name="m3_sys_light_outline_variant">@android:color/system_neutral2_200</color>
<!-- dark theme --> <!-- dark theme -->
<color name="m3_sys_dark_primary">@android:color/system_accent1_200</color> <color name="m3_sys_dark_primary">@android:color/system_accent1_200</color>
@ -43,4 +44,5 @@
<color name="m3_sys_dark_surface_variant">@android:color/system_neutral2_700</color> <color name="m3_sys_dark_surface_variant">@android:color/system_neutral2_700</color>
<color name="m3_sys_dark_on_surface_variant">@android:color/system_neutral2_200</color> <color name="m3_sys_dark_on_surface_variant">@android:color/system_neutral2_200</color>
<color name="m3_sys_dark_outline">@android:color/system_neutral2_400</color> <color name="m3_sys_dark_outline">@android:color/system_neutral2_400</color>
<color name="m3_sys_dark_outline_variant">@android:color/system_neutral2_700</color>
</resources> </resources>

View File

@ -35,6 +35,7 @@
<attr name="colorM3SurfaceVariant" format="color"/> <attr name="colorM3SurfaceVariant" format="color"/>
<attr name="colorM3OnSurfaceVariant" format="color"/> <attr name="colorM3OnSurfaceVariant" format="color"/>
<attr name="colorM3Outline" format="color"/> <attr name="colorM3Outline" format="color"/>
<attr name="colorM3OutlineVariant" format="color"/>
<attr name="colorM3DisabledBackground" format="color"/> <attr name="colorM3DisabledBackground" format="color"/>
<attr name="colorM3PressedOverlay" format="color"/> <attr name="colorM3PressedOverlay" format="color"/>
<attr name="colorM3Error" format="color"/> <attr name="colorM3Error" format="color"/>

View File

@ -119,6 +119,7 @@
<color name="m3_sys_light_surface_variant">#E7E0EC</color> <color name="m3_sys_light_surface_variant">#E7E0EC</color>
<color name="m3_sys_light_on_surface_variant">#49454F</color> <color name="m3_sys_light_on_surface_variant">#49454F</color>
<color name="m3_sys_light_outline">#79747E</color> <color name="m3_sys_light_outline">#79747E</color>
<color name="m3_sys_light_outline_variant">#CAC4D0</color>
<!-- dark theme --> <!-- dark theme -->
<color name="m3_sys_dark_primary">#D0BCFF</color> <color name="m3_sys_dark_primary">#D0BCFF</color>
@ -140,5 +141,6 @@
<color name="m3_sys_dark_surface_variant">#49454F</color> <color name="m3_sys_dark_surface_variant">#49454F</color>
<color name="m3_sys_dark_on_surface_variant">#CAC4D0</color> <color name="m3_sys_dark_on_surface_variant">#CAC4D0</color>
<color name="m3_sys_dark_outline">#938F99</color> <color name="m3_sys_dark_outline">#938F99</color>
<color name="m3_sys_dark_outline_variant">#49454F</color>
</resources> </resources>

View File

@ -59,6 +59,7 @@
<item name="colorM3SurfaceVariant">@color/m3_sys_light_surface_variant</item> <item name="colorM3SurfaceVariant">@color/m3_sys_light_surface_variant</item>
<item name="colorM3OnSurfaceVariant">@color/m3_sys_light_on_surface_variant</item> <item name="colorM3OnSurfaceVariant">@color/m3_sys_light_on_surface_variant</item>
<item name="colorM3Outline">@color/m3_sys_light_outline</item> <item name="colorM3Outline">@color/m3_sys_light_outline</item>
<item name="colorM3OutlineVariant">@color/m3_sys_light_outline_variant</item>
<item name="colorM3DisabledBackground">#1F1F1F1F</item> <item name="colorM3DisabledBackground">#1F1F1F1F</item>
<item name="colorM3PressedOverlay">@color/m3_sys_light_on_primary</item> <item name="colorM3PressedOverlay">@color/m3_sys_light_on_primary</item>
<item name="colorM3Error">#B3261E</item> <item name="colorM3Error">#B3261E</item>
@ -136,6 +137,7 @@
<item name="colorM3SurfaceVariant">@color/m3_sys_dark_surface_variant</item> <item name="colorM3SurfaceVariant">@color/m3_sys_dark_surface_variant</item>
<item name="colorM3OnSurfaceVariant">@color/m3_sys_dark_on_surface_variant</item> <item name="colorM3OnSurfaceVariant">@color/m3_sys_dark_on_surface_variant</item>
<item name="colorM3Outline">@color/m3_sys_dark_outline</item> <item name="colorM3Outline">@color/m3_sys_dark_outline</item>
<item name="colorM3OutlineVariant">@color/m3_sys_dark_outline_variant</item>
<item name="colorM3DisabledBackground">#1FE3E3E3</item> <item name="colorM3DisabledBackground">#1FE3E3E3</item>
<item name="colorM3PressedOverlay">@color/m3_sys_dark_primary</item> <item name="colorM3PressedOverlay">@color/m3_sys_dark_primary</item>
<item name="colorM3Error">#F2B8B5</item> <item name="colorM3Error">#F2B8B5</item>