溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android列表怎么實現(xiàn)單選點擊縮放動畫效果

發(fā)布時間:2021-08-03 10:09:57 來源:億速云 閱讀:271 作者:chen 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Android列表怎么實現(xiàn)單選點擊縮放動畫效果”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

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

Android列表怎么實現(xiàn)單選點擊縮放動畫效果

圖中的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);
            }
        }
    }
}

對應(yīng)的item布局,注意,最好用padding來實現(xiàn)item之間的間隙,不然放大后可能由于空間不足導(dǎo)致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"
        
        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設(shè)置為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;
    }

    /**
     * 子類需要調(diào)用該方法以獲取準(zhǔn)確的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();
    }
}

對應(yīng)的選中通用實體類,用你自己的類繼承SelectableItem即可:

/**
 * Created by ly on 2021/7/21 16:05
 */
public class SelectableItem {
    /**
     * 是否選中 true:選中
     */
    public boolean isSelected;

}

以上的BaseSingleSelectAdapter通用于列表單選場景,使用的時候繼承即可,根據(jù)自己的業(yè)務(wù)來吧。

文中代碼依賴第三方庫:BaseRecyclerViewAdapterHelper,如果你用不到,用我貼的核心代碼也能實現(xiàn)動效~

“Android列表怎么實現(xiàn)單選點擊縮放動畫效果”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI