首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >想要实现一个墙(GridView?)它会离开屏幕,用户可以触摸移动它。

想要实现一个墙(GridView?)它会离开屏幕,用户可以触摸移动它。
EN

Stack Overflow用户
提问于 2011-05-07 00:48:04
回答 4查看 2.8K关注 0票数 19

想要的效果,,我有一堆小图片,我想要显示在“墙壁”,然后让用户抛向任何方向,并选择一个图像。

Initial Idea作为一种可能的实现--我认为一个比屏幕还大的GridView可以显示--但是使用这个小部件的所有例子都表明,图片库并没有超出屏幕的大小。

问题,实现所需效果的最佳小部件是什么?代码示例将特别有益。

编辑.,如果有人有示例代码,可以让我把大约30幅图片放在“墙上”(表很好),那么我会接受这个答案。请注意,“墙”应该看起来像是超出了显示的边缘,并允许用户使用手指将“墙”拖向左向右。拖动应以“自由形式”模式进行。在图像上的一个点击选择它和回调应该是可检测的。我已经为这个解决方案创造了一笔奖金。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-10-11 22:42:15

解决办法其实很简单,但很痛苦。我必须在我最近做的一个程序中实现这一点。有一些棘手的事情,但你必须绕开。必须指出,不同的操作系统版本有不同的经验。要完成这项工作,需要一定的专业知识或排他性,因为绘图有时会受到这种方法的不利影响。虽然I有一个工作副本,但我提供的代码并不是为每个人提供的,并且会受到代码中进行的任何其他更改或自定义的影响。

  • android:layout_width设置为wrap_content
  • android:layout_height设置为wrap_content
  • 在代码中:
    • 确定您将拥有多少行。
    • 将项目数除以行数。
    • 添加gridView.setStretchMode(NO_STRETCH);
    • 添加gridView.setNumColumns(列数);
    • 添加gridView.setColumnWidth(显式宽度(以像素);为单位)

  • 转到滚动:
    • 您可以在您的gridView.scrollBy()中简单地使用onTouchEvent()

这些是步骤。所有这些都是为了让它发挥作用而需要的。关键是具有特定宽度的显式列数的NO_STRETCH。如果您需要澄清,可以提供更多的详细信息。您甚至可以使用VelocityTracker或onFling来处理抛出。我的snappingToPage已经启用了。使用此解决方案,甚至不需要覆盖onDraw()onLayout()。这三行代码消除了对WebView或任何其他嵌入或嵌套的需求。

