Внедрение объекта перетаскивания в функцию края экрана

Мне нужно выполнить текущее изменение вкладок, когда элемент перетаскивается около края экрана (влево или вправо).

Нет проблем с функцией drag N drop и текущими переключателями. Я просто не могу правильно обработать это событие – когда перетаскиваемый элемент находится рядом с краем экрана.

Как бы Вы это сделали?

То, что я пробовал:

<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(); 

Если кто-либо сталкивался с такой проблемой, поделитесь своим опытом. Или, может быть, есть еще одно лучшее решение для этого. Пожалуйста, дайте мне подсказку.

Solutions Collecting From Web of "Внедрение объекта перетаскивания в функцию края экрана"

Текущее решение, к которому я пришел, работает (более или менее), чтобы использовать TextView вложенный в PagerTabStrip как область перетаскивания. Самая большая проблема в этом подходе заключается в том, что эти области переключения слишком малы по какой-то причине. Триггеры события ENTER только в этих областях.

Введите описание изображения здесь

Я верю, что это решение было бы хорошо с вкладками oldschool. Поэтому вот код. Может быть полезно для кого-то.

1). Parse TextViews из 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; } 

После этой операции у меня есть 3 TextViews, для которых требуется перетащить drag'n'drop.

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; } }; 

Я беру его в качестве родителя трех видов (области переключения и GridView ) – RelativeLayout . Прежде всего, замените GridView , чтобы быть первым ребенком его родителя. Оставь остальную часть макета точно так, как она есть.

Во-вторых, чтобы поймать событие drop с интерфейсом View.OnDragListener , вам нужно установить минимальную версию SDK на 11 в AndroidManifest.xml . После этого вы можете передать слушателя в области переключения:

 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); 

Если у вас все еще есть проблемы, отправьте больше своего кода.