将拖动项目实现到屏幕边缘功能

时间:2015-12-18 14:31:51

标签: android android-layout drag-and-drop android-viewpager

当项目在屏幕边缘(左侧或右侧)附近拖动时,我需要实现当前标签更改。

拖拽N下降功能和当前选项卡切换没有问题。我只是无法正确处理此事件 - 当拖动项目靠近屏幕边缘时。

你会怎么做?

我尝试了什么:

 public class UserService {    
    @CacheResult
    @HystrixCommand
    public User getUserById(@CacheKey String id) { // GET
        return storage.get(id);
    }

    @CacheRemove(commandKey = "getUserById")
    @HystrixCommand
    public void update(@CacheKey("id") User user) { // SET
        storage.put(user.getId(), user);
    }
}    

我们的想法是在切换区域拖动项目时以编程方式更改当前选项卡。

但该区域的事件<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

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

2 个答案:

答案 0 :(得分:3)

我认为三个视图的父级(切换区域和GridView)是RelativeLayout。首先,将GridView替换为其父级的第一个子级。完全不考虑布局的其余部分。

其次,为了使用View.OnDragListener接口捕获drop事件,您需要在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);

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

答案 1 :(得分:3)

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

enter image description here

我相信这个解决方案对于oldschool选项卡会很好。因此这里是代码。可能对某人有用。

1)。从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个需要拖放导航的TextView。

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