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

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

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

相关文章

【C++】:STL——标准模板库介绍 || string类

&#x1f4da;1.什么是STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且 是一个包罗数据结构与算法的软件框架 &#x1f4da;2.STL的版本 原始版本 Alexander Stepanov、Meng Lee 在…

【深度学习】可交互讲解图神经网络GNN

在正式开始前&#xff0c;先找准图神经网络GNN(Graph Neural Network)的位置。 图神经网络GNN是深度学习的一个分支。 深度学习的四个分支对应了四种常见的数据格式&#xff0c;前馈神经网络FNN处理表格数据&#xff0c;表格数据可以是特征向量&#xff0c;卷积神经网络CNN处理…

Java 入门基础题

目录 1.输出一个整数的每一位 2.判定素数 3.求最大值方法的重载 4.输出闰年 5.打印 X 图形 6.数字9 出现的次数 7.计算分数的值 8. 模拟登陆 9.使用函数求最大值 10.斐波那契数列 星光不负赶路人&#xff0c;加油铁子们&#xff01;&#xff01;&#xff01; 1…

RT-DETR算法优化改进:Backbone改进 | VanillaNet一种新视觉Backbone,极简且强大!华为诺亚2023

💡💡💡本文独家改进: VanillaNet助力RT-DETR ,替换backbone,简到极致、浅到极致!深度为6的网络即可取得76.36%@ImageNet的精度,深度为13的VanillaNet甚至取得了83.1%的惊人性能。 推荐指数:五星 RT-DETR魔术师专栏介绍: https://blog.csdn.net/m0_63774211/cat…

11-13 /11-14代理模式 AOP

调用者 代理对象 目标对象 代理对象除了可以完成核心任务&#xff0c;还可以增强其他任务,无感的增强 代理模式目的: 不改变目标对象的目标方法的前提,去增强目标方法 分为:静态代理,动态代理 静态代理 有对象->前提需要有一个类&#xff0c;那么我们可以事先写好一个类&a…

【Python基础篇】字面量

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录 一 Python中字面量的定义二 常见的字面量类型1 数字(Number)2 字符串(String)3 列表(List)4 元…

微信小程序:仅前端实现对象数组的模糊查询

效果 核心代码 //对数组进行过滤&#xff0c;返回数组中每一想满足name值包括变量query的 let result array.filter(item > { return item.name.includes(query); }); 完整代码 wxml <input type"text" placeholder"请输入名称" placeholder-styl…

前端工具nvm实现node自由

node的自由之路 前言 大家使用vue框架开发的朋友可能会遇到首次运行公司项目环境的时候&#xff0c;会出现使用npm install命令安装依赖包的时候出现各种各样的问题&#xff0c;其中很重要的一个错误原因就是因为你的nodejs版本和当时搭建环境的版本不一致造成的。今天就来给…

R语言——taxize(第一部分)

ropensci 系列之 taxize &#xff08;中译手册&#xff09; taxize 包1. taxize支持的网络数据源简介目前支持的API&#xff1a;针对Catalogue of Life&#xff08;COL&#xff09; 2. 浅尝 taxize 的一些使用例子2.1. **从NCBI上获取唯一的分类标识符**2.2. **获取分类信息**2…

网络安全基础之php开发文件上传的实现

前言 php是网络安全学习里必不可少的一环&#xff0c;简单理解php的开发环节能更好的帮助我们去学习php以及其他语言的web漏洞原理 正文 在正常的开发中&#xff0c;文件的功能是必不可少&#xff0c;比如我们在论坛的头像想更改时就涉及到文件的上传等等文件功能。但也会出…

基于SpringBoot+Vue的宿舍管理系统

基于SpringBootVue的学生宿舍管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 宿舍公告 登录界面 管理员界面 维修人员 商家界面 学生界面 摘要 摘…

Azure 机器学习:在 Azure 机器学习中使用 Azure OpenAI 模型

目录 一、环境准备二、Azure 机器学习中的 OpenAI 模型是什么&#xff1f;三、在机器学习中访问 Azure OpenAI 模型连接到 Azure OpenAI部署 Azure OpenAI 模型 四、使用自己的训练数据微调 Azure OpenAI 模型使用工作室微调微调设置训练数据自定义微调参数部署微调的模型 使用…

Python---集合中的交集 、并集 | 与差集 - 特性

用 & 来求两个集合的交集&#xff1a;-----键盘上的7上的符号&#xff0c;shift 7 同时按 用 | 来求两个集合的并集&#xff1a; -----键盘上的7上的符号&#xff0c;shift 同时按&#xff08;就是enter键上面那个|\ &#xff09; 用 - 来求两个集合的差集&#xff…

抖斗音_快块手直播间获客助手+采集脚本+引流软件功能介绍

软件功能&#xff1a; 支持同时采集多个直播间&#xff0c;弹幕&#xff0c;关*注&#xff0c;礼*物&#xff0c;进直播间&#xff0c;部分用户手*号,粉*丝团采集 不支持采集匿*名直播间 设备需求&#xff1a; 电脑&#xff08;win10系统&#xff09; 文章分享者&#xff1…

Kerberos认证系统

文章目录 前提知识原理第一次对话第二次对话第三次对话 总结发现 前提知识 KDC&#xff1a;由AS、TGS&#xff0c;还有一个Kerberos Database组成。 Kerberos Database用来存储用户的密码或者其他所有信息&#xff0c;请求的时候需要到数据库中查找。 AS&#xff1a;为客户端提…

Python爬虫抓取微博数据及热度预测

首先我们需要安装 requests 和 BeautifulSoup 库&#xff0c;可以使用以下命令进行安装&#xff1a; pip install requests pip install beautifulsoup4然后&#xff0c;我们需要导入 requests 和 BeautifulSoup 库&#xff1a; import requests from bs4 import BeautifulSou…

No203.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

小H靶场学习笔记:DC-2

DC-2 Created: November 10, 2023 3:01 PM Tags: WordPress, git提权, rbash逃逸 Owner: 只会摸鱼 靶场过程 信息收集 扫描存活主机&#xff0c;找到靶机ip&#xff1a;192.168.199.131&#xff08;本机是192.168.199.129&#xff09; 扫描端口开放协议 发现有80端口和77…

2023nacos源码解读第3集——nacos-client核心功能之微服务调用和配置管理测试

文章目录 1、测试项目2、项目注意事项3、 测试核心功能3.1 测试服务调用与负载均衡3.2 测试配置监听 4、参考文档 1、测试项目 项目地址 nacos-service-a nacos-service-b 2、项目注意事项 项目初始化可以使用aliyun spring initializer ,以更方便的使用springcloud alibaba…

hive里因为列名用了关键字导致建表失败

代码 现象 ParseException line 6:4 cannot recognize input near percent String COMMENT in column name or primary key or foreign key 23/11/13 11:52:57 ERROR org.apache.hadoop.hive.ql.Driver: FAILED: ParseException line 6:4 cannot recognize input near percent …