当前位置: 首页 > news >正文

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的亮灯逻辑辨析
  • Linux学习笔记3-GPIO(1)
  • 63基于matlab的生物地理的优化器(BBO)被用作多层感知器(MLP)的训练器。
  • Python---集合中的交集 、并集 | 与差集 - 特性
  • 基于单片机的塑料厂房气体检测系统设计
  • Java读取文件内容写入新文件
  • 深入理解 Django 单元测试
  • 企业大数据治理管理平台解决方案:PPT全文33页,附下载
  • 四、Vue3中使用Pinia解构Store
  • UML建模语言
  • Linux 安装与配置
  • SpringBoot 是什么
  • Python数据容器之[列表]
  • postman上传照片,视频,音频等上传文件操作测试方法
  • 【C#学习】backgroundWorker控件
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • Brief introduction of how to 'Call, Apply and Bind'
  • input实现文字超出省略号功能
  • Java基本数据类型之Number
  • mysql 5.6 原生Online DDL解析
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • 二维平面内的碰撞检测【一】
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 两列自适应布局方案整理
  • 前嗅ForeSpider中数据浏览界面介绍
  • 鱼骨图 - 如何绘制?
  • nb
  • 国内开源镜像站点
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • #14vue3生成表单并跳转到外部地址的方式
  • #HarmonyOS:Web组件的使用
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (solr系列:一)使用tomcat部署solr服务
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (十) 初识 Docker file
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)母版页和相对路径
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .Net中wcf服务生成及调用
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka
  • @RequestMapping用法详解
  • @在php中起什么作用?
  • [ NOI 2001 ] 食物链
  • [ 常用工具篇 ] POC-bomber 漏洞检测工具安装及使用详解
  • [.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序...
  • [BUAA软工]第一次博客作业---阅读《构建之法》
  • [BZOJ1089][SCOI2003]严格n元树(递推+高精度)
  • [CC-FNCS]Chef and Churu