Android列表實現(xiàn)單選點擊縮放動畫效果
recycleView單選的時候,一般的處理就是選中的item做個stroke或者字體顏色改變,但要提升用戶體驗就得加點動畫了。也就是點擊選中的元素放大,同時之前選中的item縮小,不便截gif圖,只能放一張靜態(tài)圖,大家腦補腦補~

圖中的CheckBox,代碼實現(xiàn)其實是imageview,它的選中、取消也是有動畫的,不是控制visible,而是通過改變圖片透明度來實現(xiàn)選中取消的。
具體看代碼:
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.view.View;
import android.widget.ImageView;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.xxx.Wallpaper;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Created by ly on 2021/4/22 14:11
*/
public class ManageHomeBgAdapter extends BaseSingleSelectAdapter<Wallpaper> {
public ManageHomeBgAdapter(List<Wallpaper> mList) {
super(R.layout.m_item_manage_home_bg, mList, false);
}
@Override
protected void convert(@NotNull BaseViewHolder baseViewHolder, Wallpaper wallInfo) {
super.convert(baseViewHolder, wallInfo);
baseViewHolder.setText(R.id.m_tv_item_home_bg_name, wallInfo.name);
ImageView ivBg = baseViewHolder.getView(R.id.m_iv_item_home_bg);
GlideUtil.loadRound(getContext(), wallInfo.url, ivBg, PixelUtil.dp2px(8));
View iv = baseViewHolder.getView(R.id.m_iv_item_home_bg_sel);
int position = baseViewHolder.getAdapterPosition();
if (wallInfo.isSelected) {
//選中動畫
PropertyValuesHolder vb1 = PropertyValuesHolder.ofFloat(View.SCALE_X, 0.5f, 1.3f, 1f);
PropertyValuesHolder vb2 = PropertyValuesHolder.ofFloat(View.SCALE_Y, 0.5f, 1.3f, 1f);
PropertyValuesHolder vb3 = PropertyValuesHolder.ofFloat(View.ALPHA, 0.5f, 1f);
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(iv, vb1, vb2, vb3);
objectAnimator.setDuration(duration).start();
//背景選中放大動畫(理論上可以使用ItemAnimator實現(xiàn),但我們這里只針對圖片縮放,而不是整個item,所以采用view的動畫實現(xiàn))
ivBg.animate().scaleX(1f).scaleY(1f)
.withEndAction(() -> ivBg.animate().scaleX(1.05f).scaleY(1.05f).setDuration(duration))
.setDuration(0).start();
} else {
//此處只對上次選擇的item執(zhí)行動畫
if (getLastSelIndex() >= 0 && getLastSelIndex() == position) {
ObjectAnimator.ofFloat(iv, "alpha", 1f, 0).setDuration(duration).start();
//背景取消選中動畫
ivBg.animate().scaleX(1.05f).scaleY(1.05f)
.withEndAction(() -> ivBg.animate().scaleX(1f).scaleY(1f).setDuration(duration))
.setDuration(0).start();
} else {
iv.setAlpha(0);
}
}
}
}
對應的item布局,注意,最好用padding來實現(xiàn)item之間的間隙,不然放大后可能由于空間不足導致itemView顯示不全:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:paddingBottom="7dp"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/m_iv_item_home_bg"
android:layout_width="match_parent"
android:layout_height="@dimen/item_wallpaper_h"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:paddingLeft="7dp"
android:paddingRight="7dp"
android:paddingTop="7dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@mipmap/ic_mine_bg" />
<ImageView
android:id="@+id/m_iv_item_home_bg_sel"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginBottom="10dp"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="@+id/m_iv_item_home_bg"
app:layout_constraintEnd_toEndOf="@+id/m_iv_item_home_bg"
app:layout_constraintStart_toStartOf="@+id/m_iv_item_home_bg"
android:src="@mipmap/ic_select_bg" />
<TextView
android:id="@+id/m_tv_item_home_bg_name"
style="@style/text_second_s"
android:paddingTop="9dp"
app:layout_constraintEnd_toEndOf="@+id/m_iv_item_home_bg"
app:layout_constraintStart_toStartOf="@+id/m_iv_item_home_bg"
app:layout_constraintTop_toBottomOf="@+id/m_iv_item_home_bg"
tools:text="壁紙1" />
</androidx.constraintlayout.widget.ConstraintLayout>
父類是我做的封裝,方便其他地方用到,大家酌情參考一下:
import android.annotation.SuppressLint;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.xxx.SelectableItem;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* 單選通用baseAdapter
* 需要注意的是要將recycleView的setItemAnimator設置為null,不然動畫會沖突(錯亂)
* Created by ly on 2021/7/21 16:02
*/
public abstract class BaseSingleSelectAdapter<T extends SelectableItem> extends BaseQuickAdapter<T, BaseViewHolder> {
private int selIndex = -1, lastSelIndex = -1;
/**
* 動畫時長
*/
protected int duration = 300;
/**
* 動畫縮放因子
*/
protected float factor = 0.05f;
private boolean showItemAni = true;
public BaseSingleSelectAdapter(int layoutResId) {
super(layoutResId);
}
public BaseSingleSelectAdapter(int layoutResId, @Nullable List<T> data) {
super(layoutResId, data);
}
public BaseSingleSelectAdapter(int layoutResId, @Nullable List<T> data, boolean showItemAni) {
super(layoutResId, data);
this.showItemAni = showItemAni;
}
/**
* 子類需要調用該方法以獲取準確的selIndex以及item動畫展示
* Created by ly on 2021/7/23 16:04
*/
@Override
protected void convert(@NonNull BaseViewHolder baseViewHolder, T t) {
//選中動畫
if (t.isSelected) {
selIndex = baseViewHolder.getAdapterPosition();
if (showItemAni) scaleUp(baseViewHolder.itemView);
} else {
if (showItemAni) scaleDown(baseViewHolder.itemView);
}
}
public @Nullable
T selectOne(int index) {
if (selIndex != index) {//不處理點擊已選中的情況
if (selIndex >= 0 && selIndex < getItemCount())
getItem(selIndex).isSelected = false;
if (index >= 0 && index < getItemCount()) {
getItem(index).isSelected = true;
}
notifyItemChanged(selIndex);
notifyItemChanged(index);
lastSelIndex = selIndex;
selIndex = index;
}
return getSelectItem();
}
@SuppressLint("NotifyDataSetChanged")
public void selectNone() {
if (selIndex >= 0 && selIndex < getData().size()) {
getData().get(selIndex).isSelected = false;
notifyItemChanged(selIndex);
}else {
for (T datum : getData()) {
datum.isSelected = false;
}
notifyDataSetChanged();
}
selIndex = -1;
}
public @Nullable
T getSelectItem() {
return selIndex >= 0 && selIndex < getItemCount() ? getItem(selIndex) : null;
}
public int getSelectIndex() {
return selIndex;
}
protected int getLastSelIndex() {
return lastSelIndex;
}
protected void scaleUp(View view) {
ViewCompat.animate(view)
.setDuration(duration)
.scaleX(1f + factor)
.scaleY(1f + factor)
.start();
}
protected void scaleDown(View view) {
ViewCompat.animate(view)
.setDuration(duration)
.scaleX(1f)
.scaleY(1f)
.start();
}
}
對應的選中通用實體類,用你自己的類繼承SelectableItem即可:
/**
* Created by ly on 2021/7/21 16:05
*/
public class SelectableItem {
/**
* 是否選中 true:選中
*/
public boolean isSelected;
}
以上的BaseSingleSelectAdapter通用于列表單選場景,使用的時候繼承即可,根據(jù)自己的業(yè)務來吧。
文中代碼依賴第三方庫:BaseRecyclerViewAdapterHelper,如果你用不到,用我貼的核心代碼也能實現(xiàn)動效~
好啦,簡單的選中動畫就實現(xiàn)完成了,建議大家項目里面多用動畫來提升用戶體驗。
總結
到此這篇關于Android列表實現(xiàn)單選點擊縮放動畫效果的文章就介紹到這了,更多相關Android列表點擊縮放內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Golang+Android基于HttpURLConnection實現(xiàn)的文件上傳功能示例
這篇文章主要介紹了Golang+Android基于HttpURLConnection實現(xiàn)的文件上傳功能,結合具體實例形式分析了Android基于HttpURLConnection的客戶端結合Go語言服務器端實現(xiàn)文件上傳功能的操作技巧,需要的朋友可以參考下2017-03-03
Android Flutter利用CustomPaint繪制基本圖形詳解
CustomPaint其實和前端的Canvas基本上是一樣的,前端Canvas支持的繪制方法CustomPaint都支持,畢竟CustomPaint其實也是基于Canvas實現(xiàn)的。本篇我們來介紹 CustomPaint 基本圖形的繪制,感興趣的可以了解一下2022-07-07
Android?動態(tài)加載?so實現(xiàn)示例詳解
這篇文章主要為大家介紹了Android?動態(tài)加載?so實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09
Android pdf viewer在android studio應用問題說明詳解
這篇文章主要介紹了Android pdf viewer在android studio應用問題說明的相關資料,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下2016-09-09
Android SDK命令行工具Monkey參數(shù)及使用解析
這篇文章主要介紹了Android SDK命令行工具Monkey參,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值數(shù)及使用解析,需要的朋友可以參考下2020-10-10
Android?Camera開發(fā)實現(xiàn)可復用的相機組件
這篇文章主要為大家詳細介紹了Android?Camera開發(fā)實現(xiàn)可復用的相機組件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05

