Android拖放startDragAndDrop拖拽Glide灵活加载堆叠圆角图,Kotlin(6)
Android拖放startDragAndDrop拖拽Glide灵活加载堆叠圆角图,Kotlin(6)
Android拖放startDragAndDrop拖拽Glide加载堆叠圆角图,Kotlin(5)-CSDN博客文章浏览阅读1.3k次。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/134269432上面文章(5)虽然可以做到拖拽实现Glide动态加载1张或若干张堆叠的旋转图片,但需要在xml布局和上层Kotlin代码中小心谨慎的写好(计算好)尺寸,否则会显示布局和View异常,不够灵活。这次,现在改造文章(5)中的实现,实现低代码、灵活加载旋转的堆叠图。
import android.content.ClipData
import android.content.Context
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.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.children
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCornersclass 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")}DragEvent.ACTION_DRAG_ENTERED -> {//进入imageViewLog.d(TAG, "ACTION_DRAG_ENTERED")}DragEvent.ACTION_DRAG_ENDED -> {//拖放结束Log.d(TAG, "ACTION_DRAG_ENDED")}DragEvent.ACTION_DRAG_EXITED -> {//离开imageViewLog.d(TAG, "ACTION_DRAG_EXITED")}}return true}})}private fun createDragShadowBuilder(): MyDragShadowBuilder {val shadowView = LayoutInflater.from(this).inflate(R.layout.dnd, null)return MyDragShadowBuilder(this, shadowView)}private fun setData(viewGroup: View) {//从1和4两个数字中随机选一个。var cnt = intArrayOf(1, 4).random()Log.d(TAG, "cnt=$cnt")val number = viewGroup.findViewById<TextView>(R.id.number)when (cnt) {1 -> {//只显示一张。number.text = "1"val fl: FrameLayout? = viewGroup as? FrameLayoutfl?.children?.filter {(it as? ImageView)?.tag == resources.getString(R.string.normal_image_view_tag)}?.forEach { view ->view.apply {View.GONE}}}4 -> {//显示重叠在一起的4张。number.text = "4"val resIds = arrayOf(R.mipmap.pic1,R.mipmap.pic2,R.mipmap.pic3)val fl: FrameLayout? = viewGroup as? FrameLayoutfl?.children?.filter {(it as? ImageView)?.tag == resources.getString(R.string.normal_image_view_tag)}?.forEachIndexed { index, view ->view.apply {View.VISIBLE}val degree = (resIds.size - index) * DEGREELog.d(TAG, "index=$index degree=$degree")view.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(view as ImageView)}}}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(ctx: Context, private var mShadow: View) :View.DragShadowBuilder() {//放大参数 1.5 , 2.0//适当的放大拖拽区域的面积,否则因为图片旋转,左右两侧和顶部因为旋转半径,图会被切边。//简单的说,绘制略微大一些的区域,容纳图片旋转,半径扫过的区域。private val width: Int =(ctx.resources.getDimensionPixelSize(R.dimen.image_size_w) * 1.5).toInt()private val height: Int =(ctx.resources.getDimensionPixelSize(R.dimen.image_size_h) * 2.0).toInt()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=${mShadow.width} height=${mShadow.height}")}}
}
dnd.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@android:color/holo_orange_light"><ImageViewandroid:id="@+id/iv1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:tag="@string/normal_image_view_tag" /><ImageViewandroid:id="@+id/iv2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:tag="@string/normal_image_view_tag" /><ImageViewandroid:id="@+id/iv3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:tag="@string/normal_image_view_tag" /><ImageViewandroid:id="@+id/folder"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center" /><androidx.cardview.widget.CardViewandroid:layout_width="30dp"android:layout_height="30dp"android:layout_gravity="top|right"app:cardBackgroundColor="@android:color/holo_red_light"app:cardCornerRadius="15dp"><TextViewandroid:id="@+id/number"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="--"android:textColor="@android:color/white"android:textSize="15dp" /></androidx.cardview.widget.CardView>
</FrameLayout>
注意,根布局layout如果不使用FrameLayout,而是其他layout布局如RelativeLayout或ConstraintLayout,xml里面定义的居中放置子View失效。
dimens.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources><dimen name="image_size_w">180dp</dimen><dimen name="image_size_h">120dp</dimen>
</resources>
strings.xml:
<resources><string name="normal_image_view_tag">normal_image_view_tag</string>
</resources>
拖拽1张图片:

