Android中GridView中onTouch監聽(1)item實現觸控執行縮放動畫的功能
阿新 • • 發佈:2019-01-30
功能:當用戶點選元素,執行圖片縮放動畫,當按住元素並且移開位置離開該元素,之前元素將執行放大回到原狀,而新選中的元素將進行縮放。
效果圖
即:gridview中的元素按住就會下陷變小,移動離開就會變回原樣,點選就會進入跳轉介面
由於為了完整的監聽ontouch事件,即能監聽ACTION_DOWN,MOVE,UP返回值必須為true
但是由於為true導致事件被攔截了,之後的自帶的onItemClickListener的監聽事件不能在使用了
這裡我通過判斷點選時候的位置的item和擡起的item的位置,進行點選事件的判斷
寫了一個工具類,程式碼如下
package com.example.util; import android.content.Context; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.GridView; import android.widget.Toast; import com.example.test.R; public class AnimationUtil { // action down按下動畫 private static Animation downAnimation; // action up動畫 private static Animation upAnimation; // 前一個元素 private static int tempChildViewId = -1; // 按下時候的元素,設定為公有方便之後檢視 public static int downChildViewId = -1; // 擡起時候的元素,設定為公有方便之後檢視 public static int upChildViewId = -2; private static boolean isLastView = true; /** * 點選每個gridView元素將執行動畫 * * @param v * @param event */ public static void AnimationAlgorithm(View v, MotionEvent event, Context context) { // 判斷是不是GridView的v if (!(v instanceof GridView)) return; GridView parent = ((GridView) v); int count = parent.getChildCount(); // 沒有元素不做動畫 if (count == 0) return; // 獲得每個元素的大小。這裡每個gridView的元素都是相同大小的,取第一個為例。 int childWidth = parent.getChildAt(0).getWidth() + 10; int childHeight = parent.getChildAt(0).getHeight() + 2; Log.d("count", "==" + count); // 進行事件監聽 switch (event.getAction()) { // 按下的時候,獲得當前元素的id,由於我一行是3個,所以我的y方向上就必須乘以3 // 例如我按下的是第3個(從第0個開始,第三個為第二行第一列),那麼第三個=點選x的大小/子元素的x的大小+(點選y的大小/子元素的y的大小)*3=0+3=3、 case MotionEvent.ACTION_DOWN: { // 重置 tempChildViewId = -1; downChildViewId = -1; upChildViewId = -2; isLastView = true; // 三目運算子 int currentChildViewId = ((int) event.getX() / childWidth + (int) event .getY() / childHeight * 3) < count ? ((int) event.getX() / childWidth + (int) event.getY() / childHeight * 3) : -1; // 開始按沒按在存在的元素中的時候這個動畫不做 if (currentChildViewId == -1) return; downAnimation = AnimationUtils.loadAnimation(context, R.anim.backgroundanimdown); parent.getChildAt(currentChildViewId).startAnimation(downAnimation); tempChildViewId = currentChildViewId; downChildViewId = currentChildViewId; break; } // 通過位置判斷是哪個item,做對應的動畫 case MotionEvent.ACTION_MOVE: { // 計算出當前chidView的位於gridView中的位置 int currentChildViewId = ((int) event.getX() / childWidth + (int) event .getY() / childHeight * 3) < count ? ((int) event.getX() / childWidth + (int) event.getY() / childHeight * 3) : -1; // 當之前一個元素存在,而移動到不存在元素的區域的時候,需要立即將之前圖片擡起 //由於這個方法只讓他走一次。設定了一個isLastView的boolean引數 if (tempChildViewId != -1 && currentChildViewId == -1 && isLastView) { Log.d("movemove", "movemove"); isLastView = false; upAnimation = AnimationUtils.loadAnimation(context, R.anim.backgroundanimup); parent.getChildAt(tempChildViewId).startAnimation(upAnimation); return; } if (currentChildViewId == -1) return; // 當前元素與之前元素相同,不執行變化操作。 if (currentChildViewId != tempChildViewId) { // 表示從不存在的元素移動到存在的元素的時候。只需要做按下操作即可 if (tempChildViewId == -1) { downAnimation = AnimationUtils.loadAnimation(context, R.anim.backgroundanimdown); parent.getChildAt(currentChildViewId).startAnimation( downAnimation); } else { // 表示從存在的元素移動到另外一個存在的元素的時候。只需要做按下操作即可 // 原來的動畫變成彈起。之後的那個執行新的動畫 upAnimation = AnimationUtils.loadAnimation(context, R.anim.backgroundanimup); parent.getChildAt(tempChildViewId).startAnimation( upAnimation); downAnimation = AnimationUtils.loadAnimation(context, R.anim.backgroundanimdown); parent.getChildAt(currentChildViewId).startAnimation( downAnimation); } // 改變前一個元素的位置。 tempChildViewId = currentChildViewId; } break; } // 擡起,鬆手的時候 case MotionEvent.ACTION_UP: { int currentChildViewId = ((int) event.getX() / childWidth + (int) event .getY() / childHeight * 3) < count ? ((int) event.getX() / childWidth + (int) event.getY() / childHeight * 3) : -1; Log.d("currentChildViewId", currentChildViewId + ""); // 按下和擡起都在無效位置的話,do nothing if (currentChildViewId == -1) return; // 其他情況下,需要收起當前的動畫 upAnimation = AnimationUtils.loadAnimation(context, R.anim.backgroundanimup); parent.getChildAt(currentChildViewId).startAnimation( upAnimation); upChildViewId = currentChildViewId; } default: break; } } }
設定監聽事件,通過判斷按下和擡起時候的位置是否相同進行跳轉
typeActivity_gridview.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { AnimationUtil.AnimationAlgorithm(v, event, TypeActivity.this); // true攔截事件,不會走onclick,這裡自己寫方法吧 //判斷按下去和擡起是不是同一個元素,是的話執行跳轉 if (AnimationUtil.downChildViewId == AnimationUtil.upChildViewId) { onclickdata(); } return true; });
補充兩個xml
backgroundanimup,xml
backgroundanimdown,xml<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:fromXScale="0.8" android:fromYScale="0.8" android:toXScale="1" android:toYScale="1" android:pivotX="50%" android:pivotY="50%" android:fillAfter="true" android:duration="500" />
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1"
android:fromYScale="1"
android:toXScale="0.8"
android:toYScale="0.8"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="true"
android:duration="300"
/>