Android Glide, first start based on loadThumbnail, Kotlin(二)

Android Glide, first start based on loadThumbnail, Kotlin(二)

 

Android Glide, first start based on loadThumbnail, Kotlin(一)中有个小问题,通过loadThumbnail()采集到的缩略图真的就是整张图片的完整缩略图,直接放在正方形小格子里面,明显看到左右或者上下有空隙,因此,现在对这一情况改善,对loadThumbnail采集到的缩略图拉伸成标准的正方形图。

 

import android.content.ContentValues
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat
import androidx.core.view.setPadding
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat

class MainActivity : AppCompatActivity() {
    companion object {
        const val TAG = "glide-fly"

        const val SIZE = 450

        const val VIEW_TYPE = 0
        const val DATE_TYPE = 1

        const val SPAN_COUNT = 6

        const val PAD_SIZE = 1

        var FIRST_START = true
    }

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

        val rv: RecyclerView = findViewById(R.id.rv)

        rv.setHasFixedSize(true)
        rv.setItemViewCacheSize(SPAN_COUNT * 10)

        /*
        rv.setRecyclerListener(object : RecyclerListener {
            override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
                if ((holder as MyVH).itemView is MyIV) {
                    GlideApp.with(holder.itemView.context).clear(holder.itemView)
                }
            }
        })
         */

        val layoutManager = MyGridLayoutManager(this, SPAN_COUNT)
        layoutManager.orientation = LinearLayoutManager.VERTICAL
        rv.layoutManager = layoutManager

        val adapter = MyAdapter(this)
        rv.adapter = adapter

        lifecycleScope.launch(Dispatchers.IO) {
            val items = readAllImage(this@MainActivity)

            items.sortByDescending {
                it.dateModified
            }

            val lists = items.distinctBy {
                it.dateString
            }

            lists.forEach { it_lists ->
                val idx = items.indexOfFirst {
                    it_lists.dateString == it.dateString
                }

                val data = MyData()
                data.type = DATE_TYPE
                data.dateString = it_lists.dateString
                items.add(idx, data) //不要直接加 it_Lists,这里面涉及到List的深拷贝/浅拷贝问题。
            }

            withContext(Dispatchers.Main) {
                adapter.dataChanged(items)
            }
        }

        layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
                return if (adapter.getItemViewType(position) == DATE_TYPE) {
                    //group,标题
                    SPAN_COUNT
                } else {
                    //单个小格子
                    1
                }
            }
        }
    }

    class MyGridLayoutManager : GridLayoutManager {
        constructor(ctx: Context, cnt: Int) : super(ctx, cnt) {

        }

        override fun getExtraLayoutSpace(state: RecyclerView.State?): Int {
            return 1000
        }
    }

    class MyAdapter : RecyclerView.Adapter<MyVH> {
        private var mItems = arrayListOf<MyData>()

        private var mContext: Context? = null
        private var mPlaceholder: Drawable? = null
        private var mError: Drawable? = null

        constructor(ctx: Context) {
            mContext = ctx

            mPlaceholder = ContextCompat.getDrawable(mContext!!, android.R.drawable.ic_menu_gallery)
            mError = ContextCompat.getDrawable(mContext!!, android.R.drawable.stat_notify_error)
        }

        fun dataChanged(items: ArrayList<MyData>) {
            this.mItems = items
            notifyDataSetChanged()
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyVH {
            var v: View?
            if (viewType == VIEW_TYPE) {
                v = MyIV(mContext!!)
            } else {
                v = LayoutInflater.from(mContext!!).inflate(android.R.layout.simple_list_item_1, null)
                v.setBackgroundColor(Color.LTGRAY)
            }

            return MyVH(v!!)
        }

        override fun getItemCount(): Int {
            return mItems.size
        }

        override fun getItemViewType(position: Int): Int {
            return mItems[position].type
        }

        private fun getImageUri(context: Context, filePath: String): Uri? {
            val cursor = context.contentResolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                arrayOf(MediaStore.Images.Media._ID),
                MediaStore.Images.Media.DATA + "=? ",
                arrayOf(filePath),
                null
            )

            return if (cursor != null && cursor.moveToFirst()) {
                val id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
                val baseUri = Uri.parse("content://media/external/images/media")
                Uri.withAppendedPath(baseUri, "" + id)
            } else {
                val values = ContentValues()
                values.put(MediaStore.Images.Media.DATA, filePath)
                context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
            }
        }

        override fun onBindViewHolder(holder: MyVH, position: Int) {
            val type = getItemViewType(position)
            if (type == VIEW_TYPE) {
                val path = mItems[holder.adapterPosition].path
                val miv = holder.itemView as MyIV

                if (position > 50) {
                    FIRST_START = false
                }

                if (FIRST_START && position < 50) {
                    miv.setImageDrawable(mPlaceholder)
                    val uri = getImageUri(mContext!!, path!!)
                    QuickLoader.Instance().start(mContext!!, uri!!, miv)
                } else {
                    GlideApp.with(mContext!!)
                        .asBitmap()
                        .load(path)
                        .centerCrop()
                        .override(SIZE)
                        .placeholder(mPlaceholder)
                        .error(mError)
                        .into(miv)
                }
            } else if (type == DATE_TYPE) {
                holder.itemView.findViewById<TextView>(android.R.id.text1).text = "${mItems[position].dateString}"
            }
        }
    }

    class MyVH : RecyclerView.ViewHolder {
        constructor(itemView: View) : super(itemView) {

        }
    }

    class MyIV : AppCompatImageView {
        constructor(ctx: Context) : super(ctx) {
            setPadding(PAD_SIZE)
        }

        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec)
            val w = MeasureSpec.getSize(widthMeasureSpec)
            val h = MeasureSpec.getSize(heightMeasureSpec)
            val size = Math.max(w, h) //取w,h的最大值。
            setMeasuredDimension(size, size) //使得ImageView为正方形。
        }
    }

    class MyData {
        var type = VIEW_TYPE

        var dateModified: Long? = 0L
        var dateString: String? = null
        var path: String? = null
        var index: Int? = null

        override fun toString(): String {
            return "MyData(type=$type, dateModified=$dateModified, dateString=$dateString, path=$path, index=$index)"
        }
    }

    private fun readAllImage(context: Context): ArrayList<MyData> {
        val photos = ArrayList<MyData>()

        //读取所有图片
        val cursor = context.contentResolver.query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null
        )

        var index = 0
        val sdf = SimpleDateFormat("yyyy-MM-dd")
        while (cursor!!.moveToNext()) {
            //路径 uri
            val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))
            if (TextUtils.isEmpty(path)) {
                continue
            }

            val dateModified = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_MODIFIED))

            //图片名称
            //val name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
            //图片大小
            //val size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE))

            val dateStr = sdf.format(dateModified?.toLong()!! * 1000)

            val data = MyData()
            data.type = VIEW_TYPE
            data.path = path
            data.dateModified = dateModified.toLong()
            data.dateString = dateStr
            data.index = index++

            photos.add(data)
        }
        cursor.close()

        return photos
    }
}

 

 

 

 

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.RectF
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import android.util.Size
import androidx.appcompat.app.AppCompatActivity
import com.pkg.name0220.MainActivity.Companion.SIZE
import java.util.concurrent.Executors
import kotlin.math.min


class QuickLoader {
    private var mHandler: MsgHandler? = null

