Android拖放startDragAndDrop拖拽Glide加载堆叠圆角图,Kotlin(5)

news2025/3/13 4:59:11

Android拖放startDragAndDrop拖拽Glide加载堆叠圆角图,Kotlin(5)

 

 

import android.content.ClipData
import android.graphics.Canvas
import android.graphics.Point
import android.os.Bundle
import android.util.Log
import android.view.DragEvent
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnDragListener
import android.view.View.OnLongClickListener
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCorners


class MainActivity : AppCompatActivity() {
    companion object {
        const val TAG = "fly"
        const val DEGREE = -10 //图片选择的角度。
        const val RADIUS = 30 //图片的圆角半径。
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val shadowBuilder = createDragShadowBuilder()
        setData(shadowBuilder.getShadowView())

        val triggerView = findViewById<ImageView>(R.id.image)
        triggerView.setOnLongClickListener(object : OnLongClickListener {
            //长按事件触发拖拽.
            override fun onLongClick(v: View?): Boolean {
                val data = ClipData.newPlainText("name", "phil") //测试数据。
                triggerView.startDragAndDrop(
                    data,
                    shadowBuilder,
                    null,
                    0 or View.DRAG_FLAG_GLOBAL or View.DRAG_FLAG_OPAQUE
                )

                return true
            }
        })

        triggerView.setOnDragListener(object : OnDragListener {
            override fun onDrag(v: View?, event: DragEvent?): Boolean {
                when (event?.action) {
                    DragEvent.ACTION_DRAG_STARTED -> {
                        //拖放开始
                        Log.d(TAG, "ACTION_DRAG_STARTED")
                        //updateData(shadowView)
                    }

                    DragEvent.ACTION_DRAG_ENTERED -> {
                        //进入imageView
                        Log.d(TAG, "ACTION_DRAG_ENTERED")
                    }

                    DragEvent.ACTION_DRAG_ENDED -> {
                        //拖放结束
                        Log.d(TAG, "ACTION_DRAG_ENDED")
                    }

                    DragEvent.ACTION_DRAG_EXITED -> {
                        //离开imageView
                        Log.d(TAG, "ACTION_DRAG_EXITED")
                    }
                }

                return true
            }
        })
    }

    private fun createDragShadowBuilder(): MyDragShadowBuilder {
        val shadowView = LayoutInflater.from(this).inflate(R.layout.dnd, null)
        return MyDragShadowBuilder(shadowView)
    }

    private fun setData(viewGroup: View) {
        //从1和4两个数字中随机选一个。
        var cnt = intArrayOf(1, 4).random()
        Log.d(TAG, "cnt=$cnt")

        val group: androidx.constraintlayout.widget.Group = viewGroup.findViewById(R.id.group)
        val number = viewGroup.findViewById<TextView>(R.id.number)
        if (cnt == 1) {
            //只显示一张。
            number.text = "1"
            group.visibility = ViewGroup.INVISIBLE
        } else if (cnt == 4) {
            //显示重叠在一起的4张。
            number.text = "4"
            group.visibility = ViewGroup.VISIBLE

            val imageViews = arrayOf(
                viewGroup.findViewById<ImageView>(R.id.iv1),
                viewGroup.findViewById<ImageView>(R.id.iv2),
                viewGroup.findViewById<ImageView>(R.id.iv3)
            )

            val resIds = arrayOf(
                R.mipmap.pic1,
                R.mipmap.pic2,
                R.mipmap.pic3
            )

            imageViews.forEachIndexed { index, iv ->
                val degree = (imageViews.size - index) * DEGREE
                Log.d(TAG, "index=$index degree=$degree")

                iv.rotation = degree.toFloat()
                GlideApp.with(this)
                    .load(resIds[index])
                    .transform(CenterCrop(), RoundedCorners(RADIUS)) //先中心缩放,再切圆角。
                    .override(
                        resources.getDimensionPixelSize(R.dimen.image_size_w),
                        resources.getDimensionPixelSize(R.dimen.image_size_h)
                    ).placeholder(R.drawable.ic_launcher_foreground)
                    .error(android.R.drawable.stat_notify_error)
                    .into(iv)
            }
        }

        val folder = viewGroup.findViewById<ImageView>(R.id.folder)
        //封面
        GlideApp.with(this)
            .load(R.mipmap.pic4)
            .transform(CenterCrop(), RoundedCorners(RADIUS)) //先中心缩放,再切圆角。
            .override(
                resources.getDimensionPixelSize(R.dimen.image_size_w),
                resources.getDimensionPixelSize(R.dimen.image_size_h)
            ).placeholder(R.drawable.ic_launcher_foreground)
            .error(android.R.drawable.stat_notify_error)
            .into(folder)
    }

