Profile about tab redesign

This commit is contained in:
Grishka 2023-03-22 17:22:22 +03:00
parent 43bbe9be0f
commit f7215d00ca
5 changed files with 68 additions and 84 deletions

View File

@ -13,6 +13,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowInsets; import android.view.WindowInsets;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import org.joinmastodon.android.R; import org.joinmastodon.android.R;
@ -48,10 +49,8 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
public UsableRecyclerView list; public UsableRecyclerView list;
private List<AccountField> fields=Collections.emptyList(); private List<AccountField> fields=Collections.emptyList();
private AboutAdapter adapter; private AboutAdapter adapter;
private Paint dividerPaint=new Paint();
private boolean isInEditMode; private boolean isInEditMode;
private ItemTouchHelper dragHelper=new ItemTouchHelper(new ReorderCallback()); private ItemTouchHelper dragHelper=new ItemTouchHelper(new ReorderCallback());
private RecyclerView.ViewHolder draggedViewHolder;
private ListImageLoaderWrapper imgLoader; private ListImageLoaderWrapper imgLoader;
public void setFields(List<AccountField> fields){ public void setFields(List<AccountField> fields){
@ -74,27 +73,8 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
list.setLayoutManager(new LinearLayoutManager(getActivity())); list.setLayoutManager(new LinearLayoutManager(getActivity()));
imgLoader=new ListImageLoaderWrapper(getActivity(), list, new RecyclerViewDelegate(list), null); imgLoader=new ListImageLoaderWrapper(getActivity(), list, new RecyclerViewDelegate(list), null);
list.setAdapter(adapter=new AboutAdapter()); list.setAdapter(adapter=new AboutAdapter());
int pad=V.dp(16); list.setPadding(0, V.dp(16), 0, 0);
list.setPadding(pad, pad, pad, pad);
list.setClipToPadding(false); list.setClipToPadding(false);
dividerPaint.setStyle(Paint.Style.STROKE);
dividerPaint.setStrokeWidth(V.dp(1));
dividerPaint.setColor(UiUtils.getThemeColor(getActivity(), R.attr.colorPollVoted));
list.addItemDecoration(new RecyclerView.ItemDecoration(){
@Override
public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){
for(int i=0;i<parent.getChildCount();i++){
View item=parent.getChildAt(i);
int pos=parent.getChildAdapterPosition(item);
int draggedPos=draggedViewHolder==null ? -1 : draggedViewHolder.getAbsoluteAdapterPosition();
if(pos<adapter.getItemCount()-1 && pos!=draggedPos && pos!=draggedPos-1){
float y=item.getY()+item.getHeight();
dividerPaint.setAlpha(Math.round(255*item.getAlpha()));
c.drawLine(item.getLeft(), y, item.getRight(), y, dividerPaint);
}
}
}
});
return list; return list;
} }
@ -183,36 +163,25 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
} }
private abstract class BaseViewHolder extends BindableViewHolder<AccountField>{ private abstract class BaseViewHolder extends BindableViewHolder<AccountField>{
protected ShapeDrawable background=new ShapeDrawable();
public BaseViewHolder(int layout){ public BaseViewHolder(int layout){
super(getActivity(), layout, list); super(getActivity(), layout, list);
background.getPaint().setColor(UiUtils.getThemeColor(getActivity(), R.attr.colorBackgroundLight));
itemView.setBackground(background);
} }
@Override @Override
public void onBind(AccountField item){ public void onBind(AccountField item){
boolean first=getAbsoluteAdapterPosition()==0, last=getAbsoluteAdapterPosition()==adapter.getItemCount()-1;
float radius=V.dp(10);
float[] rad=new float[8];
if(first)
rad[0]=rad[1]=rad[2]=rad[3]=radius;
if(last)
rad[4]=rad[5]=rad[6]=rad[7]=radius;
background.setShape(new RoundRectShape(rad, null, null));
itemView.invalidateOutline();
} }
} }
private class AboutViewHolder extends BaseViewHolder implements ImageLoaderViewHolder{ private class AboutViewHolder extends BaseViewHolder implements ImageLoaderViewHolder{
private TextView title; private final TextView title;
private LinkedTextView value; private final LinkedTextView value;
private final ImageView verifiedIcon;
public AboutViewHolder(){ public AboutViewHolder(){
super(R.layout.item_profile_about); super(R.layout.item_profile_about);
title=findViewById(R.id.title); title=findViewById(R.id.title);
value=findViewById(R.id.value); value=findViewById(R.id.value);
verifiedIcon=findViewById(R.id.verified_icon);
} }
@Override @Override
@ -220,20 +189,7 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
super.onBind(item); super.onBind(item);
title.setText(item.parsedName); title.setText(item.parsedName);
value.setText(item.parsedValue); value.setText(item.parsedValue);
if(item.verifiedAt!=null){ verifiedIcon.setVisibility(item.verifiedAt!=null ? View.VISIBLE : View.GONE);
background.getPaint().setColor(UiUtils.isDarkTheme() ? 0xFF49595a : 0xFFd7e3da);
int textColor=UiUtils.isDarkTheme() ? 0xFF89bb9c : 0xFF5b8e63;
value.setTextColor(textColor);
value.setLinkTextColor(textColor);
Drawable check=getResources().getDrawable(R.drawable.ic_fluent_checkmark_24_regular, getActivity().getTheme()).mutate();
check.setTint(textColor);
value.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, check, null);
}else{
background.getPaint().setColor(UiUtils.getThemeColor(getActivity(), R.attr.colorBackgroundLight));
value.setTextColor(UiUtils.getThemeColor(getActivity(), android.R.attr.textColorPrimary));
value.setLinkTextColor(UiUtils.getThemeColor(getActivity(), android.R.attr.colorAccent));
value.setCompoundDrawables(null, null, null, null);
}
} }
@Override @Override
@ -251,20 +207,20 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
} }
private class EditableAboutViewHolder extends BaseViewHolder{ private class EditableAboutViewHolder extends BaseViewHolder{
private EditText title; private final EditText title;
private EditText value; private final EditText value;
public EditableAboutViewHolder(){ public EditableAboutViewHolder(){
super(R.layout.item_profile_about_editable); super(R.layout.onboarding_profile_field);
title=findViewById(R.id.title); title=findViewById(R.id.title);
value=findViewById(R.id.value); value=findViewById(R.id.content);
findViewById(R.id.dragger_thingy).setOnLongClickListener(v->{ findViewById(R.id.dragger_thingy).setOnLongClickListener(v->{
dragHelper.startDrag(this); dragHelper.startDrag(this);
return true; return true;
}); });
title.addTextChangedListener(new SimpleTextWatcher(e->item.name=e.toString())); title.addTextChangedListener(new SimpleTextWatcher(e->item.name=e.toString()));
value.addTextChangedListener(new SimpleTextWatcher(e->item.value=e.toString())); value.addTextChangedListener(new SimpleTextWatcher(e->item.value=e.toString()));
findViewById(R.id.remove_row_btn).setOnClickListener(this::onRemoveRowClick); findViewById(R.id.delete).setOnClickListener(this::onRemoveRowClick);
} }
@Override @Override
@ -323,8 +279,8 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
} }
} }
adapter.notifyItemMoved(fromPosition, toPosition); adapter.notifyItemMoved(fromPosition, toPosition);
((BindableViewHolder)viewHolder).rebind(); ((BindableViewHolder<?>)viewHolder).rebind();
((BindableViewHolder)target).rebind(); ((BindableViewHolder<?>)target).rebind();
return true; return true;
} }
@ -339,7 +295,6 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){ if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){
viewHolder.itemView.setTag(R.id.item_touch_helper_previous_elevation, viewHolder.itemView.getElevation()); // prevents the default behavior of changing elevation in onDraw() viewHolder.itemView.setTag(R.id.item_touch_helper_previous_elevation, viewHolder.itemView.getElevation()); // prevents the default behavior of changing elevation in onDraw()
viewHolder.itemView.animate().translationZ(V.dp(1)).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start(); viewHolder.itemView.animate().translationZ(V.dp(1)).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
draggedViewHolder=viewHolder;
} }
} }
@ -347,7 +302,6 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder){ public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder){
super.clearView(recyclerView, viewHolder); super.clearView(recyclerView, viewHolder);
viewHolder.itemView.animate().translationZ(0).setDuration(100).setInterpolator(CubicBezierInterpolator.DEFAULT).start(); viewHolder.itemView.animate().translationZ(0).setDuration(100).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
draggedViewHolder=null;
} }
@Override @Override

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="M8.6,22.5 L6.7,19.3 3.1,18.5 3.45,14.8 1,12 3.45,9.2 3.1,5.5 6.7,4.7 8.6,1.5 12,2.95 15.4,1.5 17.3,4.7 20.9,5.5 20.55,9.2 23,12 20.55,14.8 20.9,18.5 17.3,19.3 15.4,22.5 12,21.05ZM9.45,19.95 L12,18.85 14.6,19.95 16,17.55 18.75,16.9 18.5,14.1 20.35,12 18.5,9.85 18.75,7.05 16,6.45 14.55,4.05 12,5.15 9.4,4.05 8,6.45 5.25,7.05 5.5,9.85 3.65,12 5.5,14.1 5.25,16.95 8,17.55ZM12,12ZM10.95,15.55 L16.6,9.9 15.2,8.45 10.95,12.7 8.8,10.6 7.4,12Z"/>
</vector>