    companion object {
        const val THREAD_NUMBER = 4

        const val WHAT = 0xf01

        private val inst by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { QuickLoader() }
        fun Instance() = inst

        /**
         * 把采集到的缩略图(可能是瘦长的,也可能是矮平的)拉伸为宽高为标准MainActivity.SIZE的Bitmap。
         * 注意:Bitmap的API函数createScaledBitmap()相对耗时更多。
         */
        fun scale(srcBmp: Bitmap): Bitmap {
            val t = System.currentTimeMillis()

            val bmp = Bitmap.createBitmap(SIZE, SIZE, Bitmap.Config.ARGB_8888)
            val c = Canvas(bmp)

            val width: Int = srcBmp.width
            val height: Int = srcBmp.height

            val bmpCenterX: Float = width / 2f
            val bmpCenterY: Float = height / 2f

            val minVal = min(width, height)

            val srcRectF = RectF(
                bmpCenterX - minVal / 2,
                bmpCenterY - minVal / 2,
                bmpCenterX + minVal / 2,
                bmpCenterY + minVal / 2
            )

            val dstRectF = RectF(0f, 0f, SIZE.toFloat(), SIZE.toFloat())
            val matrix = Matrix()
            //把bitmap中心区域的那一块放到目标的dstRectF里面。
            matrix.setRectToRect(srcRectF, dstRectF, Matrix.ScaleToFit.CENTER)
            c.drawBitmap(srcBmp, matrix, null)

            Log.d("耗时", "scale=${System.currentTimeMillis() - t}")

            return bmp
        }
    }

    private constructor() {
        Log.d(MainActivity.TAG, "QuickLoader 初始化")
        mHandler = MsgHandler()
    }

    fun start(ctx: Context, uri: Uri, miv: MainActivity.MyIV) {
        val msg = mHandler?.obtainMessage(WHAT)
        msg?.obj = LoadTask(ctx, uri, miv)
        mHandler?.sendMessage(msg!!)
    }

    private class MsgHandler : Handler {
        private var mExecutorService = Executors.newFixedThreadPool(THREAD_NUMBER)

        constructor() : super(Looper.getMainLooper()) {
            Log.d(MainActivity.TAG, "MsgHandler 初始化")
        }

        override fun handleMessage(msg: Message) {
            mExecutorService.execute(msg.obj as LoadTask)
        }

        fun destroy() {
            removeMessages(WHAT)

            mExecutorService.shutdownNow()
            mExecutorService = null
        }
    }

    class LoadTask(private val ctx: Context, private val uri: Uri, private val miv: MainActivity.MyIV) : Runnable {
        override fun run() {
            Log.d(MainActivity.TAG, "run $uri")

            val t = System.currentTimeMillis()
            val bmp = ctx.contentResolver?.loadThumbnail(uri, Size(MainActivity.SIZE, MainActivity.SIZE), null)
            Log.d(MainActivity.TAG, "LoadTask 耗时:${System.currentTimeMillis() - t} $uri")

            (ctx as AppCompatActivity).runOnUiThread {
                miv.setImageBitmap(scale(bmp!!))
            }
        }
    }

    fun destroy() {
        mHandler?.destroy()
        mHandler = null
    }
}

 

 

 

 

 

 

 

 

Android矩阵Matrix setRectToRect实现标准scaleType中心缩放centerCrop,Kotlin-CSDN博客文章浏览阅读516次,点赞15次,收藏13次。Android拼接合并图片生成长图代码实现合并两张图片,以第一张图片的宽度为标准,如果被合并的第二张图片宽度和第一张不同,那么就以第一张图片的宽度为准线,对第二张图片进行缩放。Android拼接合并图片生成长图代码实现合并两张图片,以第一张图片的宽度为标准,如果被合并的第二张图片宽度和第一张不同,那么就以第一张图片的宽度为准线,对第二张图片进行缩放。基础上,把剪切的区域从矩形Rect变为圆形的Path,当手指在上面的ImageView移动时候,下面同等大小对应的坐标区域显示“剪切”出来的圆形图。https://blog.csdn.net/zhangphil/article/details/139753381

Android Glide, first start based on loadThumbnail, Kotlin(一)-CSDN博客文章浏览阅读642次,点赞13次,收藏12次。【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬而未决:比如用户的头像,往往用户的头像是从服务器端读出的一个普通矩形图片,但是现在的设计一般要求在APP端的用户头像显示成圆形头像,那么此时虽然Glide可以加载,但加载出来的是一个矩形,如果要Glide_android 毛玻璃圆角。Android 13手机图片存储File路径转Uri,Java_android file 转uri-CSDN博客。文章浏览阅读690次。https://blog.csdn.net/zhangphil/article/details/139743546