    class MyDragShadowBuilder(private var mShadow: View) :
        View.DragShadowBuilder() {

        private val width: Int =
            mShadow.context.resources.getDimensionPixelSize(R.dimen.view_size_w)
        private val height: Int =
            mShadow.context.resources.getDimensionPixelSize(R.dimen.view_size_h)

        fun getShadowView(): View {
            return mShadow
        }

        override fun onProvideShadowMetrics(outShadowSize: Point?, outShadowTouchPoint: Point?) {
            //拖动图像的宽和高
            outShadowSize?.set(width, height)

            //手指在拖动图像的位置 中点
            outShadowTouchPoint?.set(width / 2, height / 2)
        }

        override fun onDrawShadow(canvas: Canvas) {
            mShadow.measure(width, height)
            mShadow.layout(0, 0, width, height)
            mShadow.draw(canvas)

            Log.d(TAG, "onDrawShadow width=$width height=$height")
        }
    }
}

 

 

只有一张图片,只显示封面图:

fc388ed6edac4355962b9ab81cab9004.png

 

 

 

多张图片,显示堆叠的图片,并同时设置封面图: 

aefdc47b6caf4c18b48cb358e7bc7aaa.png

 

 

dnd.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="@dimen/view_size_w"
    android:layout_height="@dimen/view_size_h"
    android:background="@android:color/holo_orange_light">

    <ImageView
        android:id="@+id/iv1"
        android:layout_width="@dimen/image_size_w"
        android:layout_height="@dimen/image_size_h"
        android:layout_margin="@dimen/my_margin"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/iv2"
        android:layout_width="@dimen/image_size_w"
        android:layout_height="@dimen/image_size_h"
        android:layout_margin="@dimen/my_margin"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/iv3"
        android:layout_width="@dimen/image_size_w"
        android:layout_height="@dimen/image_size_h"
        android:layout_margin="@dimen/my_margin"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.Group
        android:id="@+id/group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="visible"
        app:constraint_referenced_ids="iv1,iv2,iv3" />

    <ImageView
        android:id="@+id/folder"
        android:layout_width="@dimen/image_size_w"
        android:layout_height="@dimen/image_size_h"
        android:layout_margin="@dimen/my_margin"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_red_light"
        android:text="--"
        android:textColor="@android:color/white"
        android:textSize="30dp"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

dimens.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="view_size_w">250dp</dimen>
    <dimen name="view_size_h">200dp</dimen>
    <dimen name="image_size_w">150dp</dimen>
    <dimen name="image_size_h">100dp</dimen>
    <dimen name="my_margin">50dp</dimen>
</resources>

 

 

 

Android拖放startDragAndDrop拖拽onDrawShadow静态添加xml布局View,Kotlin(4)-CSDN博客文章浏览阅读74次。Android DynamicGrid:拖曳交换位置Android DynamicGrid是一个第三方开源项目,DynamicGrid在github上的项目主页是:https://github.com/askerov/DynamicGrid它实现在一个网格布局内,拖曳任意子view实现动态的交换位置,这很类似手机的桌面,手机桌面的图标,均可自由拖曳实现摆放位置的交换,如动图所示:_android 拖拽交换位置。Android View拖拽startDragAndDrop,Kotlin-CSDN博客。https://blog.csdn.net/zhangphil/article/details/134017828

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1197567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

macOS Sonoma 14.2beta2(23C5041e)发布(附黑白苹果镜像地址)