View File

@ -1,30 +1,50 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?colorBackgroundLight" android:clipToPadding="false"
android:elevation="2dp" android:paddingStart="16dp"
android:outlineProvider="background" android:paddingTop="6dp"
android:padding="16dp"> android:paddingEnd="24dp"
android:paddingBottom="6dp">
<ImageView
android:id="@+id/verified_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginStart="16dp"
android:tint="?colorM3Primary"
android:contentDescription="@string/verified_link"
android:src="@drawable/ic_verified_24px"/>
<TextView <TextView
android:id="@+id/title" android:id="@+id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="@style/m3_label_medium" android:layout_below="@id/value"
android:minHeight="16dp" android:layout_toStartOf="@id/verified_icon"
android:textAllCaps="true" android:textAppearance="@style/m3_body_medium"
android:textSize="12sp" android:minHeight="20dp"
android:textSize="14sp"
android:gravity="center_vertical"
android:textColor="?colorM3OnSurfaceVariant"
android:singleLine="true"
android:ellipsize="end"
tools:text="Field title"/> tools:text="Field title"/>
<org.joinmastodon.android.ui.views.LinkedTextView <org.joinmastodon.android.ui.views.LinkedTextView
android:id="@+id/value" android:id="@+id/value"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toStartOf="@id/verified_icon"
android:textAppearance="@style/m3_body_large" android:textAppearance="@style/m3_body_large"
android:textColor="?colorM3OnSurface"
android:textSize="16sp" android:textSize="16sp"
android:minHeight="24dp"
android:gravity="center_vertical"
tools:text="Field value"/> tools:text="Field value"/>
</LinearLayout> </RelativeLayout>