Android简单把高大于宽或宽大于高的图从中心截成正方形,Kotlin-CSDN博客文章浏览阅读744次,点赞9次,收藏12次。Android BitmapFactory.decodeResource读取原始图片装载成原始宽高Bitmap,Kotlin_bitmapfactory解码宽高-CSDN博客。Android矩阵setRectToRect裁剪Bitmap原图Matrix放大,mapRect标记中心区域,Kotlin-CSDN博客。实现的是把原图中心区域的一片小图挖取出来放大放到下面的ImageView里面,现在不再固定中心位置,而是以手指在上图的触点位置为中心位置,挖取一片区域图放大,然后放到下面的ImageView里面。https://blog.csdn.net/zhangphil/article/details/139181062

Android用setRectToRect实现Bitmap基于Matrix矩阵scale缩放RectF动画,Kotlin(二)_android bitmap 动画-CSDN博客文章浏览阅读770次,点赞4次,收藏5次。【代码】Android用setRectToRect实现Bitmap基于Matrix矩阵scale缩放RectF动画,Kotlin(二)_android bitmap 动画https://blog.csdn.net/zhangphil/article/details/135992780Android用setRectToRect实现Bitmap基于Matrix矩阵scale缩放RectF动画,Kotlin(一)_android matrix setrecttorect-CSDN博客文章浏览阅读1.2k次,点赞14次,收藏8次。基于Matrix,控制Bitmap的setRectToRect的目标RectF的宽高。从很小的宽高开始,不断迭代增加setRectToRect的目标RectF的宽高,每次迭代加上一定时延,实现Matrix基础上的动画。文章浏览阅读180次。【代码】Android矩阵setRectToRect裁剪Bitmap原图Matrix放大,mapRect标记中心区域,Kotlin。Android矩阵setRectToRect裁剪Bitmap原图Matrix放大,mapRect标记中心区域,Kotlin-CSDN博客。_android matrix setrecttorecthttps://blog.csdn.net/zhangphil/article/details/135980821Android矩阵Matrix变换setRectToRect,Kotlin_android rect 矩阵-CSDN博客文章浏览阅读709次,点赞7次,收藏8次。Android拼接合并图片生成长图代码实现合并两张图片,以第一张图片的宽度为标准,如果被合并的第二张图片宽度和第一张不同,那么就以第一张图片的宽度为准线,对第二张图片进行缩放。Android拼接合并图片生成长图代码实现合并两张图片,以第一张图片的宽度为标准,如果被合并的第二张图片宽度和第一张不同,那么就以第一张图片的宽度为准线,对第二张图片进行缩放。基础上,把剪切的区域从矩形Rect变为圆形的Path,当手指在上面的ImageView移动时候,下面同等大小对应的坐标区域显示“剪切”出来的圆形图。_android rect 矩阵https://blog.csdn.net/zhangphil/article/details/135913218

Android矩阵Matrix裁切setRectToRect拉伸Bitmap替代Bitmap.createScaledBitmap缩放,Kotlin-CSDN博客文章浏览阅读1.1k次,点赞7次,收藏14次。Android拼接合并图片生成长图代码实现合并两张图片,以第一张图片的宽度为标准,如果被合并的第二张图片宽度和第一张不同,那么就以第一张图片的宽度为准线,对第二张图片进行缩放。Android拼接合并图片生成长图代码实现合并两张图片,以第一张图片的宽度为标准,如果被合并的第二张图片宽度和第一张不同,那么就以第一张图片的宽度为准线,对第二张图片进行缩放。基础上,把剪切的区域从矩形Rect变为圆形的Path,当手指在上面的ImageView移动时候,下面同等大小对应的坐标区域显示“剪切”出来的圆形图。_createscaledbitmaphttps://blog.csdn.net/zhangphil/article/details/135961734

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PTP简介及Linux phy ptp驱动实现

1、PTP简介 PTP(precision time protocol)精确时间协议&#xff0c;是一种时间同步的协议&#xff0c;对应 IEEE 1588 标准&#xff0c;是基于网络数据包的一种时间同步协议&#xff0c;1588v2的同步精度可以达到ns级&#xff0c;但1588协议对硬件有依赖。 2、PTP原理 时间同…