系统介绍 黑果魏叔11 月 10 日消息&#xff0c;今日向 Mac 电脑用户推送了 macOS 14.2 开发者预览版 Beta 2 更新&#xff08;内部版本号&#xff1a;23C5041e&#xff09;&#xff0c;本次更新距离上次发布隔了 14 天。 macOS Sonoma 14.2 添加了 Music 收藏夹播放列表&…

python工具HIKVISION视频编码设备接入网关任意文件下载

python工具 构造payload /serverLog/downFile.php?fileName../web/html/serverLog/downFile.php漏洞证明 文笔生疏&#xff0c;措辞浅薄&#xff0c;望各位大佬不吝赐教&#xff0c;万分感谢。 免责声明&#xff1a;由于传播或利用此文所提供的信息、技术或方法而造成的任何…

rasa train nlu详解:1.2-_train_graph()函数

本文使用《使用ResponseSelector实现校园招聘FAQ机器人》中的例子&#xff0c;主要详解介绍_train_graph()函数中变量的具体值。 一.rasa/model_training.py/_train_graph()函数   _train_graph()函数实现&#xff0c;如下所示&#xff1a; def _train_graph(file_importer…

【C语言】【数据结构】【环形链表判断是否带环并返回进环节点】有数学推导加图解

1.判断是否带环&#xff1a; 用快慢指针 slow指针一次走一步&#xff0c;fast指针一次走两步 当两个指针相遇时&#xff0c;链表带环&#xff1b;两个指针不能相遇时&#xff0c;当fast走到倒数第一个节点或为空时&#xff0c;跳出循环返回空指针。 那么slow指针一次走一步&a…

2000-2022年上市公司数字化转型同群效应数据

2000-2022年上市公司数字化转型同群效应数据 1、时间&#xff1a;2000-2022年 2、指标&#xff1a;股票代码、年份、行业代码、行政区划代码、数字化转型程度-A、数字化转型程度-B、同行业同群-数字化转型程度-A_均值、同行业同群-数字化转型程度-A_中位数、同省份同群-数字化…

使用电脑时提示msvcp140.dll丢失的5个解决方法

“计算机中msvcp140.dll丢失的5个解决方法”。在我们日常使用电脑的过程中&#xff0c;有时会遇到一些错误提示&#xff0c;其中之一就是“msvcp140.dll丢失”。那么&#xff0c;什么是msvcp140.dll呢&#xff1f;它的作用是什么&#xff1f;丢失它会对电脑产生什么影响呢&…

【Gradle-12】分析so文件和依赖的关系

1、前言 在包大小的占比中&#xff0c;so文件的占比往往是最高的&#xff0c;动辄几兆的大小多一个都会把包大小的指标打爆。 而在各厂商要求对手机CPU ARM架构进行分包适配的情况下&#xff0c;你更需要知道哪些依赖是没有适配v7a/v8a的&#xff0c;这将影响你的APP在应用市场…

华为dns mapping配置案例

解决内网PC用公网的dns用域名方法访问公司内网的web服务器&#xff1a; 原理是用DNS mapping方式解决 配置过程&#xff1a;域名——出口公网IP地址——公网端口——协议类型 公司内网client用户填公网dns&#xff0c; 公网上的dns上面已注册有公司对外映射的web服务器的公网…

管理能力测评,如何提升管理能力?

管理能力是综合能力的体现&#xff0c;通常也解读为组织管理能力&#xff0c;如果要再细分的话&#xff0c;可能还包括有沟通能力&#xff0c;协调能力&#xff0c;组织能力&#xff0c;执行力和专业能力等等。不过没有办法说的太细节&#xff0c;因为每个部分铺开了都是一个独…

AI 绘画 | Stable Diffusion 进阶 Embeddings(词嵌入)、LoRa(低秩适应模型)、Hypernetwork(超网络)

前言 Stable Diffusion web ui&#xff0c;除了依靠文生图&#xff08;即靠提示词生成图片&#xff09;&#xff0c;图生图&#xff08;即靠图片提示词生成图片&#xff09;外&#xff0c;这两种方式还不能满足我们所有的绘图需求&#xff0c;于是就有了 Embeddings&#xff0…

