2015-12-18 38 views
7

当项目在屏幕边缘附近(左侧或右侧)拖动时,我需要实现当前的选项卡更改。实现拖动项目到屏幕边缘特征

拖放拖放功能和当前选项卡开关没有问题。我无法正确处理这个事件 - 当拖动的项目靠近屏幕的边缘时。

你会怎么做?

我的尝试:

<FrameLayout 
    android:id="@+id/left_toggle_area" 
    android:layout_width="30dp" 
    android:layout_height="fill_parent" 
    android:layout_alignParentStart="true" 
    android:layout_alignParentLeft="true"> 
</FrameLayout> 

<FrameLayout 
    android:id="@+id/right_toggle_area" 
    android:layout_width="30dp" 
    android:layout_height="fill_parent" 
    android:layout_alignParentEnd="true" 
    android:layout_alignParentRight="true"> 
</FrameLayout> 

<GridView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    ... /> 

的想法是改变目前的标签编程时,在肘节区域拖曳的项目。

但该事件DragEvent.ACTION_DRAG_ENTERED从来没有发生,因为(我相信)GridView采取整个屏幕,只是与切换区域重叠。

我试过了,当拖动开始事件被触发时,已经将这些区域放在前面。但由于某种原因,这并不起作用。

FrameLayout toggleView = (FrameLayout) v; 
     toggleView.bringToFront(); 
     toggleView.requestLayout(); 
     toggleView.invalidate(); 

如果有人遇到此类问题,请分享您的经验。或者也许还有另一个更好的解决方案。请给我一个提示。

+0

我发布了我目前的解决方案。但仍倾向于使用提到的拖拽区域。所以,如果有人有想法,欢迎欢迎。 – AnZ

+0

所以你不想丢弃,仍然改变标签? –

+0

是的,我想用'DragEvent.ACTION_DRAG_ENTERED'事件更改当前选项卡 – AnZ

回答

3

我把它作为三个视图(切换区域和GridView)的父级是RelativeLayout。首先,替换GridView,成为其父母的第一个孩子。完全按原样保留布局的其余部分。

其次,为了使用View.OnDragListener接口捕获丢弃事件,您需要在AndroidManifest.xml中将最小SDK版本设置为11。之后,您可以将听众传递到切换区域:

View.OnDragListener dragListener = new View.OnDragListener() { 
    @Override 
    public boolean onDrag(View v, DragEvent event) { 
    // you can check for event.ACTION_DRAG_ENTERED here 
    return true; 
    } 
}; 
FrameLayout leftToggleArea = (FrameLayout) findViewById(R.id.left_toggle_area); 
leftToggleArea.setOnDragListener(dragListener); 

如果仍有问题,请发布更多代码。

+0

拖曳侦听器的设置没有问题。我完全是你在这里写的。问题是event.ACTION_DRAG_ENTERED从不会在切换区域发生。 – AnZ

3

我当前使用的解决方案(或多或少)是使用嵌套在PagerTabStrip标题中的TextView作为拖动区域。这种方法最大的缺点是由于某些原因,这些切换区域太小。 ENTER事件仅在这些区域触发。

enter image description here

我相信这个解决方案将有利于与老校友标签。因此,这里的代码。可能对某人有用。

1)。从PagerTabStrip

private ArrayList <TextView> titles; 

... 

public void setPager(PagerTabStrip mPagerTabStrip) { 
    for (int i = 0; i < mPagerTabStrip.getChildCount(); ++i) { 
     View nextChild = mPagerTabStrip.getChildAt(i); 
     if (nextChild instanceof TextView) { 
      TextView textViewToConvert = (TextView) nextChild; 

      if (textViewToConvert.getText().toString().contains(TabsFragment.TAG_MONITOR)){ // I take only few tabs 
       if (!titles.contains(textViewToConvert)) { 
        titles.add(textViewToConvert); 
       } 
      } 
     } 
    } 

} 

public ArrayList<TextView> getTitles() { 
    return titles; 
} 

解析TextViews此操作后,我有3个TextViews需要拖放导航。 2)。通过您的TextViews列表类,你实现DragListeners

public void setUpDragNDropTabMoves(ArrayList<TextView> views) { 
    if (views != null) { 
     for (TextView tv : views){ 
      tv.setOnDragListener(TabToggleDragListener); 
     } 
    } 
} 

3)。而聆听者本身

View.OnDragListener TabToggleDragListener = new View.OnDragListener() { 
    @Override 
    public boolean onDrag(View v, DragEvent event) { 
     TextView toggleView = (TextView) v; 
     String title = toggleView.getText().toString(); 

     switch (event.getAction()) { 
      case DragEvent.ACTION_DROP: 
       ... 
       break; 

      case DragEvent.ACTION_DRAG_ENTERED: 
       int tabId = -1; 
       //define which tab is destination 
       if (title.contains(TabsFragment.TAG_MONITOR1)){ 
        tabId = 1; 
       } else if (title.contains(TabsFragment.TAG_MONITOR2)){ 
        tabId = 2; 
       } else if (title.contains(TabsFragment.TAG_MONITOR3)){ 
        tabId = 3; 
       } 

       //send event to tab host fragment/activity and perform tab change to passed index 
       //you may use EventBus or Otto for this. I used Local Broadcast 
       BroadcastSender.sendMessageToUI(getContext(), 
         BroadcastSender.TABS_FRAGMENT, 
         BroadcastActions.TF_TOGGLE_TAB, 
         tabId 
       ); 
       break; 
      case DragEvent.ACTION_DRAG_EXITED: 
       ... 
       break; 

      case DragEvent.ACTION_DRAG_ENDED: 
       ... 
       break; 
     } 
     return true; 
    } 
};