Part 6.2.3 欧拉函数

欧拉函数φ(x) 表示了小于x的数字中&#xff0c;与x互质的数字个数。 关于欧拉函数的基本知识>欧拉函数的求解< [SDOI2008] 仪仗队 题目描述 作为体育委员&#xff0c;C 君负责这次运动会仪仗队的训练。仪仗队是由学生组成的 N N N \times N NN 的方阵&#xff0c;…

使用Docker在Mac上部署OnlyOffice,预览编辑word、excel、ppt非常好

前端编辑word、ppt文档&#xff0c;开源免费方案并没有找到合适的&#xff0c;像wps、石墨文档都是自研的方案。实现过程中wps采用的svg方案&#xff0c;而石墨文档采用的是canvas&#xff0c;它们均是自己来实现编辑器&#xff0c;不依赖浏览器提供的编辑器&#xff08;conten…

如何用python调用C++处理图片

一. 背景 用pyhton可直接调用C&#xff0c;减少重写的工作量&#xff1b;部分逻辑运算&#xff0c;C的执行效率高&#xff0c;可进行加速。 下面就一个简单的C滤镜&#xff08;彩色图转灰度图&#xff09;为例&#xff0c;展示python调用C 二. 代码实现 代码结构如下&#x…

Windows桌面运维----第四天

1、U盘故障打不开&#xff1a; 操作方式&#xff1a;WinR打开运行&#xff0c;输入cmd确定&#xff0c;在&#xff08;C:\Users\Administrator>&#xff09;后输入chkdsk,空格&#xff0c;输入U盘盘符&#xff0c;例如F:/F&#xff0c;回车&#xff0c;等待修复完成。 2、…

韩国裸机云站群服务器托管租用方案

随着网络技术的飞速发展&#xff0c;站群服务器在网站运营中扮演着越来越重要的角色。韩国裸机云站群服务器&#xff0c;以其独特的优势&#xff0c;如地理位置优越、价格相对较低、技术实力雄厚等&#xff0c;吸引了众多企业的关注。本文将为您详细介绍韩国裸机云站群服务器的…

【TB作品】MSP430G2553,单片机,口袋板, 现场数据采集装置设计

题2 现场数据采集装置设计 便携式数据采集装置将在现场采集到的数据装入装置的内部数存贮器&#xff0c;以待送实验室或试验中心的计算机进行分析处理&#xff0c;由于现场不一定有交流电供电&#xff0c;而且采集到的数据必须保存到送实验室&#xff0c;因此装置必须以电池或蓄…

红米手机RedNot11无法使用谷歌框架,打开游戏闪退的问题,红米手机如何开启谷歌框架

红米手机RedNot11无法使用谷歌框架&#xff0c;打开游戏闪退的问题&#xff0c; 1.问题描述2.问题原因3.解决方案3.1配置谷歌框架&#xff1a;3.1软件优化 4.附图 1.问题描述 红米手机打开安卓APP没有广告&#xff0c;直接闪退&#xff0c;无法使用谷歌框架 异常关键词中包含&…

NavicatforMySQL11.0软件下载-NavicatMySQL11最新版下载附件详细安装步骤

我们必须承认Navicat for MySQL 支援 Unicode&#xff0c;以及本地或远程 MySQL 服务器多连线&#xff0c;使用者可浏览数据库、建立和删除数据库、编辑数据、建立或执行 SQL queries、管理使用者权限&#xff08;安全设定&#xff09;、将数据库备份/复原、汇入/汇出数据&…

SAS副总裁Jason Mann:物联网如何让世界变得更美好

TechForge最近采访了数据和人工智能领导者 SAS的物联网副总裁 Jason Mann &#xff0c;他解释了公司如何有效利用物联网&#xff0c;以及该技术如何改善全球的可持续性。 您认为今年物联网领域的最新发展趋势是什么&#xff1f; 一个主要趋势是GenAI的不断涌现&#xff0c;这进…

