add more animation

This commit is contained in:
ShirosakiMio 2024-08-19 13:58:06 +08:00
parent ea98cb3ae9
commit 2262751065
10 changed files with 189 additions and 20 deletions

View File

@ -188,6 +188,7 @@ dependencies {
implementation 'com.google.android.material:material:1.11.0' implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.github.Mathias-Boulay:android_gamepad_remapper:06184ddbce' implementation 'com.github.Mathias-Boulay:android_gamepad_remapper:06184ddbce'
implementation 'com.github.bumptech.glide:glide:4.16.0'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

View File

@ -0,0 +1,99 @@
package com.mio.util
import android.animation.ObjectAnimator
import android.animation.TimeInterpolator
import android.view.View
class AnimUtil {
companion object {
@JvmStatic
fun playTranslationY(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "translationY", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playTranslationX(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "translationX", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playTranslationZ(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "translationZ", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playRotation(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "rotation", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playScaleX(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "scaleX", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playScaleY(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "scaleY", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun playAlpha(
view: View,
duration: Long,
vararg values: Float
): ObjectAnimator {
return ObjectAnimator.ofFloat(view, "alpha", *values).apply {
this.duration = duration
}
}
@JvmStatic
fun ObjectAnimator.delay(delayTime: Long): ObjectAnimator {
this.startDelay = delayTime
return this
}
@JvmStatic
fun ObjectAnimator.interpolator(interpolator: TimeInterpolator): ObjectAnimator {
this.interpolator = interpolator
return this
}
}
}

View File

@ -7,12 +7,15 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.bumptech.glide.Glide;
import com.mio.util.AnimUtil;
import com.tungsten.fcl.R; import com.tungsten.fcl.R;
import com.tungsten.fcl.util.ModTranslations; import com.tungsten.fcl.util.ModTranslations;
import com.tungsten.fclcore.mod.RemoteMod; import com.tungsten.fclcore.mod.RemoteMod;
import com.tungsten.fclcore.task.Schedulers; import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.util.StringUtils; import com.tungsten.fclcore.util.StringUtils;
import com.tungsten.fcllibrary.component.FCLAdapter; import com.tungsten.fcllibrary.component.FCLAdapter;
import com.tungsten.fcllibrary.component.theme.ThemeEngine;
import com.tungsten.fcllibrary.util.LocaleUtils; import com.tungsten.fcllibrary.util.LocaleUtils;
import com.tungsten.fcllibrary.component.view.FCLImageView; import com.tungsten.fcllibrary.component.view.FCLImageView;
import com.tungsten.fcllibrary.component.view.FCLLinearLayout; import com.tungsten.fcllibrary.component.view.FCLLinearLayout;
@ -76,21 +79,7 @@ public class RemoteModListAdapter extends FCLAdapter {
viewHolder.parent.setOnClickListener(v -> callback.onItemSelect(remoteMod)); viewHolder.parent.setOnClickListener(v -> callback.onItemSelect(remoteMod));
viewHolder.icon.setImageDrawable(null); viewHolder.icon.setImageDrawable(null);
viewHolder.icon.setTag(i); viewHolder.icon.setTag(i);
new Thread(() -> { Glide.with(getContext()).load(remoteMod.getIconUrl()).into(viewHolder.icon);
try {
URL url = new URL(remoteMod.getIconUrl());
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap icon = BitmapFactory.decodeStream(inputStream);
if (viewHolder.icon.getTag().equals(i)) {
Schedulers.androidUIThread().execute(() -> viewHolder.icon.setImageBitmap(icon));
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
ModTranslations.Mod mod = ModTranslations.getTranslationsByRepositoryType(downloadPage.repository.getType()).getModByCurseForgeId(remoteMod.getSlug()); ModTranslations.Mod mod = ModTranslations.getTranslationsByRepositoryType(downloadPage.repository.getType()).getModByCurseForgeId(remoteMod.getSlug());
viewHolder.name.setText(mod != null && LocaleUtils.isChinese(getContext()) ? mod.getDisplayName() : remoteMod.getTitle()); viewHolder.name.setText(mod != null && LocaleUtils.isChinese(getContext()) ? mod.getDisplayName() : remoteMod.getTitle());
List<String> categories = remoteMod.getCategories().stream().map(downloadPage::getLocalizedCategory).collect(Collectors.toList()); List<String> categories = remoteMod.getCategories().stream().map(downloadPage::getLocalizedCategory).collect(Collectors.toList());
@ -99,6 +88,7 @@ public class RemoteModListAdapter extends FCLAdapter {
String tag = StringUtils.removeSuffix(stringBuilder.toString(), " "); String tag = StringUtils.removeSuffix(stringBuilder.toString(), " ");
viewHolder.tag.setText(tag); viewHolder.tag.setText(tag);
viewHolder.description.setText(remoteMod.getDescription()); viewHolder.description.setText(remoteMod.getDescription());
AnimUtil.playTranslationX(view, ThemeEngine.getInstance().getTheme().getAnimationSpeed() * 30L, -100f, 0f).start();
return view; return view;
} }

View File

@ -10,6 +10,7 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.mio.util.AnimUtil;
import com.tungsten.fcl.R; import com.tungsten.fcl.R;
import com.tungsten.fclcore.download.RemoteVersion; import com.tungsten.fclcore.download.RemoteVersion;
import com.tungsten.fclcore.download.fabric.FabricAPIRemoteVersion; import com.tungsten.fclcore.download.fabric.FabricAPIRemoteVersion;
@ -84,6 +85,7 @@ public class RemoteVersionListAdapter extends FCLAdapter {
viewHolder.tag.setText(getTag(remoteVersion)); viewHolder.tag.setText(getTag(remoteVersion));
viewHolder.date.setVisibility(remoteVersion.getReleaseDate() == null ? View.GONE : View.VISIBLE); viewHolder.date.setVisibility(remoteVersion.getReleaseDate() == null ? View.GONE : View.VISIBLE);
viewHolder.date.setText(remoteVersion.getReleaseDate() == null ? "" : formatDateTime(getContext(), remoteVersion.getReleaseDate())); viewHolder.date.setText(remoteVersion.getReleaseDate() == null ? "" : formatDateTime(getContext(), remoteVersion.getReleaseDate()));
AnimUtil.playTranslationX(view, ThemeEngine.getInstance().getTheme().getAnimationSpeed() * 30L, -100f, 0f).start();
return view; return view;
} }

View File

@ -22,7 +22,9 @@
android:paddingBottom="10dp" android:paddingBottom="10dp"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false">
<com.tungsten.fcllibrary.component.view.FCLMenuView <com.tungsten.fcllibrary.component.view.FCLMenuView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -135,13 +137,19 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
android:padding="10dp" android:padding="10dp"
app:layout_constraintTop_toBottomOf="@+id/view"> app:layout_constraintTop_toBottomOf="@+id/view"
android:clipChildren="false"
android:clipToPadding="false"
android:stateListAnimator="@xml/anim_scale">
<com.tungsten.fcllibrary.component.view.FCLImageView <com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="30dp" android:layout_width="30dp"
android:layout_height="30dp" android:layout_height="30dp"
android:layout_gravity="center" android:layout_gravity="center"
android:id="@+id/avatar"/> android:id="@+id/avatar"
android:focusable="true"
android:clickable="true"
android:stateListAnimator="@xml/anim_scale_large"/>
<LinearLayout <LinearLayout
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
@ -211,7 +219,8 @@
android:orientation="horizontal" android:orientation="horizontal"
android:padding="10dp" android:padding="10dp"
app:layout_constraintTop_toBottomOf="@id/view2" app:layout_constraintTop_toBottomOf="@id/view2"
app:layout_constraintStart_toStartOf="parent"> app:layout_constraintStart_toStartOf="parent"
android:stateListAnimator="@xml/anim_scale">
<com.tungsten.fcllibrary.component.view.FCLImageView <com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="30dp" android:layout_width="30dp"

View File

@ -15,7 +15,8 @@
android:background="@drawable/bg_container_white_clickable" android:background="@drawable/bg_container_white_clickable"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal"
android:stateListAnimator="@xml/anim_scale">
<com.tungsten.fcllibrary.component.view.FCLImageView <com.tungsten.fcllibrary.component.view.FCLImageView
android:layout_width="30dp" android:layout_width="30dp"

View File

@ -1,5 +1,6 @@
package com.tungsten.fcllibrary.component.view; package com.tungsten.fcllibrary.component.view;
import android.animation.AnimatorInflater;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
@ -95,6 +96,7 @@ public class FCLButton extends AppCompatButton {
drawablePress.setCornerRadius(ConvertUtils.dip2px(getContext(), 8)); drawablePress.setCornerRadius(ConvertUtils.dip2px(getContext(), 8));
drawablePress.setStroke(ConvertUtils.dip2px(getContext(), 1.5f), Color.GRAY); drawablePress.setStroke(ConvertUtils.dip2px(getContext(), 1.5f), Color.GRAY);
drawablePress.setColor(ThemeEngine.getInstance().getTheme().getLtColor()); drawablePress.setColor(ThemeEngine.getInstance().getTheme().getLtColor());
setStateListAnimator(AnimatorInflater.loadStateListAnimator(getContext(), R.xml.anim_scale));
} }
public FCLButton(@NonNull Context context) { public FCLButton(@NonNull Context context) {

View File

@ -1,5 +1,6 @@
package com.tungsten.fcllibrary.component.view; package com.tungsten.fcllibrary.component.view;
import android.animation.AnimatorInflater;
import android.content.Context; import android.content.Context;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.drawable.RippleDrawable; import android.graphics.drawable.RippleDrawable;
@ -11,6 +12,7 @@ import androidx.appcompat.widget.AppCompatImageButton;
import com.tungsten.fclcore.fakefx.beans.property.IntegerProperty; import com.tungsten.fclcore.fakefx.beans.property.IntegerProperty;
import com.tungsten.fclcore.fakefx.beans.property.IntegerPropertyBase; import com.tungsten.fclcore.fakefx.beans.property.IntegerPropertyBase;
import com.tungsten.fcllibrary.R;
import com.tungsten.fcllibrary.component.theme.ThemeEngine; import com.tungsten.fcllibrary.component.theme.ThemeEngine;
import com.tungsten.fcllibrary.util.ConvertUtils; import com.tungsten.fcllibrary.util.ConvertUtils;
@ -68,6 +70,7 @@ public class FCLMenuView extends AppCompatImageButton {
setSelected(true); setSelected(true);
} }
}); });
setStateListAnimator(AnimatorInflater.loadStateListAnimator(getContext(), R.xml.anim_scale_large));
} }
public void setSelected(boolean selected) { public void setSelected(boolean selected) {

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<set>
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleX"
android:valueTo="0.9"
android:valueType="floatType" />
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleY"
android:valueTo="0.9"
android:valueType="floatType" />
</set>
</item>
<item android:state_pressed="false">
<set>
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleX"
android:valueTo="1"
android:valueType="floatType" />
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleY"
android:valueTo="1"
android:valueType="floatType" />
</set>
</item>
</selector>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<set>
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleX"
android:valueTo="1.5"
android:valueType="floatType" />
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleY"
android:valueTo="1.5"
android:valueType="floatType" />
</set>
</item>
<item android:state_pressed="false">
<set>
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleX"
android:valueTo="1"
android:valueType="floatType" />
<objectAnimator
android:duration="@android:integer/config_shortAnimTime"
android:propertyName="scaleY"
android:valueTo="1"
android:valueType="floatType" />
</set>
</item>
</selector>