2013-10-09 59 views
2

我一直在嘗試實施四向定向滑動導航。我有一些關於如何把事情放在一起的問題。Android:四向導航

  1. 考慮使用片段。它會鍛鍊嗎?
  2. 另一個想法是創建一個很大的相對佈局和排列視圖如圖所示。但是在旋轉設備portait/landscape時可能會遇到問題。
  3. 不知怎的,模仿刷卡效果

所有這些問題將如何鍛鍊?任何人都可以幫助它。 我已經找到關於向TouchMove功能

  1. Touch movement in only four directions?
  2. Fling gesture detection on grid layout
  3. https://github.com/JakeWharton/Android-DirectionalViewPager/

任何建議和幫助表示讚賞的問題,其原因是,我是比較新的Android開發。

enter image description here

+0

'另一個想法是創建一個大相對佈局和排列視圖如圖所示。但是在旋轉設備portait/landscape時可能會遇到問題。如果您還爲橫向模式實施佈局,則應該沒有問題。 –

回答

4

不是那麼難的任務,由於滾輪它幾乎容易蛋糕

如果你想放一些互動瀏覽喜歡按鈕等

(我敢打賭,你會)你需要重寫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); 
+0

整潔。我建議Fragments的原因是因爲我認爲視圖會很沉重,而且我討厭擁有甚至看不到的大量視圖樹。 (並且在你的解決方案中,他們都將被散步*和*畫在屏幕外)。但是,是的,我過於複雜,主要是因爲我在動畫方面思考,而不是經典的滾動(我以前在處理嵌套滾動時遇到過......)。 – Delyan

+0

@pskink它的工作:)謝謝 – sultan

+0

@sultan更新到優化實施,減少約30等待線的類 – pskink

1

不是一項容易的任務,恐怕沒有一個做這和鴕鳥政策-DO,這個問題的答案。

讓我們輕鬆一點 - 您檢測滑動的方式是使用GestureDetector。您將獲得onFling(或onScroll)事件,然後您可以更新Scroller以獲取實際座標。您存儲/顯示屏幕的方式更加困難。

關閉我的頭頂,RelativeLayout將有點難以動畫。滾動是一件很痛苦的事情,雖然通過改變中間的屏幕可以更輕鬆地製作動畫,讓它佈置並使用ViewTreeObserver.onPreDraw爲新位置設置動畫(在第一次繪製之前)。滾動會有點困難,我懷疑(但是,如果你擴展RelativeLayout,你可以改變孩子的位置,沒有重新佈局或重新測量,所以也許這不是一個壞主意)。

個人而言,我會延長FrameLayout,在孩子可以做出反應之前檢測到fl(聲(請參閱onInterceptTouchEvent),並在其中放入正確的片段並帶有適當的過渡動畫。似乎是思考它的最好方法。

P.S.我希望你可以使用DirectionalViewPager並在運行時改變方向,但問題是中間屏幕 - 它必須響應兩個方向。也許從該類延伸不是一個壞主意......

+0

謝謝@Delyan。我會用'FrameLayout'嘗試一下,結果一到,就會發佈一個屏幕截圖。 – sultan

+0

@Delyan我認爲你對你的解決方案過於複雜:看到我的答案,現在經過一些優化,我的課程只需要99行代碼:) – pskink

1

我能想到的最接近的是Google地圖和它們讓用戶通過地圖導航(滾動,拖動和擦除)的方式。

當你在緩慢的網絡中滾動瀏覽時,你會發現它們看起來可以與4x5網格一起工作。因此,放置在網格上的20個單個圖像。並且可能在屏幕外的每個方向上還有一個。

現在,你需要做兩件事情:

  • 獲取觸摸事件檢測,用戶希望看到在哪個位置是什麼。

  • 將您的內容放置在網格上。您可以將網格作爲ImageView在FrameLayout上構建,也可以作爲SurfaceView上的位圖構建。使用後者,您可以更好地控制繪圖和放置。第一個放置文本,按鈕等更容易。根據你想要展示的內容,你可以使用這些方法。