计算机网络:运输层 - TCP 流量控制 拥塞控制

计算机网络&#xff1a;运输层 - TCP 流量控制 & 拥塞控制 滑动窗口流量控制拥塞控制慢开始算法拥塞避免算法快重传算法快恢复算法 滑动窗口 如图所示&#xff1a; 在TCP首部中有一个窗口字段&#xff0c;该字段就基于滑动窗口来辅助流量控制和拥塞控制。所以我们先讲解滑…

Spark Core内核调度机制详解(第5天)

系列文章目录 如何构建DAG执行流程图 (掌握)如何划分Stage阶段 (掌握)Driver底层是如何运转 (掌握)确定需要构建多少分区(线程) (掌握) 文章目录 系列文章目录引言一、Spark内核调度&#xff08;掌握&#xff09;1.1、内容概述1.2、RDD的依赖1.3、DAG和Stage1.4、Spark Shuffl…

Flink 1.19.1 standalone 集群模式部署及配置

flink 1.19起 conf/flink-conf.yaml 更改为新的 conf/config.yaml standalone集群: dev001、dev002、dev003 config.yaml: jobmanager address 统一使用 dev001&#xff0c;bind-port 统一改成 0.0.0.0&#xff0c;taskmanager address 分别更改为dev所在host dev001 config.…

M1失效后,哪个是观察A股的关键新指标?

M1失效后&#xff0c;哪个是观察A股的关键新指标&#xff1f; 央地支出增速差&#xff08;地方-中央支出增速的差值&#xff09;或许是解释沪深300定价更有效的前瞻指标。该数值扩张&#xff0c;则有利于大盘指数&#xff0c;反之亦然&#xff0c;该指标从2017年至今对大盘指数…

网络程序通信的流程---socket与TCP的简单认识

网络程序通信的流程 网络程序通信的流程&#xff1a; 1.通过ip地址找到网络中的设备 2.通过端口号找到对应进程的端口 3.传输数据时还需要使用传输协议&#xff08;TCP&#xff09;&#xff0c;保证数据的可靠性 4.socket完成进程之间网络数据的传输 ip地址的介绍 IP地址…

在小程序wxml中截取字符串

在微信小程序的WXML中直接进行字符串截取是不被支持的&#xff0c;因为WXML主要负责布局和渲染&#xff0c;不包含数据处理逻辑。 但你可以通过使用微信小程序提供的wxs&#xff08;WeiXin Script&#xff09;来实现字符串的截取。 wxs是一种运行在客户端的脚本语言&#xff…

LeetCode 算法:删除链表的倒数第 N 个结点 c++

原题链接&#x1f517;&#xff1a;删除链表的倒数第 N 个结点 难度&#xff1a;中等⭐️⭐️ 题目 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a…

opencascade AIS_InteractiveContext源码学习相关枚举 AIS_SelectionScheme AIS_StatusOfPick

AIS_SelectionScheme 枚举 AIS_SelectionScheme 设置交互上下文中的选择方案。 枚举值&#xff1a; AIS_SelectionScheme_UNKNOWN 未定义的方案 AIS_SelectionScheme_Replace 清除当前选择并选择检测到的对象 AIS_SelectionScheme_Add 将检测到的对象添加到当前选择 AIS_…

Artalk-CORS,跨域拦截问题

今天重新部署Artalk之后&#xff0c;遇到了CORS——跨域拦截的问题&#xff0c;卡了好一会记录一下。 起因 重新部署之后&#xff0c;浏览器一直提示CORS&#xff0c;之前在其他项目也遇到过类似的问题&#xff0c;原因就在于跨域问题。

功能测试 之 单模块测试----添加会员

1.需求分析 点击【添加会员】按钮后&#xff0c;页面跳转至添加会员详细页面。 说明&#xff1a; 会员昵称&#xff1a;必填&#xff0c;长度在20个字符&#xff08;除去空格&#xff09;以内&#xff0c;&#xff08;会员昵称&#xff09;可以重复&#xff1b;登录密码&#x…