在 AdapterView(如 Gallery、Spinner、ListView)的 onItemSelected 回調中,需對當前選中項啟動縮放動畫,同時清除其他項的動畫。
AdapterView 不直接支持下標訪問子視圖(adView[i] 編譯錯誤),需使用 getChildCount() 和 getChildAt(index) 遍歷。
@Override
public void onItemSelected(AdapterView> adapterView, View view, int position, long id) {
// 1. 當前項啟動動畫
view.startAnimation(AnimationUtils.loadAnimation(context, R.anim.scale_anim));
// 2. 遍歷所有可見子視圖清除動畫
int childCount = adapterView.getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = adapterView.getChildAt(i);
// 跳過當前選中項
if (childView != view) {
childView.clearAnimation();
}
}
}
| 方法 | 說明 |
|---|---|
| getChildCount() | 返回當前佈局的可見子視圖數量(非數據總量) |
| getChildAt(index) | 獲取指定索引的子視圖引用 |
| clearAnimation() | 清除視圖上正在運行的動畫,重置狀態 |
| startAnimation(Animation) | 啟動指定動畫 |
若需精確控制前後項(如 Gallery 中心項放大,兩側項縮小):
int selectedPosition = position; // 當前選中在數據中的位置
int firstVisiblePosition = adapterView.getFirstVisiblePosition(); // 首個可見項在數據中的位置
for (int i = 0; i < childCount; i++) {
View childView = adapterView.getChildAt(i);
int dataPosition = firstVisiblePosition + i; // 計算該視圖對應的數據位置
if (dataPosition == selectedPosition) {
// 當前項:放大
childView.startAnimation(scaleUpAnim);
} else if (dataPosition == selectedPosition - 1 || dataPosition == selectedPosition + 1) {
// 相鄰項:縮小
childView.startAnimation(scaleDownAnim);
} else {
// 其他項:恢復正常
childView.clearAnimation();
childView.setScaleX(1.0f);
childView.setScaleY(1.0f);
}
}
getChildCount() 只返回當前可見的子視圖,非數據總條目數。不可見項無視圖引用。ListView/GridView 復用視圖,onItemSelected 可能不觸發(需設置 setItemsCanFocus(true) 或使用 OnItemClickListener)。clearAnimation() 後建議顯式重置 setScaleX(1f)/setScaleY(1f)/setAlpha(1f)。RecyclerView 替代 ListView,配合 ItemAnimator 實現更流暢的選中/滾動動畫。<set xmlns:android="https://schemas.android.com/apk/res/android">
<scale
android:duration="200"
android:fromXScale="1.0"
android:toXScale="1.2"
android:fromYScale="1.0"
android:toYScale="1.2"
android:pivotX="50%"
android:pivotY="50%" />
</set>