From 1e501c707ca3d6a384e3d1bb6d6e80aafe353f54 Mon Sep 17 00:00:00 2001 From: Grishka Date: Sat, 24 Feb 2024 23:03:18 +0300 Subject: [PATCH] Add labels and animations to the tab bar --- mastodon/build.gradle | 2 +- .../android/ui/ViewProperties.java | 37 ++++++ .../joinmastodon/android/ui/views/TabBar.java | 62 +++++++++- mastodon/src/main/res/color/tab_bar_icon.xml | 5 + .../src/main/res/drawable/bg_tabbar_tab.xml | 30 +++-- .../drawable/bg_tabbar_tab_selected_anim.xml | 26 ++++ .../bg_tabbar_tab_unselected_anim.xml | 17 +++ .../res/drawable/bg_tabbar_tab_vector.xml | 7 ++ .../main/res/drawable/ic_home_fill1_24px.xml | 9 ++ .../drawable/ic_notifications_fill1_24px.xml | 9 ++ .../res/drawable/ic_search_fill1_24px.xml | 9 ++ .../src/main/res/drawable/ic_tab_home.xml | 5 + .../res/drawable/ic_tab_notifications.xml | 5 + .../src/main/res/drawable/ic_tab_search.xml | 5 + mastodon/src/main/res/layout/tab_bar.xml | 111 +++++++++++++----- mastodon/src/main/res/values/strings.xml | 3 + 16 files changed, 293 insertions(+), 49 deletions(-) create mode 100644 mastodon/src/main/java/org/joinmastodon/android/ui/ViewProperties.java create mode 100644 mastodon/src/main/res/color/tab_bar_icon.xml create mode 100644 mastodon/src/main/res/drawable/bg_tabbar_tab_selected_anim.xml create mode 100644 mastodon/src/main/res/drawable/bg_tabbar_tab_unselected_anim.xml create mode 100644 mastodon/src/main/res/drawable/bg_tabbar_tab_vector.xml create mode 100644 mastodon/src/main/res/drawable/ic_home_fill1_24px.xml create mode 100644 mastodon/src/main/res/drawable/ic_notifications_fill1_24px.xml create mode 100644 mastodon/src/main/res/drawable/ic_search_fill1_24px.xml create mode 100644 mastodon/src/main/res/drawable/ic_tab_home.xml create mode 100644 mastodon/src/main/res/drawable/ic_tab_notifications.xml create mode 100644 mastodon/src/main/res/drawable/ic_tab_search.xml diff --git a/mastodon/build.gradle b/mastodon/build.gradle index f5e9c549..05228763 100644 --- a/mastodon/build.gradle +++ b/mastodon/build.gradle @@ -9,7 +9,7 @@ android { applicationId "org.joinmastodon.android" minSdk 23 targetSdk 33 - versionCode 85 + versionCode 86 versionName "2.3.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" resConfigs "ar-rSA", "be-rBY", "bn-rBD", "bs-rBA", "ca-rES", "cs-rCZ", "da-rDK", "de-rDE", "el-rGR", "es-rES", "eu-rES", "fa-rIR", "fi-rFI", "fil-rPH", "fr-rFR", "ga-rIE", "gd-rGB", "gl-rES", "hi-rIN", "hr-rHR", "hu-rHU", "hy-rAM", "ig-rNG", "in-rID", "is-rIS", "it-rIT", "iw-rIL", "ja-rJP", "ka-rGE", "kab", "ko-rKR", "lt-rLT", "my-rMM", "nl-rNL", "no-rNO", "oc-rFR", "pl-rPL", "pt-rBR", "pt-rPT", "ro-rRO", "ru-rRU", "si-rLK", "sl-rSI", "sv-rSE", "th-rTH", "tr-rTR", "uk-rUA", "ur-rIN", "vi-rVN", "zh-rCN", "zh-rTW" diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/ViewProperties.java b/mastodon/src/main/java/org/joinmastodon/android/ui/ViewProperties.java new file mode 100644 index 00000000..cdf38114 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/ViewProperties.java @@ -0,0 +1,37 @@ +package org.joinmastodon.android.ui; + +import android.graphics.Typeface; +import android.os.Build; +import android.util.Property; +import android.widget.TextView; + +import androidx.annotation.RequiresApi; + +public class ViewProperties{ + public static final Property FONT_WEIGHT=new Property<>(Integer.class, "fontWeight"){ + @RequiresApi(api = Build.VERSION_CODES.P) + @Override + public Integer get(TextView object){ + return object.getTypeface().getWeight(); + } + + @RequiresApi(api = Build.VERSION_CODES.P) + @Override + public void set(TextView object, Integer value){ + // typeface objects are cached internally, I looked at AOSP sources to confirm that + object.setTypeface(Typeface.create(null, value, false)); + } + }; + + public static final Property TEXT_COLOR=new Property<>(Integer.class, "textColor"){ + @Override + public Integer get(TextView object){ + return object.getCurrentTextColor(); + } + + @Override + public void set(TextView object, Integer value){ + object.setTextColor(value); + } + }; +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/views/TabBar.java b/mastodon/src/main/java/org/joinmastodon/android/ui/views/TabBar.java index 53fce500..cfafd12d 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/views/TabBar.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/views/TabBar.java @@ -1,20 +1,35 @@ package org.joinmastodon.android.ui.views; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; import android.content.Context; +import android.graphics.Typeface; +import android.os.Build; import android.util.AttributeSet; import android.view.View; +import android.view.animation.AnimationUtils; import android.widget.LinearLayout; +import android.widget.TextView; +import org.joinmastodon.android.R; +import org.joinmastodon.android.ui.ViewProperties; +import org.joinmastodon.android.ui.utils.UiUtils; + +import java.util.ArrayList; import java.util.function.IntConsumer; import java.util.function.IntPredicate; import androidx.annotation.IdRes; +import me.grishka.appkit.utils.CubicBezierInterpolator; public class TabBar extends LinearLayout{ @IdRes private int selectedTabID; private IntConsumer listener; private IntPredicate longClickListener; + private Typeface mediumFont=Typeface.create("sans-serif-medium", Typeface.NORMAL), boldFont=Typeface.DEFAULT_BOLD; public TabBar(Context context){ this(context, null); @@ -32,9 +47,14 @@ public class TabBar extends LinearLayout{ public void onViewAdded(View child){ super.onViewAdded(child); if(child.getId()!=0){ + ViewHolder holder=new ViewHolder(); + holder.label=child.findViewById(R.id.label); + child.setTag(holder); if(selectedTabID==0){ selectedTabID=child.getId(); - child.setSelected(true); + setTabSelected(child, true); + }else{ + holder.label.setTypeface(mediumFont); } child.setOnClickListener(this::onChildClick); child.setOnLongClickListener(this::onChildLongClick); @@ -45,8 +65,8 @@ public class TabBar extends LinearLayout{ listener.accept(v.getId()); if(v.getId()==selectedTabID) return; - findViewById(selectedTabID).setSelected(false); - v.setSelected(true); + setTabSelected(findViewById(selectedTabID), false); + setTabSelected(v, true); selectedTabID=v.getId(); } @@ -60,8 +80,40 @@ public class TabBar extends LinearLayout{ } public void selectTab(int id){ - findViewById(selectedTabID).setSelected(false); + setTabSelected(findViewById(selectedTabID), false); selectedTabID=id; - findViewById(selectedTabID).setSelected(true); + setTabSelected(findViewById(selectedTabID), true); + } + + private void setTabSelected(View tab, boolean selected){ + tab.setSelected(selected); + ViewHolder holder=(ViewHolder) tab.getTag(); + if(holder.currentAnim!=null) + holder.currentAnim.cancel(); + ArrayList anims=new ArrayList<>(); + if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.P){ + anims.add(ObjectAnimator.ofInt(holder.label, ViewProperties.FONT_WEIGHT, selected ? 700 : 500)); + }else{ + holder.label.setTypeface(selected ? boldFont : mediumFont); + } + anims.add(ObjectAnimator.ofArgb(holder.label, ViewProperties.TEXT_COLOR, UiUtils.getThemeColor(getContext(), selected ? R.attr.colorM3OnSurface : R.attr.colorM3OnSurfaceVariant))); + AnimatorSet set=new AnimatorSet(); + set.playTogether(anims); + set.setDuration(400); +// set.setInterpolator(AnimationUtils.loadInterpolator(getContext(), R.interpolator.m3_sys_motion_easing_standard)); + set.setInterpolator(CubicBezierInterpolator.DEFAULT); + holder.currentAnim=set; + set.addListener(new AnimatorListenerAdapter(){ + @Override + public void onAnimationEnd(Animator animation){ + holder.currentAnim=null; + } + }); + set.start(); + } + + private static class ViewHolder{ + public TextView label; + public Animator currentAnim; } } diff --git a/mastodon/src/main/res/color/tab_bar_icon.xml b/mastodon/src/main/res/color/tab_bar_icon.xml new file mode 100644 index 00000000..715a365e --- /dev/null +++ b/mastodon/src/main/res/color/tab_bar_icon.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/bg_tabbar_tab.xml b/mastodon/src/main/res/drawable/bg_tabbar_tab.xml index 4f98d167..050c460d 100644 --- a/mastodon/src/main/res/drawable/bg_tabbar_tab.xml +++ b/mastodon/src/main/res/drawable/bg_tabbar_tab.xml @@ -1,21 +1,19 @@ - - - - + + + + - - - + + + - + + + + + + - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/bg_tabbar_tab_selected_anim.xml b/mastodon/src/main/res/drawable/bg_tabbar_tab_selected_anim.xml new file mode 100644 index 00000000..9a9c56a6 --- /dev/null +++ b/mastodon/src/main/res/drawable/bg_tabbar_tab_selected_anim.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/bg_tabbar_tab_unselected_anim.xml b/mastodon/src/main/res/drawable/bg_tabbar_tab_unselected_anim.xml new file mode 100644 index 00000000..ae958337 --- /dev/null +++ b/mastodon/src/main/res/drawable/bg_tabbar_tab_unselected_anim.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/bg_tabbar_tab_vector.xml b/mastodon/src/main/res/drawable/bg_tabbar_tab_vector.xml new file mode 100644 index 00000000..c8d4b12a --- /dev/null +++ b/mastodon/src/main/res/drawable/bg_tabbar_tab_vector.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_home_fill1_24px.xml b/mastodon/src/main/res/drawable/ic_home_fill1_24px.xml new file mode 100644 index 00000000..61590a1f --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_home_fill1_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_notifications_fill1_24px.xml b/mastodon/src/main/res/drawable/ic_notifications_fill1_24px.xml new file mode 100644 index 00000000..3fb86659 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_notifications_fill1_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_search_fill1_24px.xml b/mastodon/src/main/res/drawable/ic_search_fill1_24px.xml new file mode 100644 index 00000000..34e7ace3 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_search_fill1_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/mastodon/src/main/res/drawable/ic_tab_home.xml b/mastodon/src/main/res/drawable/ic_tab_home.xml new file mode 100644 index 00000000..a554453d --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_tab_home.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_tab_notifications.xml b/mastodon/src/main/res/drawable/ic_tab_notifications.xml new file mode 100644 index 00000000..83f2802e --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_tab_notifications.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/drawable/ic_tab_search.xml b/mastodon/src/main/res/drawable/ic_tab_search.xml new file mode 100644 index 00000000..3f22bbe0 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_tab_search.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/layout/tab_bar.xml b/mastodon/src/main/res/layout/tab_bar.xml index be22305c..59715e37 100644 --- a/mastodon/src/main/res/layout/tab_bar.xml +++ b/mastodon/src/main/res/layout/tab_bar.xml @@ -12,8 +12,7 @@ + android:tint="@color/tab_bar_icon" + android:src="@drawable/ic_tab_home"/> + + @@ -41,18 +54,32 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" - android:layout_marginRight="8dp" android:background="@drawable/bg_tabbar_tab" + android:paddingHorizontal="4dp" android:contentDescription="@string/search_hint"> + android:tint="@color/tab_bar_icon" + android:src="@drawable/ic_tab_search"/> + + @@ -61,25 +88,26 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" - android:layout_marginRight="8dp" android:background="@drawable/bg_tabbar_tab" + android:paddingHorizontal="4dp" android:contentDescription="@string/notifications"> + android:tint="@color/tab_bar_icon" + android:src="@drawable/ic_tab_notifications"/> + + + + diff --git a/mastodon/src/main/res/values/strings.xml b/mastodon/src/main/res/values/strings.xml index d92d9ac9..71e7d30e 100644 --- a/mastodon/src/main/res/values/strings.xml +++ b/mastodon/src/main/res/values/strings.xml @@ -713,4 +713,7 @@ In-app browser System browser Add word + Home + Explore + Profile \ No newline at end of file