Unity3D特效百例 | 案例项目实战源码 | Android-Unity实战问题汇总 |
---|---|---|
游戏脚本-辅助自动化 | Android控件全解手册 | 再战Android系列 |
Scratch编程案例 | 软考全系列 | Unity3D学习专栏 |
蓝桥系列 | ChatGPT和AIGC |
👉关于作者
专注于Android/Unity和各种游戏开发技巧,以及各种资源分享(网站、工具、素材、源码、游戏等)
有什么需要欢迎底部卡片私我,交流让学习不再孤单。
👉实践过程
GestureViewBinder
public class GestureViewBinder {private ScaleGestureBinder scaleGestureBinder;private ScrollGestureBinder scrollGestureBinder;private ScaleGestureListener scaleGestureListener;private ScrollGestureListener scrollGestureListener;private View targetView;private ViewGroup viewGroup;private boolean isScaleEnd = true;private OnScaleListener onScaleListener;private boolean isFullGroup = false;public static GestureViewBinder bind(Context context, ViewGroup viewGroup, View targetView) {return new GestureViewBinder(context, viewGroup, targetView);}private GestureViewBinder(Context context, ViewGroup viewGroup, View targetView) {this.targetView = targetView;this.viewGroup = viewGroup;scaleGestureListener = new ScaleGestureListener(targetView, viewGroup);scrollGestureListener = new ScrollGestureListener(targetView, viewGroup);scaleGestureBinder = new ScaleGestureBinder(context, scaleGestureListener);scrollGestureBinder = new ScrollGestureBinder(context, scrollGestureListener);targetView.setClickable(false);viewGroup.setOnTouchListener(new View.OnTouchListener() {@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouch(View v, MotionEvent event) {if (event.getPointerCount() == 1 && isScaleEnd) {return scrollGestureBinder.onTouchEvent(event);} else if (event.getPointerCount() == 2 || !isScaleEnd) {isScaleEnd = event.getAction() == MotionEvent.ACTION_UP;if (isScaleEnd) {scaleGestureListener.onActionUp();}scrollGestureListener.setScale(scaleGestureListener.getScale());if (onScaleListener != null) {onScaleListener.onScale(scaleGestureListener.getScale());}return scaleGestureBinder.onTouchEvent(event);}return false;}});}private void fullGroup() {targetView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {@Overridepublic boolean onPreDraw() {targetView.getViewTreeObserver().removeOnPreDrawListener(this);float viewWidth = targetView.getWidth();float viewHeight = targetView.getHeight();float groupWidth = viewGroup.getWidth();float groupHeight = viewGroup.getHeight();ViewGroup.LayoutParams layoutParams = targetView.getLayoutParams();float widthFactor = groupWidth / viewWidth;float heightFactor = groupHeight / viewHeight;if (viewWidth < groupWidth && widthFactor * viewHeight <= groupHeight) {layoutParams.width = (int) groupWidth;layoutParams.height = (int) (widthFactor * viewHeight);} else if (viewHeight < groupHeight && heightFactor * viewWidth <= groupWidth) {layoutParams.height = (int) groupHeight;layoutParams.width = (int) (heightFactor * viewWidth);}targetView.setLayoutParams(layoutParams);return true;}});}public boolean isFullGroup() {return isFullGroup;}public void setFullGroup(boolean fullGroup) {isFullGroup = fullGroup;scaleGestureListener.setFullGroup(fullGroup);scrollGestureListener.setFullGroup(fullGroup);fullGroup();}public void setOnScaleListener(OnScaleListener onScaleListener) {this.onScaleListener = onScaleListener;}public interface OnScaleListener {void onScale(float scale);}
}
ScaleGestureBinder
public class ScaleGestureBinder extends ScaleGestureDetector {ScaleGestureBinder(Context context, ScaleGestureListener scaleGestureListener) {super(context, scaleGestureListener);}@Overridepublic boolean onTouchEvent(MotionEvent event) {return super.onTouchEvent(event);}}
ScaleGestureListener
public class ScaleGestureListener implements ScaleGestureDetector.OnScaleGestureListener/*, GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener */ {private View targetView;private float scale = 1;private float scaleTemp = 1;private boolean isFullGroup = false;ScaleGestureListener(View targetView, ViewGroup viewGroup) {this.targetView = targetView;}@Overridepublic boolean onScale(ScaleGestureDetector detector) {scale = scaleTemp * detector.getScaleFactor();targetView.setScaleX(scale);targetView.setScaleY(scale);return false;}@Overridepublic boolean onScaleBegin(ScaleGestureDetector detector) {return true;}@Overridepublic void onScaleEnd(ScaleGestureDetector detector) {scaleTemp = scale;}float getScale() {return scale;}public boolean isFullGroup() {return isFullGroup;}void setFullGroup(boolean fullGroup) {isFullGroup = fullGroup;}void onActionUp() {if (isFullGroup && scaleTemp < 1) {scale = 1;targetView.setScaleX(scale);targetView.setScaleY(scale);scaleTemp = scale;}}
}
ScrollGestureBinder
class ScrollGestureBinder extends GestureDetector {ScrollGestureBinder(Context context, ScrollGestureListener scrollGestureListener) {super(context, scrollGestureListener);}
}
ScrollGestureListener
public class ScrollGestureListener extends GestureDetector.SimpleOnGestureListener {private float scale = 1;private View targetView;private ViewGroup viewGroup;private float distanceXTemp = 0;private float distanceYTemp = 0;private float viewWidthReal = 0;private float viewHeightReal = 0;private float viewWidthRealTemp = 0;private float viewHeightRealTemp = 0;private boolean isCalculate = false;private int viewWidthNormal = 0;private int viewHeightNormal = 0;private int groupWidth = 0;private int groupHeight = 0;private float maxTranslationLeft = 0;private float maxTranslationTop = 0;private float maxTranslationRight = 0;private float maxTranslationBottom = 0;private boolean isFullGroup = false;ScrollGestureListener(View targetView, ViewGroup viewGroup) {this.targetView = targetView;this.viewGroup = viewGroup;}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {distanceX = -distanceX;distanceY = -distanceY;if (isFullGroup || scale > 1) {if (viewWidthReal > groupWidth) {translationXOnScrollEvent(distanceX);}if (viewHeightReal > groupHeight) {translationYOnScrollEvent(distanceY);}} else {translationXOnScrollEvent(distanceX);translationYOnScrollEvent(distanceY);}return super.onScroll(e1, e2, distanceX, distanceY);}private void translationXOnScrollEvent(float distanceX) {//最大移动距离全部为正数,所以需要通过判断distanceX的正负,来判断是向左移动还是向右移动,// 然后通过取distanceX的绝对值来和相应移动方向的最大移动距离比较if ((distanceX < 0 && Math.abs(distanceXTemp + distanceX) < maxTranslationLeft)|| (distanceX > 0 && distanceXTemp + distanceX < maxTranslationRight)) {distanceXTemp += distanceX;targetView.setTranslationX(distanceXTemp);//如果超出边界,就移动到最大距离,防止边界有剩余量} else if ((distanceX < 0 && Math.abs(distanceXTemp + distanceX) > maxTranslationLeft)) {distanceXTemp = -maxTranslationLeft;targetView.setTranslationX(-maxTranslationLeft);} else if ((distanceX > 0 && distanceXTemp + distanceX > maxTranslationRight)) {distanceXTemp = maxTranslationRight;targetView.setTranslationX(maxTranslationRight);}}private void translationYOnScrollEvent(float distanceY) {if ((distanceY < 0 && Math.abs(distanceYTemp + distanceY) < maxTranslationTop)|| (distanceY > 0 && distanceYTemp + distanceY < maxTranslationBottom)) {distanceYTemp += distanceY;targetView.setTranslationY(distanceYTemp);//如果超出边界,就移动到最大距离,防止边界有剩余量} else if ((distanceY < 0 && Math.abs(distanceYTemp + distanceY) > maxTranslationTop)) {distanceYTemp = -maxTranslationTop;targetView.setTranslationY(-maxTranslationTop);} else if ((distanceY > 0 && distanceYTemp + distanceY > maxTranslationBottom)) {distanceYTemp = maxTranslationBottom;targetView.setTranslationY(maxTranslationBottom);}}@Overridepublic boolean onDown(MotionEvent e) {//计算能移动的最大距离if (!isCalculate) {isCalculate = true;maxTranslationLeft = targetView.getLeft();maxTranslationTop = targetView.getTop();maxTranslationRight = viewGroup.getWidth() - targetView.getRight();maxTranslationBottom = viewGroup.getHeight() - targetView.getBottom();viewWidthNormal = targetView.getWidth();viewHeightNormal = targetView.getHeight();viewWidthRealTemp = viewWidthNormal;viewHeightRealTemp = viewHeightNormal;viewWidthReal = viewWidthNormal;viewHeightReal = viewHeightNormal;groupWidth = viewGroup.getWidth();groupHeight = viewGroup.getHeight();}return true;}void setScale(float scale) {viewWidthReal = viewWidthNormal * scale;viewHeightReal = viewHeightNormal * scale;//如果view比group小if (viewWidthReal < groupWidth) {if (isFullGroup) {distanceXTemp = 0;targetView.setTranslationX(0);}maxTranslationLeft = targetView.getLeft() - (viewWidthReal - viewWidthNormal) / 2;maxTranslationRight = (viewGroup.getWidth() - targetView.getRight()) - (viewWidthReal - viewWidthNormal) / 2;//如果移动距离超过最大可移动距离if (scale > this.scale && distanceXTemp < 0 && -distanceXTemp > maxTranslationLeft) {float translate = (viewWidthReal - viewWidthRealTemp) / 2;targetView.setTranslationX(targetView.getTranslationX() + translate);distanceXTemp = distanceXTemp + translate;} else if (scale > this.scale && distanceXTemp > 0 && distanceXTemp > maxTranslationRight) {float translate = (viewWidthReal - viewWidthRealTemp) / 2;targetView.setTranslationX(targetView.getTranslationX() - translate);distanceXTemp = distanceXTemp - translate;}} else {maxTranslationLeft = (viewWidthReal - viewWidthNormal) / 2 - (viewGroup.getWidth() - targetView.getRight());maxTranslationRight = (viewWidthReal - viewWidthNormal) / 2 - targetView.getLeft();if (scale < this.scale && distanceXTemp < 0 && -distanceXTemp > maxTranslationLeft) {float translate = (viewWidthRealTemp - viewWidthReal) / 2;targetView.setTranslationX(targetView.getTranslationX() + translate);distanceXTemp = distanceXTemp + translate;} else if (scale < this.scale && distanceXTemp > 0 && distanceXTemp > maxTranslationRight) {float translate = (viewWidthRealTemp - viewWidthReal) / 2;targetView.setTranslationX(targetView.getTranslationX() - translate);distanceXTemp = distanceXTemp - translate;}}if (viewHeightReal < groupHeight) {maxTranslationTop = targetView.getTop() - (viewHeightReal - viewHeightNormal) / 2;maxTranslationBottom = (viewGroup.getHeight() - targetView.getBottom()) - (viewHeightReal - viewHeightNormal) / 2;if (isFullGroup) {distanceYTemp = 0;targetView.setTranslationY(0);}//如果移动距离超过最大可移动距离if (scale > this.scale && distanceYTemp < 0 && -distanceYTemp > maxTranslationTop) {float translate = (viewHeightReal - viewHeightRealTemp) / 2;targetView.setTranslationY(targetView.getTranslationY() + translate);distanceYTemp = distanceYTemp + translate;} else if (scale > this.scale && distanceYTemp > 0 && distanceYTemp > maxTranslationBottom) {float translate = (viewHeightReal - viewHeightRealTemp) / 2;targetView.setTranslationY(targetView.getTranslationY() - translate);distanceYTemp = distanceYTemp - translate;}} else {maxTranslationTop = (viewHeightReal - viewHeightNormal) / 2 - (viewGroup.getHeight() - targetView.getBottom());maxTranslationBottom = (viewHeightReal - viewHeightNormal) / 2 - targetView.getTop();if (scale < this.scale && distanceYTemp < 0 && -distanceYTemp > maxTranslationTop) {float translate = (viewHeightRealTemp - viewHeightReal) / 2;targetView.setTranslationY(targetView.getTranslationY() + translate);distanceYTemp = distanceYTemp + translate;} else if (scale < this.scale && distanceYTemp > 0 && distanceYTemp > maxTranslationBottom) {float translate = (viewHeightRealTemp - viewHeightReal) / 2;targetView.setTranslationY(targetView.getTranslationY() - translate);distanceYTemp = distanceYTemp - translate;}}viewWidthRealTemp = viewWidthReal;viewHeightRealTemp = viewHeightReal;this.scale = scale;}@Overridepublic boolean onSingleTapUp(MotionEvent e) {float left = viewWidthReal > groupWidth ? 0 : (targetView.getLeft() - ((viewWidthReal - viewWidthNormal) / 2));float top = viewHeightReal > groupHeight ? 0 : (targetView.getTop() - ((viewHeightReal - viewHeightNormal) / 2));float right = viewWidthReal > groupWidth ? groupWidth : viewGroup.getWidth() - ((viewGroup.getWidth() - targetView.getRight()) - (viewWidthReal - viewWidthNormal) / 2);float bottom = viewHeightReal > groupHeight ? groupHeight : viewGroup.getHeight() - ((viewGroup.getHeight() - targetView.getBottom()) - (viewHeightReal - viewHeightNormal) / 2);RectF rectF = new RectF(left, top, right, bottom);if (rectF.contains(e.getX(), e.getY())) {targetView.performClick();}return super.onSingleTapUp(e);}public boolean isFullGroup() {return isFullGroup;}void setFullGroup(boolean fullGroup) {isFullGroup = fullGroup;}
}
👉其他
📢作者:小空和小芝中的小空
📢转载说明-务必注明来源:https://zhima.blog.csdn.net/
📢这位道友请留步☁️,我观你气度不凡,谈吐间隐隐有王者霸气💚,日后定有一番大作为📝!!!旁边有点赞👍收藏🌟今日传你,点了吧,未来你成功☀️,我分文不取,若不成功⚡️,也好回来找我。
温馨提示:点击下方卡片获取更多意想不到的资源。