在具有流布局的多个动态按钮上设置 ontouchlistener



我正在使用参考 https://github.com/ApmeM/android-flowlayout 的流布局。现在,我正在此布局上创建多个动态按钮,并在它们上设置ontouchlistener。问题是,当我通过触摸改变一个按钮的位置时,其他按钮也在改变那里的位置。我想更改我正在触摸的唯一按钮的位置。有没有办法做到这一点或其他解决方案。

public class MainActivity extends AppCompatActivity implements    View.OnTouchListener {
          Button floatButton;
        Button _view;
        private int _xDelta;
        private int _yDelta;
        ViewGroup layout;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
            Toolbar toolbar = (Toolbar) this.findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
            layout = (ViewGroup) findViewById(R.id.flowLayout);
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT
                    , ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams.leftMargin = 50;
            layoutParams.topMargin = 50;
            layoutParams.bottomMargin = 0;
            layoutParams.rightMargin = 0;
            for (int i = 0; i < 10; i++) {
                _view = new Button(this);
                _view.setText("Button"+(i+1));
                _view.setLayoutParams(layoutParams);
               _view.setOnTouchListener(this);
                layout.addView(_view);
            }
        }
        public boolean onTouch(View view, MotionEvent event) {
            final int X = (int) event.getRawX();
            final int Y = (int) event.getRawY();
            try {
                switch (event.getAction() & MotionEvent.ACTION_MASK) {
                    case MotionEvent.ACTION_DOWN:
                        FlowLayout.LayoutParams lParams = (FlowLayout.LayoutParams) view.getLayoutParams();
                        _xDelta = X - lParams.leftMargin;
                        _yDelta = Y - lParams.topMargin;
                        break;
                    case MotionEvent.ACTION_UP:
                        break;
                    case MotionEvent.ACTION_POINTER_DOWN:
                        break;
                    case MotionEvent.ACTION_POINTER_UP:
                        break;
                    case MotionEvent.ACTION_MOVE:
                        FlowLayout.LayoutParams layoutParams = (FlowLayout.LayoutParams) view.getLayoutParams();
                        layoutParams.leftMargin = X - _xDelta;
                        layoutParams.topMargin = Y - _yDelta;
                        layoutParams.rightMargin = 0;
                        layoutParams.bottomMargin = 0;
                        view.setLayoutParams(layoutParams);
                        break;
                }
            }catch (Exception ex){
                Log.d("ON Touch ", ex.toString());
            }
            layout.invalidate();
            return true;
        }
    }

发生这种情况很可能是因为您使用的是 RelativeLayout,并且其他对象位置是相对于您正在移动的按钮以某种方式定义的。如果是这种情况,那么您描述的行为是预期的。但是我们需要查看 XML 文件才能确切地知道发生了什么。

您可以使用

2 个布局,并在一个活动中为每个布局应用 OnTouchListener。这是我的例子:-floating_View.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:id="@+id/thisIsAnID"
        android:layout_width="44dp"
        android:layout_height="124dp"
        android:background="#BB000000"
        android:orientation="vertical">
        <ToggleButton
            android:id="@+id/toggl"
            android:layout_width="44dp"
            android:layout_height="40dp"
            android:scaleX="1.4"
            android:scaleY="1.2"
            android:background="@drawable/toggle_selector"
            android:textOff=""
            android:textOn="" />
        <Button
            android:id="@+id/stop"
            android:layout_width="44dp"
            android:layout_height="40dp"
            android:text=""
            android:background="@drawable/ic_baseline_close_24"/>
        <View
            android:id="@+id/view1"
            android:layout_width="44dp"
            android:layout_height="40dp"
            android:text=""
            android:scaleX="0.9"
            android:scaleY="0.9"
            android:background="@drawable/ic_baseline_open_with_24"/>
    </LinearLayout>
</FrameLayout>

pointer_view.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <View
        android:layout_width="45dp"
        android:layout_height="45dp"
        android:background="@drawable/ic_outline_adjust_24"
        android:id="@+id/pointerr"
        android:scaleX="1.1"
        android:scaleY="1.1"
        android:layout_gravity="center_horizontal"/>
</FrameLayout>

和主文件浮动视图.java它使用上述两种布局

public class FloatingView extends Service {
    private WindowManager mWindowManager;
    private WindowManager mWindowManager2;
    private View myFloatingView;
    private View myFloatingView2;
    @Override
    public void onCreate() {
        super.onCreate();
        ////getting the widget layout from xml using layout inflater ...dynamic layout use inflater
        myFloatingView= LayoutInflater.from(this).inflate(R.layout.floating_view,null);
        myFloatingView2=LayoutInflater.from(this).inflate(R.layout.pointer_view,null);
        
        final WindowManager.LayoutParams parmss=  new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,//width
                WindowManager.LayoutParams.WRAP_CONTENT,//height
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,//type
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,//flags
                PixelFormat.TRANSLUCENT//format
        );
        final WindowManager.LayoutParams parmss2= new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                PixelFormat.TRANSLUCENT
        );
        //specify the view position
        parmss.gravity= Gravity.CENTER | Gravity.LEFT;
        parmss.x=5;
        parmss.y=50;
        parmss2.gravity=Gravity.CENTER | Gravity.CENTER;
        //getting windows services and adding the floating view to it
        mWindowManager=(WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager2=(WindowManager)getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(myFloatingView,parmss);
        mWindowManager2.addView(myFloatingView2,parmss2);
        myFloatingView.findViewById(R.id.thisIsAnID).setOnTouchListener(new View.OnTouchListener() {
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        //remember the initial position.
                        initialX=parmss.x;
                        initialY= parmss.y;
                        //get the touch location
                        initialTouchX=event.getRawX();
                        initialTouchY=event.getRawY();
                        return true;
                    case MotionEvent.ACTION_UP:
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        float Xdiff= Math.round(event.getRawX()-initialTouchX);
                        float Ydiff= Math.round(event.getRawY()-initialTouchY);
                        //Calculate the X and Y coordinates of the view.
                        parmss.x=initialX+(int)Xdiff;
                        parmss.y=initialY+(int)Ydiff;
                        //Update the layout with new X & Y coordinates
                        mWindowManager.updateViewLayout(myFloatingView,parmss);
                        return true;
                }
                return false;
            }
        });
        myFloatingView2.findViewById(R.id.pointerr).setOnTouchListener(new View.OnTouchListener() {
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        //remember the initial position.
                        initialX=parmss2.x;
                        initialY= parmss2.y;
                        //get the touch location
                        initialTouchX=event.getRawX();
                        initialTouchY=event.getRawY();
                        return true;
                    case MotionEvent.ACTION_UP:
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        float Xdiff= Math.round(event.getRawX()-initialTouchX);
                        float Ydiff= Math.round(event.getRawY()-initialTouchY);
                        //Calculate the X and Y coordinates of the view.
                        parmss2.x=initialX+(int)Xdiff;
                        parmss2.y=initialY+(int)Ydiff;
                        //Update the layout with new X & Y coordinates
                        mWindowManager2.updateViewLayout(myFloatingView2,parmss2);
                        return true;
                }
                return false;
            }
        });
    }
}

相关内容

  • 没有找到相关文章

最新更新