View File

@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <TextView android:id="@+id/add_row"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="56dp"
android:elevation="2dp" android:gravity="center_vertical"
android:outlineProvider="background"> android:paddingStart="16dp"
android:paddingEnd="24dp"
<View android:textAppearance="@style/m3_body_large"
android:layout_width="24dp" android:textColor="?colorM3OnSurface"
android:layout_height="24dp" android:drawableEnd="@drawable/ic_add_24px"
android:layout_gravity="start|center_vertical" android:drawableTint="?colorM3OnSurface"
android:layout_marginStart="16dp" android:drawablePadding="16dp"
android:backgroundTint="?colorDarkIcon" android:singleLine="true"
android:background="@drawable/ic_fluent_add_circle_24_regular"/> android:ellipsize="end"
android:text="@string/profile_add_row"
</FrameLayout> xmlns:android="http://schemas.android.com/apk/res/android" />

View File

@ -449,4 +449,5 @@
<string name="profile_endorsed_accounts">Accounts</string> <string name="profile_endorsed_accounts">Accounts</string>
<string name="pinned_posts">Pinned posts</string> <string name="pinned_posts">Pinned posts</string>
<string name="featured_hashtags">Featured hashtags</string> <string name="featured_hashtags">Featured hashtags</string>
<string name="verified_link">Verified link</string>
</resources> </resources>