android - 如何在现有视图上使用拖放功能?
问题描述
我正在尝试在我的 Android 应用程序中为用户创建拖放任务,我希望在用户能够完成任务时更改活动。我用ChoiceTouchListener
来检测用户的拖放。它应该使用户能够将纯白色按钮拖到虚线圆圈中。但发生的事情是,因为我将一些align_Parent
参数设置为 true,它并没有离开屏幕的边界。因此Layout Parameters
,一旦用户触摸屏幕,我就使用并将这些值设为 false。但发生的事情是我无法拖动它:
这是屏幕在触摸之前的样子。触摸按钮后,它会根据align_Parent
参数被约束到一个角落。
布局代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#03B0F5"
android:id="@+id/bottom_right_layout">
<TextView
android:id="@+id/drag_drop_bottomRight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#FFFFFF"
android:text="@string/drag_and_drop"
android:textSize="50sp"
android:textColor="#03B0F5"
tools:ignore="MissingConstraints" />
<ImageView
android:id="@+id/circle_bottomRight"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
app:srcCompat="@drawable/circle"
tools:ignore="MissingConstraints,VectorDrawableCompat" />
<ImageView
android:id="@+id/circle_outline_bottomRight"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerInParent="true"
app:srcCompat="@drawable/circle_outline"
tools:ignore="MissingConstraints,VectorDrawableCompat"
/>
</RelativeLayout>
活动代码:
public class DragAndDrop extends AppCompatActivity {
private ImageView img;
private ImageView img_outline;
private ViewGroup rootLayout;
private int _xDelta;
private int _yDelta;
private RelativeLayout.LayoutParams params = null ;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
List<Integer> givenList = Arrays.asList(0, 1, 2, 3);
Random rand = new Random();
int randomElement = givenList.get(rand.nextInt(givenList.size()));
switch (randomElement){
case 0:
setContentView(R.layout.bottom_left);
rootLayout = (ViewGroup) findViewById(R.id.bottom_left_layout);
img = (ImageView) rootLayout.findViewById(R.id.circle_bottomLeft);
img_outline = findViewById(R.id.circle_outline_bottomLeft);
break;
case 1:
setContentView(R.layout.bottom_right);
rootLayout = (ViewGroup) findViewById(R.id.bottom_right_layout);
img = (ImageView) rootLayout.findViewById(R.id.circle_bottomRight);
img_outline = findViewById(R.id.circle_outline_bottomRight);
break;
case 2:
setContentView(R.layout.top_left);
rootLayout = (ViewGroup) findViewById(R.id.top_left_layout);
img = (ImageView) rootLayout.findViewById(R.id.circle_topleft);
img_outline = findViewById(R.id.circle_outline_topleft);
break;
case 3:
setContentView(R.layout.top_right);
rootLayout = (ViewGroup) findViewById(R.id.top_right_layout);
img = (ImageView) rootLayout.findViewById(R.id.circle_topRight);
img_outline = findViewById(R.id.circle_outline_topRight);
break;
}
img.setOnTouchListener(new ChoiceTouchListener());
}
public void check_success(){
int[] location_circle = new int[2];
int[] location_outline = new int[2];
img.getLocationOnScreen(location_circle);
img_outline.getLocationOnScreen(location_outline);
if(((location_circle[0] >= location_outline[0]-75) &&(location_circle[0] <= location_outline[0]+75))
&& ((location_circle[1] >= location_outline[1]-75) &&(location_circle[1] <= location_outline[1]+75)) ){
Intent i = new Intent(DragAndDrop.this, IntermediateActivity.class);
startActivity(i);
}
}
private final class ChoiceTouchListener implements View.OnTouchListener {
public boolean onTouch(View view, MotionEvent event) {
params = new RelativeLayout.LayoutParams(200, 200);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
params.addRule(RelativeLayout.ALIGN_PARENT_START, 0);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
img.setLayoutParams(params);
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
check_success();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.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:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
view.setLayoutParams(layoutParams);
check_success();
break;
}
rootLayout.invalidate();
return true;
}
}
}
我如何确保实心圆从角落位置开始并且用户可以拖动它?
解决方案
推荐阅读
- r - 在ggplot中为线条的一部分使用不同的颜色
- pyspark - 使用 pyspark 模块中的函数时峰度是否过高?
- php - Woocommerce 新订单然后保存
- c# - 从 Dotfuscator 迁移到 .NET Reactor - 支持哪些混淆属性?
- json - 无法为 Cloudformation 的 Elasticsearch 服务添加细粒度访问
- ruby-on-rails - 如何确保 ActiveStorage URL 实际过期?
- r - RasterStack 数学和条件语句的限制
- queue - 如何在 AnyLogic 中从模拟页面设置排队模式
- javascript - Javascript Unexpected token { 在 JSON 中,带有 Twig 变量
- python - 如何使用 Numpy 将多维数组附加到新维度?