Android:四方向导航

我一直在尝试实现四个定向滑动导航。 我对如何把事情放在一起有一些问题。

  1. 考虑使用片段。 它会锻炼吗?
  2. 另一个想法是创建一个大的相对布局并安排如图所示的视图。 但是在旋转设备portait / landscape时可能会出现问题。
  3. 以某种方式模仿滑动效果

所有这些要点如何锻炼? 任何人都可以帮助它。 我已经找到了有关TouchMovefunction的问题

  1. 只在四个方向触摸运动?
  2. 网格布局上的手势检测
  3. https://github.com/JakeWharton/Android-DirectionalViewPager/

任何建议和帮助表示赞赏,原因是我对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 (或onScroll )事件,然后您可以更新Scroller以获取实际坐标。 存储/显示屏幕的方式更加困难。

在我的头顶, RelativeLayout有点难以制作动画。 滚动可能会很痛苦,虽然通过更改中间的屏幕,让它布局并使用ViewTreeObserver.onPreDraw设置动画到新位置(在它们首次绘制之前),可以更容易地进行动画制作。 滚动会有点困难,我怀疑(但是,如果你扩展RelativeLayout ,你可以改变孩子的位置,没有重新布局或重新测量,所以也许这不是一个坏主意)。

就个人而言,我会扩展FrameLayout ,在孩子们做出反应之前检测onInterceptTouchEvent (参见onInterceptTouchEvent )并将正确的片段放在那里,并使用适当的过渡动画。 似乎是思考它的最佳方式。

PS我希望你可以使用DirectionalViewPager并在运行时改变方向,但问题是中间屏幕 – 它必须响应两个方向。 也许延伸到那个class级并不是一个坏主意……

我能想到的最接近的是谷歌地图以及他们让用户通过地图导航(滚动,投掷和擦除)的方式。

当您使用慢速网络滚动时,您看到的是它们似乎使用4×5网格。 所以20个单个图像放在网格上。 屏幕上的每个方向可能还有一个。

你现在需要做两件事:

  • 获取触摸事件以检测用户想要在哪个位置看到的内容。

  • 将您的内容放在网格上。 您可以将网格构建为FrameLayout上的ImageView,也可以构建为SurfaceView上的Bitmap。 使用后者,您可以更好地控制绘图和放置。 使用第一个放置文本,按钮等更容易。 根据您想要展示的内容,您可以使用这些方法。