期望的效果 我有一堆小图像,我想在"墙"上显示,然后让用户在任何方向投掷这个墙并选择一个图像.
最初的想法 作为一种可能的实现我在想一个比屏幕更大的GridView可以显示 - 但是使用这个小部件的所有例子都表明Gallery没有扩展到超出屏幕的大小.
问题 用于实现所需效果的最佳小部件是什么?代码示例将特别有益.
编辑... 如果有人的示例代码可以让我在"墙上"放置约30张图片(表格会很好),那么我会接受这个作为答案.请注意,"墙"看起来应该超出显示器的边缘,并允许用户使用手指将"墙"向上拖动到左下方.拖动应该处于"自由格式"模式.单击图像就可以选择它,并且可以检测到回调.我为这个解决方案创造了一笔赏金.
Fuz*_*gic 11
解决方案实际上很简单,但很痛苦.我必须在我最近做的一个程序中实现这一点.虽然你有一些棘手的事情需要解决.必须注意的是,不同的OS版本具有不同的体验.由于这种方法有时会对绘图产生不利影响,因此需要某些专业知识或用于解决这些问题.虽然我有一个工作副本,但我提供的代码并不适合所有人,并且受到代码中进行的任何其他更改或自定义的影响.
android:layout_width为wrap_contentandroid:layout_height为wrap_contentsetStretchMode(NO_STRETCH);setNumColumns(列数);setColumnWidth(明确的像素宽度);scrollBy()在你的onTouchEvent()这些是步骤.所有这些都是必需的,以使其工作.关键是NO_STRETCH,具有特定宽度的明确列数.如果您需要澄清,可以提供更多详细信息.您甚至可以使用VelocityTracker或onFling来处理投掷.我已经启用了snappingToPage.使用此解决方案,甚至没有要求覆盖onDraw()或onLayout().这三行代码摆脱了对WebView或任何其他嵌入或嵌套的需求.
双向滚动也很容易实现.这是一个简单的代码解决方案:
首先,在你的班级中,通过制作两个班级成员来开始跟踪X和Y的位置.还添加状态跟踪;
// Holds the last position of the touch event (including movement)
int myLastX;
int myLastY;
// Tracks the state of the Touch handling
final static private int TOUCH_STATE_REST = 0;
final static private int TOUCH_STATE_SCROLLING = 1;
int myState = TOUCH_STATE_REST;
Run Code Online (Sandbox Code Playgroud)其次,请务必检查滚动,这样您仍然可以单击或长按图像本身.
@Override public boolean onInterceptTouchEvent(final MotionEvent ev)
{//User is already scrolling something. If we haven't interrupted this already,
// then something else is handling its own scrolling and we should let this be.
// Once we return TRUE, this event no longer fires and instead all goes to
// onTouch() until the next TouchEvent begins (often beginning with ACTION_DOWN).
if ((ev.getAction() == MotionEvent.ACTION_MOVE)
&& (myState != TOUCH_STATE_REST))
return false;
// Grab the X and Y positions of the MotionEvent
final float _x = ev.getX();
final float _y = ev.getY();
switch (ev.getAction())
{ case MotionEvent.ACTION_MOVE:
final int _diffX = (int) Math.abs(_x - myLastX);
final int _diffY = (int) Math.abs(_y - myLastY);
final boolean xMoved = _diffX > 0;
final boolean yMoved = _diffY > 0;
if (xMoved || yMoved)
myState = TOUCH_STATE_SCROLLING;
break;
case MotionEvent.ACTION_DOWN:
// Remember location of down touch
myLastX = _x;
myLastY = _y;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (myState == TOUCH_STATE_SCROLLING)
// Release the drag
myState = TOUCH_STATE_REST;
}
//If we are not At Rest, start handling in our own onTouch()
return myState != TOUCH_STATE_REST;
}
Run Code Online (Sandbox Code Playgroud)在GridView知道您正在滚动之后,它会将所有触摸事件发送到onTouch.你在这里滚动吗?
@Override public boolean onTouchEvent(final MotionEvent ev)
{
final int action = ev.getAction();
final float x = ev.getX();
final float y = ev.getY();
final View child;
switch (action)
{
case MotionEvent.ACTION_DOWN:
//Supplemental code, if needed
break;
case MotionEvent.ACTION_MOVE:
// This handles Scrolling only.
if (myState == TOUCH_STATE_SCROLLING)
{
// Scroll to follow the motion event
// 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;
scrollBy(deltaX, deltaY);
}
break;
case MotionEvent.ACTION_UP:
// If Scrolling, stop the scroll so we can scroll later.
if (myState == TOUCH_STATE_SCROLLING)
myState = TOUCH_STATE_REST;
break
case MotionEvent.ACTION_CANCEL:
// This is just a failsafe. I don't even know how to cancel a touch event
myState = TOUCH_STATE_REST;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)如果当然,此解决方案同时在X和Y处移动.如果您想一次只移动一个方向,则可以通过检查X和Y差异中的较大值来轻松区分.(即Math.abs(deltaX) > Math.abs(deltaY))下面是一个方向滚动的部分样本,但可以在X或Y方向之间切换.
3B.OnTouch()如果您想一次处理一个方向,请在您的内容中进行更改:
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;
Run Code Online (Sandbox Code Playgroud)
FuzzicalLogic
A GridView可以具有超出屏幕大小的内容,但仅限于垂直方向.
问题:用于实现所需效果的最佳小部件是什么?
没有实现2D滚动的默认小部件(至少在3.0之前).它们都只实现1D(单向滚动).可悲的是,你的问题的解决方案并不那么容易.
你可以:
TableLayout自定义ScrollView类,并自己处理触摸事件.这将允许您进行适当的2D平移,但对于大型数据集不会那么好,因为没有视图回收GridView如果可能,修改以启用水平滚动功能(如果可以的话,可能是最好的解决方案)TableLayout放入一个ScrollView(带layout_width="wrap_content)放入其中HorizontalScrollView- 虽然这可能有效,但它不是最佳解决方案| 归档时间: |
|
| 查看次数: |
2743 次 |
| 最近记录: |