安卓基础(拖拽)
当用户长按或拖拽某个视图(如按钮、图片)时,需要提供视觉反馈(即阴影)。这行代码通常在拖拽事件的处理逻辑中,例如:
view.setOnLongClickListener(v -> {// 创建拖拽阴影DragShadowBuilder shadowBuilder = new DragShadowBuilder(v);// 启动拖拽操作v.startDragAndDrop(null, shadowBuilder, null, 0);return true;
});
设置长按监听器(触发拖拽)
View.OnLongClickListener longClickListener = new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {// 创建拖拽阴影(使用被长按的视图自身作为阴影)DragShadowBuilder shadowBuilder = new DragShadowBuilder(v);// 启动拖拽操作,将视图自身作为本地数据传递(第三个参数)v.startDragAndDrop(null, shadowBuilder, v, 0);return true; // 表示已处理长按事件}
};
// 为三个可拖拽的TextView设置相同的长按监听器
draggable1.setOnLongClickListener(longClickListener);
draggable2.setOnLongClickListener(longClickListener);
draggable3.setOnLongClickListener(longClickListener);
完整代码
主活动代码 MainActivity.java
package com.example.draganddropdemo;import android.os.Bundle;
import android.view.DragEvent;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView draggable1 = findViewById(R.id.draggable1);TextView draggable2 = findViewById(R.id.draggable2);TextView draggable3 = findViewById(R.id.draggable3);FrameLayout targetContainer = findViewById(R.id.target_container);// 为可拖拽组件设置长按监听View.OnLongClickListener longClickListener = new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {DragShadowBuilder shadowBuilder = new DragShadowBuilder(v);v.startDragAndDrop(null, shadowBuilder, v, 0);return true;}};draggable1.setOnLongClickListener(longClickListener);draggable2.setOnLongClickListener(longClickListener);draggable3.setOnLongClickListener(longClickListener);// 为目标容器设置拖拽监听targetContainer.setOnDragListener(new View.OnDragListener() {@Overridepublic boolean onDrag(View v, DragEvent event) {switch (event.getAction()) {case DragEvent.ACTION_DRAG_STARTED:return true;case DragEvent.ACTION_DRAG_ENTERED:v.setBackgroundColor(getResources().getColor(android.R.color.holo_green_light));return true;case DragEvent.ACTION_DRAG_LOCATION:return true;case DragEvent.ACTION_DRAG_EXITED:v.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));return true;case DragEvent.ACTION_DROP:View draggedView = (View) event.getLocalState();// 从原父容器移除if (draggedView.getParent() instanceof FrameLayout) {((FrameLayout) draggedView.getParent()).removeView(draggedView);}// 添加到目标容器targetContainer.addView(draggedView);draggedView.setVisibility(View.VISIBLE);v.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));// 为容器内组件设置可拖拽draggedView.setOnLongClickListener(longClickListener);return true;case DragEvent.ACTION_DRAG_ENDED:v.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));return true;default:return false;}}});}
}
布局文件 activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><!-- 可拖拽组件 --><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center"><TextViewandroid:id="@+id/draggable1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Component 1"android:padding="16dp"android:background="@android:color/holo_blue_light"android:layout_margin="8dp" /><TextViewandroid:id="@+id/draggable2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Component 2"android:padding="16dp"android:background="@android:color/holo_blue_light"android:layout_margin="8dp" /><TextViewandroid:id="@+id/draggable3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Component 3"android:padding="16dp"android:background="@android:color/holo_blue_light"android:layout_margin="8dp" /></LinearLayout><!-- 目标容器 --><FrameLayoutandroid:id="@+id/target_container"android:layout_width="match_parent"android:layout_height="300dp"android:background="@android:color/darker_gray"android:layout_marginTop="16dp" />
</LinearLayout>
把自定义的xml组件放入父布局的容器里面
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获取 LayoutInflater 实例LayoutInflater inflater = LayoutInflater.from(this);// 用 inflater 把 XML 布局文件转换成 View 对象View view = inflater.inflate(R.layout.some_layout, null);// 找到一个父布局LinearLayout parentLayout = findViewById(R.id.parent_layout);// 把转换后的 View 对象添加到父布局中parentLayout.addView(view);}
}