拖拽4张图片,背景3张旋转,封面不旋转:

Android改造CardView为圆形View,Kotlin_android 圆形view-CSDN博客文章浏览阅读1k次。可以利用androidx.cardview.widget.CardView的cardCornerRadius特性,将CardView改造成一个圆形的View,技术实现的关键首先设定CardView为一个宽高相等的View(正方形),然后将radius特意设置成宽度(或高度,一样,因为正方形,宽高相等)的1/2,此时CardView自然就变成一个圆。Android RoundedBitmapDrawable:Android官方的圆角图形图象实现方案_android 官方圆角-CSDN博客。_android 圆形viewhttps://blog.csdn.net/zhangphil/article/details/133346170
相关文章:
Android拖放startDragAndDrop拖拽Glide灵活加载堆叠圆角图,Kotlin(6)
Android拖放startDragAndDrop拖拽Glide灵活加载堆叠圆角图,Kotlin(6) Android拖放startDragAndDrop拖拽Glide加载堆叠圆角图,Kotlin(5)-CSDN博客文章浏览阅读1.3k次。Android Dyna…...
计算机网络课后作业2023秋
计算机网络第三版吴功宜版 课后作业 第一章作业三、计算与问答3.73.8 第二章作业三、计算与问答3.23.53.6 第三章作业三、计算与问答3.13.53.73.8 第四章作业三、计算与问答3.13.2 第五章作业三、计算与问答3.13.33.4VLAN交换机模式模式切换重置交换机VLAN配置命令其…...
阿里云国际站:全球加速GA
文章目录 一、前言 二、阿里云全球加速的概念 三、阿里云全球加速的功能优势 四、阿里云全球加速的原理 五、阿里云全球加速的应用场景 六、写在最后 一、前言 随着互联网的快速发展,网站速度已经成为了用户访问体验的一个重要指标。阿里云加速作为一种新的技…...
M2LC-Net
模型结构 作者未提供代码...
Jenkins 质量扫描
代码质量扫描工具(SonarQube) 质量评审 SonarQube有四个关键组件 ◼ SonarQube Server运行有三个组件 ◆ Web Server:UI ◆ Search Server:为UI提供搜索功能,基于ElasticSearch ◆ Compute Engine Server:…...
【LeetCode刷题笔记】滑动窗口
992. K 个不同整数的子数组 解题思路: 滑动窗口 , 题目问题转化为: 求 「最多存在 K 个不同整数的子数组的个数」 与 「最多存在 K - 1 个不同整数的子数组的个数」 之差, 就是题目所求的 「恰好存在 K 个不同整数的子数组的个数」 , 最终问题就变成求解滑动窗口内,以 R …...
笔试题之指针和数组的精讲
𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - :来于“云”的“羽球人”。…...
.secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
导言: 勒索病毒成为了网络安全的一项严峻挑战,其中.secret勒索病毒尤为引人注目。这种恶意软件通过加密用户的数据文件,使其无法访问,并勒索受害者支付赎金以获取解密密钥。本文将介绍.secret勒索病毒的基本信息,以及…...
junit写搜索树测试
用法 assertTrue(range.contains("Two")); 2个参数,右边错就打印左边. AbstractSelfBalancingBinarySearchTree abt; AbstractBinarySearchTree.Node node; Before public void setUp() { abt new AbstractSelfBalancingBinarySearchTree() { Override protecte…...
顺丰接口对接-订单创建与取消(java单元测试)
api文档 下单接口 :https://qiao.sf-express.com/Api/ApiDetails?level3393&interName%E4%B8%8B%E8%AE%A2%E5%8D%95%E6%8E%A5%E5%8F%A3-EXP_RECE_CREATE_ORDER 取消订单接口: https://qiao.sf-express.com/Api/ApiDetails?level3339&interNa…...
C++:OJ练习(每日练习!)
编程题: 题一:计算日期到天数的转换 计算日期到天数转换_牛客题霸_牛客网 (nowcoder.com) 示例1 输入: 2012 12 31 输出: 366 思路一: 第一步:创建年,月,日的变量,并按…...
GPTs Hunter 是什么?
原文: https://openaigptguide.com/openai-gpts-hunter/ GPTs Hunter 是一个功能强大的免费导航网站,支持多语言,提供用户友好的界面。 GPTs Hunter:功能强大的免费导航网站 GPTs Hunter是一个功能强大的免费导航网站ÿ…...
【移远QuecPython】EC800M物联网开发板的硬件TIM定时器精准延时
【移远QuecPython】EC800M物联网开发板的硬件TIM定时器精准延时 文章目录 导入库定时器初始化延时函数定时中断回调调用函数打包附录:列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包 首先 这个定时器是硬件底层级别的 优先级最高 如果调用 会导致GN…...
HDU 1027:Ignatius and the Princess II ← next_permutation()
【题目来源】http://acm.hdu.edu.cn/showproblem.php?pid1027【题目描述】 Now our hero finds the door to the BEelzebub feng5166. He opens the door and finds feng5166 is about to kill our pretty Princess. But now the BEelzebub has to beat our hero first. feng5…...
主题讲座:全球增材制造现状与未来(暨香港科技大学广州|智能制造学域2024博士学位全额奖学金项目)
时间:2023 年11月16日(星期四)14:30 地点:合肥工业大学 学术会议中心三楼报告厅 主讲嘉宾:陈模军 助理教授 https://facultyprofiles.hkust-gz.edu.cn/faculty-personal-page/CHEN-Mojun/mjchen 报名表直达࿱…...
hugeGraph修改PropertyKey属性类型
修改PropertyKey字段属性的类型,发现没办法保留数据的前提下修改,智能是先删除数据,然后再修改,或者备份后修改再恢复。 方法一、 修改groovy脚本中的Text为Int后重新建元数据 schema.propertyKey(“youkey”).asText().valueSing…...
vscode 访问本地或者远程docker环境
1、vscode 访问docker本地环境 直接点击左下角连接图标,弹出选项可以选择容器,只要容器在本地运行者,选择attach可以看到运行中的容器可以选择,选择其中需要选择的就行 ## 运行容器,可以-d后台运行都可以 docker run…...
人工智能与充电技术:携手共创智能充电新时代
人工智能与充电技术:携手共创智能充电新时代 摘要:本文探讨了人工智能与充电技术的结合及其在未来充电设施领域的应用。通过分析智能充电系统的技术原理、优势以及挑战,本文展望了由人工智能驱动的充电技术为未来电动交通带来的巨大变革与机…...
『自定义B站视频播放速度』
哔哩哔哩 的最高播放速度是 2.0, 但对于我们这种程序员来说,2.0 速度观看学习视频还是稍微慢了点, 🫵🏻3.0 以上才是王道🫵🏻, 下面就是具体的操作方法: ① 在浏览器…...
Java入门篇 之 继承
本篇碎碎念:最近的课程遇到瓶颈了,看的时候感觉自己会了,但是结束仔细一回顾还是一知半解,一点一点来吧,基础必须要打好(自己给自己好的心里暗示,结局一定是好的) 今日份励志文案:慢慢改变,慢慢…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
论文阅读:Matting by Generation
今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...
路由基础-路由表
本篇将会向读者介绍路由的基本概念。 前言 在一个典型的数据通信网络中,往往存在多个不同的IP网段,数据在不同的IP网段之间交互是需要借助三层设备的,这些设备具备路由能力,能够实现数据的跨网段转发。 路由是数据通信网络中最基…...
