我想做一个简单的控件:一个里面有视图的容器。如果我触摸容器并移动手指,我想让视图跟着我的手指移动。
我应该使用什么样的容器(布局)?如何做到这一点?
我不需要使用一个表面,但一个简单的布局。
我想做一个简单的控件:一个里面有视图的容器。如果我触摸容器并移动手指,我想让视图跟着我的手指移动。
我应该使用什么样的容器(布局)?如何做到这一点?
我不需要使用一个表面,但一个简单的布局。
当前回答
触摸容器,视图将跟随您的手指。
xml代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/floating_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/btn_chat"
android:layout_width="42dp"
android:layout_height="42dp"
/>
<LinearLayout>
Java代码
public class DashBoardActivity extends Activity implements View.OnClickListener, View.OnTouchListener {
float dX;
float dY;
int lastAction;
LinearLayout floatingLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
floatingLayout = findViewById(R.id.floating_layout);
floatingLayout.setOnTouchListener(this);
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
lastAction = MotionEvent.ACTION_DOWN;
break;
case MotionEvent.ACTION_MOVE:
view.setY(event.getRawY() + dY);
view.setX(event.getRawX() + dX);
lastAction = MotionEvent.ACTION_MOVE;
break;
case MotionEvent.ACTION_UP:
if (lastAction == MotionEvent.ACTION_DOWN)
Toast.makeText(DashBoardActivity.this, "Clicked!", Toast.LENGTH_SHORT).show();
break;
default:
return false;
}
return true;
}
}
其他回答
创建一个自定义的触摸监听器类(在Kotlin中):
(这段代码限制了视图从父视图中拖出)
class CustomTouchListener(
val screenWidth: Int,
val screenHeight: Int
) : View.OnTouchListener {
private var dX: Float = 0f
private var dY: Float = 0f
override fun onTouch(view: View, event: MotionEvent): Boolean {
val newX: Float
val newY: Float
when (event.action) {
MotionEvent.ACTION_DOWN -> {
dX = view.x - event.rawX
dY = view.y - event.rawY
}
MotionEvent.ACTION_MOVE -> {
newX = event.rawX + dX
newY = event.rawY + dY
if ((newX <= 0 || newX >= screenWidth - view.width) || (newY <= 0 || newY >= screenHeight - view.height)) {
return true
}
view.animate()
.x(newX)
.y(newY)
.setDuration(0)
.start()
}
}
return true
}
}
如何使用它?
parentView.viewTreeObserver.addOnGlobalLayoutListener { view.setOnTouchListener(CustomTouchListener(parentView.width, parentView.height)) }
parentView是视图的父视图。
我发现了一个简单的方法来做到这一点与ViewPropertyAnimator:
float dX, dY;
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
view.animate()
.x(event.getRawX() + dX)
.y(event.getRawY() + dY)
.setDuration(0)
.start();
break;
default:
return false;
}
return true;
}
//如果你想移动你的相机或任何东西,然后按照下面的方法来做 //我在相机上实现的情况下,你可以应用它在任何你想要的
public class VideoCallActivity extends AppCompatActivity implements
View.OnTouchListener {
FrameLayout myLayout1;
@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//in the frame layout I am setting my camera
myLayout1.setOnTouchListener(this);
}
float dX, dY;
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
//this is your code
case MotionEvent.ACTION_DOWN:
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
view.animate()
.x(event.getRawX() + dX)
.y(event.getRawY() + dY)
.setDuration(0)
.start();
break;
default:
return false;
}
return true;
}
在Kotlin中实现相同
rightPanel.setOnTouchListener(View.OnTouchListener { view, event ->
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
rightDX = view!!.x - event.rawX
// rightDY = view!!.getY() - event.rawY;
}
MotionEvent.ACTION_MOVE -> {
var displacement = event.rawX + rightDX
view!!.animate()
.x(displacement)
// .y(event.getRawY() + rightDY)
.setDuration(0)
.start()
}
else -> { // Note the block
return@OnTouchListener false
}
}
true
})
触摸容器,视图将跟随您的手指。
xml代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/floating_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/btn_chat"
android:layout_width="42dp"
android:layout_height="42dp"
/>
<LinearLayout>
Java代码
public class DashBoardActivity extends Activity implements View.OnClickListener, View.OnTouchListener {
float dX;
float dY;
int lastAction;
LinearLayout floatingLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
floatingLayout = findViewById(R.id.floating_layout);
floatingLayout.setOnTouchListener(this);
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
lastAction = MotionEvent.ACTION_DOWN;
break;
case MotionEvent.ACTION_MOVE:
view.setY(event.getRawY() + dY);
view.setX(event.getRawX() + dX);
lastAction = MotionEvent.ACTION_MOVE;
break;
case MotionEvent.ACTION_UP:
if (lastAction == MotionEvent.ACTION_DOWN)
Toast.makeText(DashBoardActivity.this, "Clicked!", Toast.LENGTH_SHORT).show();
break;
default:
return false;
}
return true;
}
}