我一直在尝试实现四向滑动导航。我有一些关于如何把事情放在一起的问题。
- 考虑使用片段。会锻炼吗?
- 另一个想法是创建一个大的相对布局并如图所示排列视图。但是在旋转设备纵向/横向时可能会出现问题。
- 以某种方式模拟滑动效果
所有这些要点将如何锻炼?任何人都可以帮助它。我已经找到了有关TouchMove
功能的问题
感谢任何建议和帮助,原因是我对 android 开发比较陌生。
我一直在尝试实现四向滑动导航。我有一些关于如何把事情放在一起的问题。
所有这些要点将如何锻炼?任何人都可以帮助它。我已经找到了有关TouchMove
功能的问题
感谢任何建议和帮助,原因是我对 android 开发比较陌生。
不是那么难的任务,多亏了 Scroller,它几乎是简单的蛋糕
如果您想放置一些交互式视图,例如 Button 等(我打赌您会这样做),您需要覆盖 onInterceptTouchEvent(MotionEvent ev)
public class FourDirectionLayout extends ViewGroup {
private GestureDetector mDetector;
private Scroller mScroller;
private final String[] TEXTS = {
"left view, left swipe only",
"right view, right swipe only",
"top view, top swipe only",
"bottom view, bottom swipe only",
"central view, swipe to the left, right, top or bottom",
};
private final int[] COLORS = {
0xaa0000ff, 0xaa0000ff, 0xaaff0000, 0xaaff0000, 0xaa00ff00
};
private final int[] PACKED_OFFSETS = {
-1, 0, 1, 0, 0, -1, 0, 1, 0, 0
};
public FourDirectionLayout(Context context) {
super(context);
for (int i = 0; i < TEXTS.length; i++) {
TextView tv = new TextView(context);
tv.setTag(i);
tv.setTextSize(32);
tv.setTypeface(Typeface.DEFAULT_BOLD);
tv.setTextColor(0xffeeeeee);
tv.setText(TEXTS[i]);
tv.setBackgroundColor(COLORS[i]);
addView(tv);
}
mDetector = new GestureDetector(context, mListener);
mScroller = new Scroller(context);
}
private OnGestureListener mListener = new SimpleOnGestureListener() {
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (!mScroller.isFinished()) {
return false;
}
int sx = getScrollX();
int sy = getScrollY();
int w = getWidth();
int h = getHeight();
int DURATION = 500;
// check if horizontal/vertical fling
if (Math.abs(velocityX) > Math.abs(velocityY)) {
if (sy != 0 || velocityX * sx < 0) {
return false;
}
// DURATION = (int) (1000 * w / Math.abs(velocityX));
int distance = velocityX < 0? w : -w;
mScroller.startScroll(sx, sy, distance, 0, DURATION);
} else {
if (sx != 0 || velocityY * sy < 0) {
return false;
}
// DURATION = (int) (1000 * h / Math.abs(velocityY));
int distance = velocityY < 0? h : -h;
mScroller.startScroll(sx, sy, 0, distance, DURATION);
}
invalidate();
return true;
}
};
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mDetector.onTouchEvent(event);
return true;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int cnt = getChildCount();
for (int i = 0; i < cnt ; i++) {
View child = getChildAt(i);
int idx = (Integer) child.getTag() << 1;
int xOffset = (r - l) * PACKED_OFFSETS[idx];
int yOffset = (b - t) * PACKED_OFFSETS[idx + 1];
child.layout(l + xOffset, t + yOffset, r + xOffset, b + yOffset);
}
}
}
要对其进行测试,请将其添加到您的 Activity.onCreate 中:
ViewGroup layout = new FourDirectionLayout(this);
setContentView(layout);
这不是一件容易的事,恐怕没有一个做这个和不做那个的答案。
让我们把简单的部分排除在外 - 您检测滑动的方式是使用GestureDetector
. 您将获得一个onFling
(or onScroll
) 事件,然后您可以更新 aScroller
以获取实际坐标。您存储/显示屏幕的方式更加困难。
在我的脑海中,RelativeLayout
动画会有点困难。滚动会很痛苦,尽管通过改变中间的屏幕,让它布局并使用ViewTreeObserver.onPreDraw
动画到新位置(在它们第一次绘制之前),可以更容易地制作动画。我怀疑滚动会有点困难(不过,如果你 extend RelativeLayout
,你可以改变孩子的位置,而不需要重新布局或重新测量,所以也许这不是一个坏主意)。
就我个人而言,我会FrameLayout
在孩子做出反应之前扩展、检测弹跳(请参阅onInterceptTouchEvent
),并在其中放置正确的片段,并带有适当的过渡动画。似乎是考虑它的最简洁的方式。
PS 我希望你可以只使用 DirectionalViewPager 并在运行时更改方向,但问题是中间屏幕 - 它必须响应两个方向。也许从那个类扩展不是一个坏主意......
我能想到的最接近的是谷歌地图以及它们让用户在地图上导航(滚动、翻动和擦除)的方式。
当您使用慢速网络滚动时,您在那里看到的是它们似乎适用于 4x5 网格。因此,放置在网格上的 20 个单张图像。屏幕外的每个方向可能还有一个。
你现在需要做两件事:
获取触摸事件以检测用户想要在哪个位置看到的内容。
将您的内容放在网格上。您可以将网格构建为 FrameLayout 上的 ImageView 或 SurfaceView 上的 Bitmap。使用后者,您可以更好地控制绘图和放置。使用第一个放置文本,按钮等更容易。根据您想要展示的内容,您可以使用其中一种方法。