Echarts柱状体实现滚动条动态滚动

当我们柱状图中X轴数据太多的时候&#xff0c;会自动把柱形的宽度挤的很细&#xff0c;带来的交互非常不好&#xff0c;因此就有一个属性来解决&#xff1a;dataZoom 我这里只是实现了一个简易的版本&#xff0c;横向滚动。 dataZoom: {show: true, // 为true 滚动条出现realti…

自主开发刷题应用网站H5源码(无需后端无需数据库)

该应用使用JSON作为题库的存储方式&#xff0c;层次清晰、结构简单易懂。 配套的word模板和模板到JSON转换工具可供使用&#xff0c;方便将题库从word格式转换为JSON格式。 四种刷题模式包括顺序刷题、乱序刷题、错题模式和背题模式&#xff0c;可以根据自己的需求选择适合的模…

Activiti6工作流引擎:Form表单

表单约等于流程变量。StartEvent 有一个Form属性&#xff0c;用于关联流程中涉及到的业务数据。 一&#xff1a;内置表单 每个节点都可以有不同的表单属性。 1.1 获取开始节点对应的表单 Autowired private FormService formService;Test void delopyProcess() {ProcessEngi…

stm32超声波测距不准的解决方法(STM32 delay_us()产生1us)

首先要说明一下原理&#xff1a;使用stm32无法准确产生1us的时间&#xff0c;但是超声波测距一定要依赖时间&#xff0c;时间不准&#xff0c;距离一定不准&#xff0c;这是要肯定的&#xff0c;但是在不准确的情况下&#xff0c;要测量一个比较准确的时间&#xff0c;那么只能…

RK3568平台 查看内存的基本命令

一.free命令 free命令显示系统使用和空闲的内存情况&#xff0c;包括物理内存、交互区内存(swap)和内核缓冲区内存。共享内存将被忽略。 Mem 行(第二行)是内存的使用情况。 Swap 行(第三行)是交换空间的使用情况。 total 列显示系统总的可用物理内存和交换空间大小。 used 列显…

学习c#的第四天

目录 C# 变量 C# 中的变量定义与初始化 接受来自用户的值 C# 中的 Lvalues 和 Rvalues 不同类型变量进行运算 静态变量 局部变量 C# 常量 整数常量 浮点常量 字符常量 字符串常量 定义常量 扩展知识 Convert.ToDouble 与 Double.Parse 的区别 静态常量和动态常…

SpringBoot_01

Spring https://spring.io/ SpringBoot可以帮助我们非常快速的构建应用程序、简化开发、提高效率。 SpringBootWeb入门 需求&#xff1a;使用SpringBoot开发一个web应用&#xff0c;浏览器发起请求/hello后&#xff0c;给浏览器返回字符串"Hello World~~~"。 步骤…

数据结构:树的基本概念(二叉树,定义性质,存储结构)

目录 1.树1.基本概念1.空树2.非空树 2.基本术语1.结点之间的关系描述2.结点、树的属性描述3.有序树、无序树4.森林 3.树的常考性质 2.二叉树1.基本概念2.特殊二叉树1.满二叉树2.完全二叉树3.二叉排序树4.平衡二叉树 3.常考性质4.二叉树的存储结构1.顺序存储2.链式存储 1.树 1.…

MYSQL5.7和MYSQL8配置主从

1、创建专门主从的账号 #登录 mysql -u root -p #创建用户 我这里用户名为test5&#xff0c;注意这里的ip是从库服务器的ip CREATE USER test5192.168.1.20 IDENTIFIED WITH mysql_native_password BY xxxxx; #给主从复制账号授权 grant replication slave on *.* to test5192…

Java程序设计2023-第八次上机练习

8-1简单文本编辑器 编写简单文本编辑器&#xff0c;该程序可以新建、打开、编辑和保存文本文件。当用户点击New时&#xff0c;新建一个文件&#xff0c;用户可以编辑文件内容&#xff0c;然后点击Save保存文件。用户点击Open时&#xff0c;选择一个已有文件&#xff0c;然后可…