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

秦皇岛网站制作公司优化设计全部答案

秦皇岛网站制作公司,优化设计全部答案,音乐网站开发书籍,义乌网站建设优化排名一、前言 很久没有更新Android 原生技术内容了,前些年一直在做跨端方向开发,最近换工作用重新回到原生技术,又回到了熟悉但有些生疏的环境,真是感慨万分。 近期也是因为准备做地图交互相关的需求,功能非常复杂&#x…

一、前言

很久没有更新Android 原生技术内容了,前些年一直在做跨端方向开发,最近换工作用重新回到原生技术,又回到了熟悉但有些生疏的环境,真是感慨万分。
近期也是因为准备做地图交互相关的需求,功能非常复杂,尤其是交互部分,不过再复杂的交互,只要一点点将它拆解,分而治之,问题还是可以解决,就比如接下来要做的放大镜功能。

二、功能设计

该功能的场景是在操作地图时,对于边缘的精细化操作(像素级别的)需要在放大镜里显示正在操作的地图区域。比如
在这里插入图片描述

如上图,我在操作地图里的内容时,可以在左上角看到我手指操作的内容。
这里需要支持如下几点:

  • 支持设置放大镜的放大倍数
  • 支持实时更新放大镜里的内容,手指操作地图时,放大镜要里的内容要一直显示(刷新),手指松开时,放大镜里的内容要清空。
  • 放大镜是个圆形。

三、功能实现

分下下来,放大镜的功能实现,拆解下来可以分成两部分来实现。

  • 绘制圆形容器。
  • 绘制手指操作的区域内容。
    接下来我们逐个实现

3.1 绘制圆形容器

关于绘制圆形容器,这里会涉及到Path 路径知识,因为正常的图形都是方形,因此需要图形裁切才行,这里会涉及到canvas.clipPath()API。
具体代码如下:

	private Paint paint;// 用于裁剪成圆形private Path clipPath;private void init() {paint = new Paint(Paint.ANTI_ALIAS_FLAG);clipPath = new Path();}@Overrideprotected void onDraw(@NonNull Canvas canvas) {super.onDraw(canvas);// 获取 MagnifierView 的宽高int viewWidth = getWidth();int viewHeight = getHeight();// 计算圆形半径float radius = Math.min(viewWidth, viewHeight) / 2f;clipPath.reset();// 绘制圆形路径clipPath.addCircle(viewHeight / 2f, (float) viewHeight /2,radius,Path.Direction.CW);// 裁切圆形画布canvas.clipPath(clipPath);}

3.2 绘制手指操作区域

放大镜本质就是放大图片,而图片在Android 里面就是Bitmap。这里有个问题。

3.2.1 如何获取当前手指操作View 的Bitmap呢?

答案是用getDrawingCache()。
具体实现如下:

setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(getDrawingCache());
setDrawingCacheEnabled(false);

