如何为可移动的浮动按钮设置 onTouch 和 onClick 功能

Posted

技术标签:

【中文标题】如何为可移动的浮动按钮设置 onTouch 和 onClick 功能【英文标题】:How to set onTouch and onClick functions for a movable floating button 【发布时间】:2019-08-29 16:32:32 【问题描述】:

我在此处制作了一个可移动的浮动按钮,用于引用某个文档,现在它可以在屏幕上的任何位置触摸、拖放。但是我在点击那个可移动的浮动按钮时刷新了一个片段。我可以触摸但我无法点击它。

public class MainScreen extends Fragment implements View.OnTouchListener 

    FloatingActionButton fab;

    FrameLayout rootlayout;
    int x_Delta;
    int y_delta;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) 

        View rootView = inflater.inflate(R.layout.activity_main_screen, container, false);

        fab = (FloatingActionButton)rootView.findViewById(R.id.fab);
        rootlayout = (FrameLayout) rootView.findViewById(R.id.rootlayout);


        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(150, 150);
        fab.setLayoutParams(layoutParams);
        fab.setOnTouchListener(MainScreen.this);


        fab.setOnClickListener(new View.OnClickListener() 
           @Override
            public void onClick(View v) 
               getFragmentManager().beginTransaction().detach(MainScreen.this).attach(MainScreen.this).commit();

            
        );


        return rootView;
    

    public boolean onTouch(View view, MotionEvent event) 
        final int X = (int) event.getRawX();
        final int Y = (int) event.getRawY();
        switch (event.getAction() & MotionEvent.ACTION_MASK) 
            case MotionEvent.ACTION_DOWN:
                FrameLayout.LayoutParams lParams = (FrameLayout.LayoutParams) view.getLayoutParams();
                x_Delta = X - lParams.leftMargin;
                y_delta = Y - lParams.topMargin;
                break;
            case MotionEvent.ACTION_UP:
                if(Math.abs(event.getRawX()- X )<=2)
                    getFragmentManager().beginTransaction().detach(MainScreen.this).attach(MainScreen.this).commit();
                    return true;
                
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                break;
            case MotionEvent.ACTION_POINTER_UP:

                break;
            case MotionEvent.ACTION_MOVE:
                FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view
                        .getLayoutParams();
                layoutParams.leftMargin = X - x_Delta;
                layoutParams.topMargin = Y - y_delta;
                layoutParams.rightMargin = -250;
                layoutParams.bottomMargin = -250;
                view.setLayoutParams(layoutParams);
                break;
        
        rootlayout.invalidate();
        return true;
    

【问题讨论】:

【参考方案1】:

添加一个新的boolean 变量。

FrameLayout rootlayout;
int x_Delta;
int y_delta;
boolean moveStarted;

然后在onTouch事件中

switch (event.getAction() & MotionEvent.ACTION_MASK) 
    case MotionEvent.ACTION_DOWN:
        FrameLayout.LayoutParams lParams = (FrameLayout.LayoutParams) view.getLayoutParams();
        x_Delta = X - lParams.leftMargin;
        y_delta = Y - lParams.topMargin;
        break;
    case MotionEvent.ACTION_UP:
        if (!moveStarted) 
            // do here your click event
         else 
            if(Math.abs(event.getRawX()- X )<=2) 
                getFragmentManager().beginTransaction().detach(MainScreen.this).attach(MainScreen.this).commit();
            
            return true;
        
        moveStarted = false;
        break;
    case MotionEvent.ACTION_POINTER_DOWN:
        break;
    case MotionEvent.ACTION_POINTER_UP:
        break;
    case MotionEvent.ACTION_MOVE:
        moveStarted = true;
        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view
                .getLayoutParams();
        layoutParams.leftMargin = X - x_Delta;
        layoutParams.topMargin = Y - y_delta;
        layoutParams.rightMargin = -250;
        layoutParams.bottomMargin = -250;
        view.setLayoutParams(layoutParams);
        break;

【讨论】:

【参考方案2】:

android 中,触摸侦听器将在单击侦听器之前执行,并且由于您返回 true,因此触摸侦听器会告诉系统中断任何其他侦听器。

所以要解决这个问题你需要在ACTION_UP下添加view.performClick();

【讨论】:

以上是关于如何为可移动的浮动按钮设置 onTouch 和 onClick 功能的主要内容,如果未能解决你的问题,请参考以下文章

如何为可扩展的 Flutter 小部件设置动画以将其滑出屏幕

如何为移动屏幕的导航栏项目添加切换按钮,并使用 HTML、CSS 和 Bootstrap v4 将它们切换为下拉菜单

如何为以下两个按钮添加约束

QWidget上浮动的按钮?

如何为单选按钮和复选框设置禁用/只读功能

android如何为片段按钮设置OnClickListener