双向滚动也很容易实现。下面是一个简单的代码解决方案:

  1. 首先,在您的班级中,通过让两个类成员开始跟踪X和Y的位置。还增加国家跟踪; //保持触摸事件(包括移动) int myLastX的最后位置;int myLastY;//跟踪触摸处理最终静态int TOUCH_STATE_REST = 0;最终静态int TOUCH_STATE_SCROLLING = 1;int myState = TOUCH_STATE_REST;
  2. 第二,确保检查滚动,这样您仍然可以单击或长击图像本身。 @重写公共布尔值onInterceptTouchEvent(final MotionEvent ev) {//MotionEvent用户已经在滚动某些内容。如果我们还没有中断它,//那么其他东西正在处理它自己的滚动,我们应该让它这样做。//一旦返回TRUE,该事件就不再触发,而是全部转到// onTouch(),直到下一个TouchEvent开始(通常以ACTION_DOWN开头)。如果((ev.getAction() == MotionEvent.ACTION_MOVE)和& (myState != TOUCH_STATE_REST))返回false;//获取MotionEvent最终浮点数_x =ev.getX()的X和Y位置;最终浮点数_y = ev.getY();开关(ev.getAction()) { case MotionEvent.ACTION_MOVE: final int _diffX = (int) Math.abs(_x - myLastX);final int _diffY = (int) Math.abs(_y - myLastY);最终布尔xMoved = _diffX > 0;最终布尔yMoved = _diffY > 0;if (xMoved欧元/_diffY) myState = TOUCH_STATE_SCROLLING;case;case MotionEvent.ACTION_DOWN: // Remember of down touch myLastX = _x;myLastY = _y;MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (myState == TOUCH_STATE_SCROLLING) //释放拖动myState = TOUCH_STATE_REST;}//如果我们没有休息,则开始在我们自己的onTouch()中处理返回myState != TOUCH_STATE_REST;}
  3. 在GridView知道您正在滚动之后,它将将所有的Touch事件发送到onTouch。在这里滚动。 @覆盖公共布尔值onTouchEvent( MotionEvent ev) { final action = ev.getAction();最终浮点数x= ev.getX();最终浮点数y= ev.getY();final子视图;开关(操作){ case MotionEvent.ACTION_DOWN: //补充代码(如果需要的话);大小写MotionEvent.ACTION_MOVE: //这只处理滚动。如果(myState == TOUCH_STATE_SCROLLING) { //滚动以跟踪运动事件//,则只要手指向下,这将更新vars。final int deltaX = ( int ) (myLastX - x);final int deltaY = (int) (myLastY - y);myLastX = x;myLastY = y;scrollBy(deltaX,deltaY);} break;case MotionEvent.ACTION_UP: //如果滚动,则停止滚动,以便我们以后滚动。if (myState == TOUCH_STATE_SCROLLING) myState = TOUCH_STATE_REST;断开case MotionEvent.ACTION_CANCEL: //这只是一个故障安全。我甚至不知道如何取消触摸事件myState = TOUCH_STATE_REST;}返回true;}

当然,这个解在X和Y同时移动。如果你想一次只移动一个方向,你可以很容易地通过检查X和Y之间的差异来区分。(即Math.abs(deltaX) > Math.abs(deltaY))下面是一个方向滚动的部分样本,但可以在X方向或Y方向之间切换。

3b。如果您想一次处理一个方向,请在OnTouch()中更改此操作:

代码语言:javascript
复制
            case MotionEvent.ACTION_MOVE:
                if (myState == TOUCH_STATE_SCROLLING)
                {
                    //This will update the vars as long as your finger is down.
                    final int deltaX = (int) (myLastX - x);
                    final int deltaY = (int) (myLastY - y);
                    myLastX = x;
                    myLastY = y;

                    // Check which direction is the bigger of the two
                    if (Math.abs(deltaX) > Math.abs(deltaY))
                        scrollBy(deltaX, 0);
                    else if (Math.abs(deltaY) > Math.abs(deltaX))
                        scrollBy(0, deltaY);
                    // We do nothing if they are equal.
                }
                break;

FuzzicalLogic

票数 11
EN

Stack Overflow用户

发布于 2011-05-07 01:08:17

GridView可以有超出屏幕大小的内容,但只能在垂直方向扩展。

问题:实现所需效果的最佳小部件是什么?

这些不是实现2D滚动的默认小部件(至少在3.0之前)。它们都只实现一维(单向滚动)。不幸的是,解决你的问题并不是那么容易。

你可以:

  • 在自定义的TableLayout类中放置一个ScrollView,并自己处理触摸事件。这将允许您执行正确的2D平移操作,但对于大型数据集则不太好,因为不需要回收视图。
  • 如果可能,修改GridView以启用水平滚动功能(如果可以的话,可能是最好的解决方案)
  • 尝试将TableLayout放入ScrollView (使用layout_width="wrap_content),并将其放入HorizontalScrollView中--尽管这可能有效,但这并不是最佳的解决方案
  • 用OpenGL做点什么,然后直接画到画布上--默认的图库3D应用程序是这样做的--它是“图片墙”
票数 5
EN

Stack Overflow用户

发布于 2011-05-12 12:55:40

我认为这方面唯一的Android原生解决方案是有一个嵌入式WebView,您可以在其中拥有二维滚动(顺便说一句,这是唯一具有这种功能的东西)。

在按下图像时,可以通过从JavaScript到JAva的回调来控制行为。

这不是很“漂亮”但是..。这是唯一可行的方式来做你想要的“开箱即用”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5918412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档