当然,这里里的Bitmap是一整个View的,我们仅想放大手指操作(比如点击、滑动)区域的Bitmap,这就需要手指所在的坐标区域。
我们可以自定义一个View,然后重写它的onTouchEvent方法,通过event.getX(), event.getY()获取手指实时操作的坐标,然后传给放大镜View(比如我们这次自定义的放大镜MagnifierView)里面,连同前面的Bitmap一起传过去。这里可以搞一个回调接口。

	public interface MagnifierListener {// 传递放大镜内容void onMagnify(Bitmap bitmap, float x, float y);// 隐藏放大镜void onHideMagnifier();}

3.2.2 绘制操作区域

得到了要绘制的内容Bitmap,接下来就是绘制出来。
绘制Bitmap很简单,就是调用下面的API:

canvas.drawBitmap(bitmap, srcRect, dstRect, paint);

复杂的是计算放大内容的源区域,也就是srcRect。
这里先解释下dstRect,它是定义目标矩形(也就是放大镜自身大小)实现如下:

RectF dstRect = new RectF(0, 0, viewWidth, viewHeight);

接下来我们开始设置srcRect。写到这里我们好像漏了一个关键参数“放大倍数”。

// 放大倍数
private static final float SCALE_FACTOR = 2.0f;

因为我们要显示的区域和放大倍数有直接关联。srcRect 是一个Rect 对象,它里面有四个参数(左上右下),相当于当前显示区域范围,计算公式如下:

// 计算放大内容的源区域
float srcLeft = focusX - (viewWidth / SCALE_FACTOR) / 2;
float srcTop = focusY - (viewHeight / SCALE_FACTOR) / 2;
float srcRight = focusX + (viewWidth / SCALE_FACTOR) / 2;
float srcBottom = focusY + (viewHeight / SCALE_FACTOR) / 2;

先来解释下上面的公式意义,focusX对应的就是手指操作的x坐标,即event.getX(),focusY 同理则是event.getY()。
SCALE_FACTOR 是放大倍数。
因为我们想要显示的是“手指为中心,显示区域大小是当前放大镜的面积”,因此需要(viewWidth / SCALE_FACTOR) / 2,这里用focusX是确定左边界的位置。后面参数计算和前面差不多,这里我不重复解释。不过写到这里还不算完成。为了防止越界,这里还需要做一次矫正防护:

// 防止越界
srcLeft = Math.max(0, srcLeft);
srcTop = Math.max(0, srcTop);
srcRight = Math.min(bitmap.getWidth(), srcRight);
srcBottom = Math.min(bitmap.getHeight(), srcBottom);

最后的放大区域代码如下:

		// 计算放大内容的源区域float srcLeft = focusX - (viewWidth / SCALE_FACTOR) / 2;float srcTop = focusY - (viewHeight / SCALE_FACTOR) / 2;float srcRight = focusX + (viewWidth / SCALE_FACTOR) / 2;float srcBottom = focusY + (viewHeight / SCALE_FACTOR) / 2;// 防止越界srcLeft = Math.max(0, srcLeft);srcTop = Math.max(0, srcTop);srcRight = Math.min(bitmap.getWidth(), srcRight);srcBottom = Math.min(bitmap.getHeight(), srcBottom);// 定义源矩形(放大的内容区域)Rect srcRect = new Rect((int) srcLeft,(int) srcTop,(int) srcRight,(int) srcBottom);

3.3 小结

这里附上这个功能的完整代码:

/*** author      : coffer* date        : 2025/1/11* description : 放大镜视图*/
public class MagnifierView extends View {private float focusX = 0f; // 放大内容的中心点Xprivate float focusY = 0f; // 放大内容的中心点Y// 要放大的内容private Bitmap bitmap;private Paint paint;// 用于裁剪成圆形private Path clipPath;// 放大倍数private static final float SCALE_FACTOR = 2.0f;// 是否可以显示private boolean isVisible = false;public MagnifierView(Context context) {super(context);init();}public MagnifierView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init();}public MagnifierView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {paint = new Paint(Paint.ANTI_ALIAS_FLAG);clipPath = new Path();}/*** 设置放大镜的内容和位置*/public void setFocus(Bitmap bitmap, float x, float y) {this.bitmap = bitmap;this.focusX = x;this.focusY = y;this.isVisible = true;invalidate(); // 触发重绘}/*** 隐藏放大镜*/public void hide() {this.isVisible = false;invalidate();}@Overrideprotected void onDraw(@NonNull Canvas canvas) {super.onDraw(canvas);if (!isVisible || bitmap == null) {return;}// 获取 MagnifierView 的宽高int viewWidth = getWidth();int viewHeight = getHeight();// 计算圆形半径float radius = Math.min(viewWidth, viewHeight) / 2f;clipPath.reset();clipPath.addCircle(viewHeight / 2f, (float) viewHeight /2,radius,Path.Direction.CCW);canvas.clipPath(clipPath);// 计算放大内容的源区域float srcLeft = focusX - (viewWidth / SCALE_FACTOR) / 2;float srcTop = focusY - (viewHeight / SCALE_FACTOR) / 2;float srcRight = focusX + (viewWidth / SCALE_FACTOR) / 2;float srcBottom = focusY + (viewHeight / SCALE_FACTOR) / 2;// 防止越界srcLeft = Math.max(0, srcLeft);srcTop = Math.max(0, srcTop);srcRight = Math.min(bitmap.getWidth(), srcRight);srcBottom = Math.min(bitmap.getHeight(), srcBottom);// 定义源矩形(放大的内容区域)Rect srcRect = new Rect((int) srcLeft,(int) srcTop,(int) srcRight,(int) srcBottom);// 定义目标矩形(放大镜自身大小)RectF dstRect = new RectF(0, 0, viewWidth, viewHeight);// 绘制放大内容canvas.drawBitmap(bitmap, srcRect, dstRect, paint);}
}
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><stroke android:color="#abf4db"android:width="1dp"/></shape>

上面的这个drawable 可有可无,这里这是方便测试用。

四、总结

一开始接到这个需求的时候我是真的有些懵,因为以前从来没有写过。不过后来在仔细拆分问题后,觉的还是可以实现的。这里我要着重感谢ChatGPT,它给了我很大的帮助,就比如这个功能的实现,它就给了我思路,就像老师一样,能从它身上学到很多技能。
但是,请注意!不能完全依赖它,即使AI 帮你做了,你也必须要深入搞懂背后的原理,要把知识吸收到自己大脑思维中,否则未来你将会被AI取代!!!

http://www.hkea.cn/news/544845/

相关文章:

  • wordpress mysql类惠州网站seo
  • 为什么做网站必须要用域名举出最新的网络营销的案例
  • 电子请柬网站开发百度竞价推广登录入口
  • 网站设计与推广国际时事新闻2022最新
  • 柬埔寨网站开发营销技巧和营销方法
  • 网站建立价格长沙网站外包公司
  • 王建设医生个人网站免费google账号注册入口
  • 免费自建手机网站搜索引擎优化的方法包括
  • 甘肃省建设工程安全质量监督管理局网站官网拉新项目官方一手平台
  • 做电影网站赚钱武汉新闻最新消息
  • 做网站没有成本的方法上海百度分公司电话
  • 寺庙网站建设百度ai人工智能
  • 完成公司网站建设下载关键词推广软件
  • wordpress如何关闭网站下载app
  • WordPress小程序二次修改石家庄seo排名外包
  • 做百度关键词网站厦门seo外包
  • 泉州seo-泉州网站建设公司谷歌关键词搜索工具
  • 组织部网站建设方案行业关键词分类
  • 上海黄浦 网站制作中国搜索引擎排名2021
  • 手机网站建设 cms营销技巧和营销方法
  • 平顶山做网站优化微博搜索引擎优化
  • 网站如何做品牌宣传海报每日舆情信息报送
  • 做论坛网站需要多大空间seo推广招聘
  • 中国建设银行网站软件不限次数观看视频的app
  • 网站开发建设的步骤win11优化大师
  • 在线做数据图的网站樱桃bt磁力天堂
  • 网站建设费的税率东莞公司网上推广
  • 上海设计公司排名前十宁波seo搜索优化费用
  • 如皋做网站公司com域名
  • 织梦做企业网站教程网络营销推广方案论文