Android中GridView中onTouch监听(1)item实现触摸执行缩放动画的功能

本文介绍如何在Android的GridView中实现点击元素触发缩放动画,并处理ACTION_DOWN, ACTION_MOVE和ACTION_UP事件。当按下并移动离开元素时,元素会恢复原状;点击时则触发跳转。由于监听事件可能导致内置的onItemClickListener失效,作者通过比较按下和抬起时的位置来判断点击事件。" 113320826,10326285,SQL大全:从基础到高级操作详解,"['SQL语法', '数据库管理', '数据操作', '查询优化', '数据库设计']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

功能:当用户点击元素,执行图片缩放动画,当按住元素并且移开位置离开该元素,之前元素将执行放大回到原状,而新选中的元素将进行缩放。

效果图


即: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

<?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"
     />


backgroundanimdown,xml
<?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"
     />


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值