我正在使用参考 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;
}
});
}
}