乱码三千 – 分享实用IT技术

乱码三千 – 码出一个新世界


  • 首页

  • 归档

  • 搜索

使用外部域名访问黑群晖的方法

发表于 2023-12-30

前言

使用外部域名访问群晖,大约有下面3种方法:

  1. 一种方法是使用DDNS服务,这个服务可以让你把一个域名绑定到你的动态IP地址上,这样你就可以通过域名来访问群晖。你需要在群晖的控制面板中开启外部访问功能,然后选择一个DDNS服务商,比如群晖自带的或者其他的,然后输入你的域名和账号信息。
  2. 另一种方法是使用内网穿透服务,这个服务可以让你在没有公网IP的情况下,通过一个中转服务器来访问群晖。你需要在群晖上安装一个内网穿透的应用,比如花生壳、QuickConnect等,然后注册一个账号和域名,然后在电脑或手机上安装相应的客户端,就可以通过域名来访问群晖。
  3. 还有一种方法是使用IPv4协议,这个协议可以让你的每个设备都有一个独立的公网地址,外网可以直接通过这个地址来访问群晖。你需要在群晖上安装Docker,并运行一个DDNS-GO的容器,然后在阿里云或其他服务商上注册一个域名,并设置好API密钥,然后在DDNS-GO的设置页面中输入你的域名和密钥,就可以通过域名来访问群晖。

今天咱们就用重点用第3种方法来实现。

第一步:登录注册阿里云

首先打开阿里云官网注册账号并完成实名认证。

完成之后在【账号中心】>【基本信息】中就可以看到“个人实名认证”的信息,就说明我们这个账号创建成功了,然后我们进行下一步操作。

第二步:注册域名

在搜索框输入自己想要的域名名字,任何名字都可以,最好想一个适合自己专属的名字,这里以“bihu”为例说明,输入好以后点击后面的“查询域名”按钮。

看见自己喜欢的直接点击后面的“加入清单”按钮(不要只看首购便宜,你得看续费的价格)。然后下单付款。

然后打开“域名服务—域名列表”,就能看到你刚刚购买的那个域名了。

阿里云域名控制台直达:http://dc.console.aliyun.com/

第三步:创建DDNS

在“域名列表”中,点击你刚才注册的域名后面的【解析】按钮。

需要添加一条主机记录为 nas,记录值为 0.0.0.0 的记录,其它保持默认即可,完成之后点击右下角的“确认”按钮。(主机记录,你可以写www或者nas都可以,我这里以nas为例)

继续点击页面右上角的图像点击“AccessKey管理”进入下一个页面。

点击创建AccessKey,然后就会出现AccessKey ID和AccessKey Secret两个数值,请一定妥善保管好这两个数值,等下需要用到的。(记不住也没有关系,任何时候都可以点击后面的查看Secret随时查看。)

第四步:群晖NAS里启用DDNS

接下来需要到群晖上操作了。需要说明的是,目前群晖自带的DDNS设置并没有阿里云的服务供应商。所以我们需要借助一个工具套件,叫做【DDNS-GO】(它同时也有Docker容器插件可以安装)。

PS:【DDNS-GO】顾名思义就是用来做DDNS的,支持国内的阿里云、腾讯云、华为云和百度云这四大域名商,以及支持国外大名鼎鼎的Cloudflare,同时支持IPv4和IPv6的解析,非常强大。

群晖套间里搜索【DDNS-GO】,然后安装(安装插件就不需要教程了吧)。

安装好【DDNS-GO】后,直接打开。如上图:

DNS服务商:这里很明显是选择“阿里云”

AccessKey ID:上面获取的阿里云AccessKey ID

AccessKey Secret:上面获取的阿里云AccessKey Secret

Domains:需要解析的域名,也就是上面你申请的那个阿里域名

设置好对应的参数后,点“Save”保存,稍等几秒就会看到右边的日志显示运行情况。出现更新域名解析成功,并出现你的公网IP,就说明我们【DDNS-GO】设置好了。

最后返回阿里云后台的解析设置那里,可以看到我们设置为0.0.0.0的记录值,已经自动变成我们的公网IP地址。至此我们的DDNS设置部分全部搞定!

第五步:路由器端口路转发

首先是在路由器拨号的情况下,打开路由器的upnp,然后直接找到路由器的端口转发开始创建即可。创建方法按上图设置就可以了,基本没有什么难度。

PS:端口映射不同的路由器叫法不一样,有的叫做“端口映射”,还有的叫做“虚拟服务器”。每个人使用的路由器品牌和网络环境不一样,设置也会有所不同,请根据实际情况进行设置,本文不再赘述。

第六步:验证登录

直接用浏览器登录你的域名,加上你路由器映射的端口号,能直接访问群晖NAS,就说明此次设置成功!

本文转载自:知乎

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

推荐几款好用的跨平台磁力or种子下载工具

发表于 2023-12-29

前言

老司机必备,且往下看

Motrix

支持各种协议并且免费开源跨平台的下载工具 不仅可以下载文件 还可以下载视频流

image-20231229114333177

支持平台: Windows、MacOs、Linux

官网: 点击进入

GitHub: 点击进入

Transmission

image-20231229114557365

该工具提速快, 基本上能秒杀市面上大部分BT下载器

支持平台: Windows、MacOs、Linux

官网: 点击进入

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

一款好用的网盘管理工具Alist

发表于 2023-12-23

前言

最近在折腾NAS,发现一款比较好用的跨平台网盘管理工具,名为Alist

image-20231223120448624

这款工具不仅支持群晖系统和docker容器, 还支持主流的桌面系统,如下图:

image-20231223120250775

它不仅可以管理多个网盘,还可以将其挂载到电脑本地使用, 可谓是网盘党的福音

支持的网盘厂商

支持市面上主流的网盘,包括但不限于百度网盘,阿里云盘,谷歌网盘等等

image-20231223121137429

使用说明

Alist功能很强大, 具体的使用说明详见官方文档:

Alist官方文档: 点击进入

Alist下载

GitHub: 点击进入

Alist官网: 点击进入

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

移动设备下,我都用什么app来管理我的NAS

发表于 2023-12-23

前言

大多数人使用nas都是在pc端,不管你是通过web界面也好,还是通过映射管理你nas上的文件也好,pc端永远都是nas的主要操作环境。而今天我介绍的便是我自己移动端下的一些app或者小程序等服务,通过这一系列服务,实现移动端操作nas某一部分特定的功能。

app

app

「ds file」

由群晖科技官方推出的一款文件远程管理手机软件,用户可以非常轻松的进行图片、视频、txt文件的浏览。也可以直接在移动设备端通过ds file直接上传下载文件或进行基本的编辑。

文件夹

但是!以上功能我一个都用不上,之所以手机会有ds file,全是为了同步相册罢了,moments移动端的同步功能太难用了,而且如果使用群晖的相册同步也就意味着你的照片在传到nas后会被打乱,它会通过生成一个一个文件夹来存放你的同步,这点我接受不了。而通过ds file同步,它只会同步你想要同步的文件夹,不会胡乱的打乱你的照片存放。

同步相册

「群晖助手」

由民间大神开发的一款开源的群晖管理应用。可以管理nas各个文件夹的内容,支持系统状况、存储、资源监控、目前连接用户、计划任务、最新日志、缓存状态,查看系统消息,查看套件信息。总之它的功能太多了,基本可以实现大部分nas的操作了,而且作者还一直在更新,只不过最近加了开屏广告,不过也能理解。

控制台

用过群晖助手后再对比一下群晖官方的软件,真的就一坨答辩O.o,而且明明很多功能是可以集成的,非要搞一堆app出来,真的逆天。我的建议是群晖直接花重金买软件版权,emmm不对,按照群晖的尿性,买了后估计是不会继续更新了,建议直接聘用作者。

更新公告

「EMBY」

emby我觉得不需要过多的介绍了。app端的emby体验上相对于网页端基本没有什么差别,web能操作的app上基本都是同样可以操作的,包括控制台这一类。

控制台

对于折腾好的东西我一向是不想折腾第二遍的,所以除了emby我也没使用过其他的媒体套件了,当然群晖自带的还是用过。在众多的媒体管理套件中,大家觉得拿一个好用呢?我可以去尝试一下。

媒体库

「moents」

moments支持自动扫描识别相似的照片,可以将像素较低的照片删除节省手机空间,可以按照关键字来查找和预览照片,还可以将手机里的照片备份到moments里面。当然同步功能我是用不上,毕竟我已经使用ds file同步了,所以moments的同步我一直都是关闭状态。

主题

我的mometns主要作用还是查看和下载照片,有时候和爱人或者朋友在一起,翻翻之前的照片聊聊以前的事情,这种氛围还蛮不错的。我几乎所有照片都存在nas,这导致我moments大概有接近3000找照片,手机上从来都是不存照片的。(谁知道moments的智能助手能关吗?)

「mix文件管理」

这并不是一个用于群晖的app,为什么要介绍它?因为它拥有webdav、smb以及众多网盘等功能,这让我可以直接使用手机通过webdav或者smb链接群晖。群晖官方的app太烂了,而群晖助手自带的一些播放器或者编辑器兼容性太差,而mix能够实现几乎所有文档的编辑与查看功能,同时还能作为手机自带文件管理器的替代品。

界面

「drive」

支持在手机上将各种文档文件进行安全备份处理,不仅可以备份音乐、视频、图片、文件等,还可以直接备份应用以及数据。作为群晖官方的同步工具,我实际使用几乎为0,下这个软件的原因是为了同步工作日程表,后面发现mix一样可以做到,就再也没用过了。

drive

以上便是我目前手机所有app类的群晖相关应用,当然除了以上这些还有很多适用于群晖的app,例如群晖ds cam摄像头监控软件、ds audio软件、ds finder远程唤醒app以及note station笔记软件等等。这些就不一一介绍了,使用方法都很简单,功能也很明了。

小程序

「随身PT」

顾名思义,一款能监控PT下器的小程序,可以添加多个服务器,也能通过链接或者本地上传添加种子,还能显示pt对应的标签。

种子界面

整体作为一个监控pt的工具还是不错,不过不能链接pt站点,也不能使用服务器预设的下载路径很不方便,如果想要下载,还需要手动去更改路径。

「PT管理宝」

统计信息

我一直在使用的工具,相对于上一款,它既能限时服务器统计信息,也能通过服务器预设分类直接按照分类路径下载,最重要的是它存在docker容器,在群晖端设置好docker容器后,便可以直接通过小程序链接各类“知名”PT站点,并且支持搜索和直接下载。

下载

由于“知名”PT站点的内容不好截图,我这里就不展示了。有兴趣的小伙伴可以自行研究或评论区讨论。

后述

以上便是我手机端的所有关于nas的应用以及小程序了,针对适应手机的web界面没什么可介绍的,所以在这里就不讲了。手机作为每天使用最多的工具,能够使用手机更好的操控nas,那么我一定会选择手机,毕竟有时候下班回到家压根不想打开电脑。

本文转载自:什么值得买

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

M3U8在线播放和下载工具

发表于 2023-09-13

在线播放

点击进入

在线下载提取

点击进入

image-20230924145356260

网页M3U8嗅探播放和下载

需要安装一个Chorme插件, 名叫猫抓:

image-20230924141300072

这个插件不仅可以嗅探视频链接, 还能直接播放和下载, 并且支持任意m3u8地址的解析, 很是强大:

image-20230924141940042

image-20230924142213584

image-20230924144328549

此插件已经开源:GitHub

其他相关工具

  • 🎞️m3u8下载工具:https://live.fanmingming.com/m3u8
  • 🆕TXT转M3U格式:https://live.fanmingming.com/txt2m3u
  • 📄在线M3U转TXT:Demo🔗 https://fanmingming.com/txt?url=https://live.fanmingming.com/tv/m3u/ipv6.m3u
  • 🌐M3U8 Web Player:Demo🔗 https://live.fanmingming.com/player/?vurl=https://0472.org/hls/cgtn.m3u8

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

如何对网页进行防调试配置

发表于 2023-09-12

前言

有时候我们需要对网页进行反爬虫和防浏览器调试抓包

只需在网页源代码尾部添加一段代码即可实现

具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!-- 禁开发者工具调试 --><script>
//如果用户在工具栏调起开发者工具,那么判断浏览器的可视高度和可视宽度是否有改变,如有改变则关闭本页面
// var debuggerH = window.innerHeight, debuggerW = window.innerWidth;
// window.onresize = function () {
// if (debuggerH != window.innerHeight || debuggerW != window.innerWidth) {
// window.close();
// window.location = "about:blank";
// }
// }

// 无限的 debugger 兼容性好
setInterval(function() {
debuggerCheck();
}, 2000);
var debuggerCheck = function() {
function doCheck(a) {
if (('' + a / a)['length'] !== 1 || a % 20 === 0) {
(function() {}['constructor']('debugger')());
} else {
(function() {}['constructor']('debugger')());
}
doCheck(++a);
}
try {
doCheck(0);
} catch (err) {}
};
debuggerCheck();
</script>

突破封锁

作为用户来说, 这种防调试手段的确很烦人, 有时候我们可能需要抓取网页当中的视频流, 比如抓取网页中的M3U8地址

此时我们可以通过安装浏览器插件的方式来解决, 以谷歌浏览器为例, 这里给大家介绍一款好用的网页媒体嗅探插件, 名叫猫爪:

image-20230924141300072

这个插件不仅可以嗅探视频链接, 还能直接播放和下载, 很是强大:

image-20230924141940042

image-20230924142213584

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

一款免费开源且跨平台的去中心化文件同步工具

发表于 2023-07-12

前言

今天无意之中发现一个很不错的文件同步工具, 它既不是类似于坚果云那种需要服务器中转的同步工具, 也不是类似于FreeFileSync那种电脑和U盘之间的同步工具, 它其实更像Windows系统中的网上邻居文件共享

但和网上邻居不同的是, 它支持非局域网的远程设备文件实时共享

特别适合多台电脑之间进行远程协作, 唯一缺点就是电脑必须开启才能共享, 在特定场景下还是非常好用的

该工具特点:

  • 跨平台: 支持Windows, Mac, Linux, BSD, Android,群晖
  • 免费开源
  • 私密安全: 去中心化的分享方式, 避免第三方服务器中转

软件安装后直接在浏览器即可看到当前共享状态:

image-20230717151201535

软件下载

官网: 点击进入

Github: 点击进入

使用步骤

  1. 在需要进行数据共享的设备上都安装syncthing工具

  2. 启动并运行该工具(Windows平台运行syncthing.exe文件)

  3. 浏览器地址栏输入http://localhost:8384打开控制面板

  4. 相互添加远程设备

    image-20230827145215469

  5. 相互添加需要共享的文件夹 并共享给对方的设备

    image-20230827143031588

    image-20230827142934567

    注: 这里需要注意的是,设备之间的文件夹ID需要填写相同的名称

  6. 修改最低空闲磁盘空间(可选)

    如果你的磁盘空间不是太充裕, 那么需要在页面右上角设置菜单中修改最低空闲磁盘空间, 否则无法共享, 这里我设置为0.1%

    image-20230827142416049

    同时 文件夹设置中也需要进行更改:

    image-20230827144501846

  7. 开始共享

    任意设备在共享文件夹中添加或者删除文件 其他设备都会同步更新

相关资料

官网: 点击进入

官方论坛: 点击进入

工具使用案例: 《Synchronizing REAPER Installs Across Computers》

本文为作者原创转载时请注明出处 谢谢

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

关于Android使用TextView加载Html实现图片居中显示

发表于 2023-05-12

前言

在 Android原生 TextView 中加载 HTML 图片时,默认情况下图片会按照其原来的大小显示,并且会与文字共存,而不会像网页中一样默认居中显示。如果需要在 TextView 中将图片居中显示, 可以使用以下几种方式

实现方案

第一种 使用自定义 ImageGetter

可以通过自定义ImageGetter 来实现图片居中显示。ImageGetter接口定义了获取 Drawable的方法,我们可以在这个方法中对图片进行处理,使其能够居中显示。以下是一个示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class CenteredImageSpan implements LineHeightSpan, Html.ImageGetter {

private Context mContext;
private Drawable mDrawable;

public CenteredImageSpan(Context context, Drawable drawable) {
mContext = context;
mDrawable = drawable;
}

@Override
public int getLeadingMargin(boolean first) {
return mDrawable.getIntrinsicWidth() / 2;
}

@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
canvas.save();

int transY = bottom - mDrawable.getBounds().bottom;

canvas.translate(x + getLeadingMargin(true), transY / 2);
mDrawable.draw(canvas);

canvas.restore();
}

@Override
public Drawable getDrawable(String source) {
if (mDrawable == null) {
// 获取图片
Bitmap bitmap = BitmapFactory.decodeFile(source);
mDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
}
return mDrawable;
}
}

该示例代码主要通过实现 ImageGetter 接口和 LineHeightSpan 接口来实现图片的居中显示。通过实现 Drawable的 getDrawable()方法,我们可以在这里获取图片,并在 draw()方法中实现图片的绘制。而由于图片的高度是不确定的,我们需要通过实现 LineHeightSpan 接口来控制行间距,以使得图片垂直居中。

使用上述代码,可以在 HTML 代码中添加以下标签,来调用自定义的 CenteredImageSpan 类:

1
<img src="file:///android_asset/1.jpg" width="200" align="middle">

第二种 使用 Html.TagHandler 和 CSS 样式

可以通过自定义Html.TagHandler 和 CSS 样式来实现图片居中显示。以下是一个示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class CenterImageTagHandler implements Html.TagHandler {

private final TextView mTextView;

public CenterImageTagHandler(TextView textView) {
mTextView = textView;
}

@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
if (tag.equalsIgnoreCase("img")) {
if (opening) {
// 处理图片标签
ImageSpanCenter span = new ImageSpanCenter(mTextView.getContext(), null);
output.setSpan(span, output.length(), output.length(), Spannable.SPAN_MARK_MARK);
} else {
// 处理结束标签
Object[] obj = output.getSpans(0, output.length(), Object.class);
if (obj != null && obj.length > 0) {
Object span = obj[obj.length - 1];
int start = output.getSpanStart(span);
int end = output.length();
output.removeSpan(span);
if (start != end) {
// 设置图片的对齐方式为居中
span = new ImageSpanCenter(mTextView.getContext(), ((ImageSpan) span).getDrawable());
output.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
}
}

private static class ImageSpanCenter extends ImageSpan {

ImageSpanCenter(Context context, Drawable drawable) {
super(drawable);
}

@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
Drawable drawable = getDrawable();

canvas.save();

// 获取 TextView 的宽度
float textWidth = paint.measureText(text, start, end);
Layout layout = ((TextView) ((Spanned) text).getSpans(0, ((Spanned) text).length(), Object.class)[0]).getLayout();
float viewWidth = layout.getWidth();

float transX = (viewWidth - textWidth) / 2 - drawable.getIntrinsicWidth() / 2;

canvas.translate(x + transX, (top + bottom) / 2 - drawable.getIntrinsicHeight() / 2);
drawable.draw(canvas);

canvas.restore();
}
}
}

该示例代码主要通过实现 Html.TagHandler接口和自定义 ImageSpan 类来实现图片的居中显示。通过实现 TagHandler 的 handleTag() 方法,我们可以在这里处理 img 标签,并在对应的位置插入一个ImageSpan 对象。而ImageSpan 可以通过重写 draw() 方法来实现图片的绘制。通过测量 TextView和文本的宽度,并使用 translate()方法来实现图片的水平居中和垂直居中。

使用上述代码,可以在 HTML 代码中添加以下标签和样式,来调用自定义的 CenterImageTagHandler 类:

1
<img src="file:///android_asset/1.jpg" width="200" style="display:block;margin:0 auto;">

第三种 给img标签包一层div然后添加居中样式

这种方式最为简单, 具体html代码如下:

1
<div style="text-align:center"><img src="图片地址" /></div>

以上几种方式都可以实现图片居中显示,只是实现方法不同,选择哪种方式主要是根据实际情况灵活选择。

本文内容来自 : ChatGPT

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Android使用TextView加载Html实现点击图片放大

发表于 2023-05-11

具体实现

在 Android的 TextView 中加载HTML标记时,我们可以使用 <img> 标记来显示图片,然后通过重写 onTouchEvent 方法来实现图片的放大效果。下面是一个示例代码,该代码在点击图片时会弹出一个对话框显示原图,用户可以选择是否放大图片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
public class MyTextView extends AppCompatTextView {
private static final int LONG_CLICK_TIME_THRESHOLD = 400;
private long mStartClickTime = 0;

public MyTextView(Context context) {
super(context);
}

public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
CharSequence text = getText();
if (text instanceof Spanned) {
Spanned spanned = (Spanned) text;
int action = event.getAction();

if (action == MotionEvent.ACTION_DOWN) {
mStartClickTime = System.currentTimeMillis();
} else if (action == MotionEvent.ACTION_UP) {
long clickDuration = System.currentTimeMillis() - mStartClickTime;

if (clickDuration < LONG_CLICK_TIME_THRESHOLD) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= getTotalPaddingLeft();
y -= getTotalPaddingTop();
x += getScrollX();
y += getScrollY();
Layout layout = getLayout();
int line = layout.getLineForVertical(y);
int offset = layout.getOffsetForHorizontal(line, x);

ClickableSpan[] link = spanned.getSpans(offset, offset, ClickableSpan.class);
ImageSpan[] images = spanned.getSpans(offset, offset, ImageSpan.class);

if (link.length != 0) {
link[0].onClick(this);
return true;
} else if (images.length != 0) {
Drawable drawable = images[0].getDrawable();
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) drawable).getBitmap();
} else if (drawable instanceof GifDrawable) {
bitmap = ((GifDrawable) drawable).getFirstFrame();
}
if (bitmap != null) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("图片预览");
View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_image_preview, null);
ImageView imageView = view.findViewById(R.id.image_view);
imageView.setImageBitmap(bitmap);
builder.setView(view);
builder.setPositiveButton("放大", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 进行图片放大操作
}
});
builder.setNegativeButton("关闭", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
return true;
}
}
}
}
}
return super.onTouchEvent(event);
}
}

// 使用方式
String html = "这是一张图片: <img src='file:///android_asset/sample.png'>";

MyTextView textView = findViewById(R.id.text_view);
textView.setText(Html.fromHtml(html, new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
Drawable drawable = null;
try {
InputStream inputStream = getAssets().open(source);
drawable = Drawable.createFromStream(inputStream, null);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
} catch (IOException e) {
e.printStackTrace();
}
return drawable;
}
}, null));
textView.setMovementMethod( LinkMovementMethod.getInstance());

在这个示例代码中,我们继承了 AppCompatTextView 并重写了 onTouchEvent 方法。在该方法中,我们使用类似于之前的方式获取点击位置,并查找到该位置对应的 ImageSpan 对象。然后我们根据该对象的 Drawable 对象生成一个 Bitmap 对象,并将其显示在一个自定义的对话框中。在对话框中,用户可以选择放大图片,也可以直接关闭对话框。

需要注意的是,当我们使用 <img> 标记来显示图片时,我们需要在第二个参数中传入一个 ImageGetter 对象,该对象用于将图片加载到 Drawable 中并返回。在本例中,我们通过从 Assets 中读取文件的方式来生成 Drawable 对象,并将其绑定到相应的 ImageSpan中。那么在触发点击事件时,我们只需要找到该位置的 ImageSpan 并获取其 Drawable 对象就能够得到原始的 Bitmap 对象了。

本文内容来自 : ChatGPT

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

Android使用TextView加载Html都支持哪些标签和样式

发表于 2023-05-10

支持的标签

Android 原生的 TextView 控件通过 Html.fromHtml() 方法可以加载 HTML 内容,并自动将其转换为Spannable 对象以支持富文本样式和链接等功能。在加载 HTML 内容时,TextView支持的 HTML 标签和样式主要有以下几种:

标题标签

TextView 可以解析 HTML 中的标题标签,包括 <h1>、<h2>、<h3>、<h4>、<h5>、<h6>,并自动转换为对应的样式。

例如:

1
myTextView.setText(Html.fromHtml("<h1>这是一级标题</h1><h2>这是二级标题</h2>"));

文本格式标签

TextView 支持的文本格式标签有 <b>(加粗)、<i>(斜体)、<u>(下划线)和 <strike>(删除线)等。在加载HTML 时,这些标签会自动被转换为相应的 Spannable 对象,并应用到对应的文字上。

例如:

1
myTextView.setText(Html.fromHtml("<b>这段文字加粗</b>,<i>这段文字斜体</i>,<u>这段文字加下划线</u>,<strike>这段文字带删除线</strike>"));

列表标签

TextView 支持的列表标签有无序列表 <ul> 和有序列表 <ol>,并会自动转换为相应的 Spannable 对象。

例如:

1
myTextView.setText(Html.fromHtml("<ul><li>这是无序列表的第一项</li><li>这是无序列表的第二项</li></ul><ol><li>这是有序列表的第一项</li><li>这是有序列表的第二项</li></ol>"));

链接标签

TextView 支持的链接标签有 <a>,在加载 HTML时会自动将其转换为 LinkSpan 对象,并允许用户点击跳转到对应的URL 地址。同时,在跳转时,也支持使用自定义的 Callback回调函数进行处理。

例如:

1
2
myTextView.setText(Html.fromHtml("请点击这个 <a href=\"http://www.baidu.com\">链接</a>"));
myTextView.setMovementMethod(LinkMovementMethod.getInstance());

除了默认的点击行为之外,我们还可以使用自定义的 URLSpan 和 ClickableSpan 类来处理连接的点击事件,例如弹出一个对话框或者打开一个新的 Activity 等。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MyLinkMovementMethod extends LinkMovementMethod {
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
int action = event.getAction();

if (action == MotionEvent.ACTION_UP) {
int x = (int) event.getX();
int y = (int) event.getY();

x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();

x += widget.getScrollX();
y += widget.getScrollY();

Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);

URLSpan[] urls = buffer.getSpans(off, off, URLSpan.class);
ClickableSpan[] cs = buffer.getSpans(off, off, ClickableSpan.class);

if (urls.length != 0) {
urls[0].onClick(widget);
return true;
} else if (cs.length != 0) {
cs[0].onClick(widget);
return true;
}
}
return super.onTouchEvent(widget, buffer, event);
}
}

上面的代码继承了 LinkMovementMethod 类,并重写了 onTouchEvent 方法,用于处理链接的点击事件。具体来说,当用户点击链接时,首先会判断该链接是否是一个 URLSpan 或者 ClickableSpan 对象,如果是,则调用其相应的 onClick() 方法实现自定义的行为。否则,将返回 false 继续使用默认的点击行为。

使用自定义的 MyLinkMovementMethod 可以通过以下方式设置给 TextView:

1
myTextView.setMovementMethod(new MyLinkMovementMethod());

这样,就可以在用户点击链接时实现自定义的行为了。需要注意的是,实现过程中需要根据具体的需求自己进行相应的代码编写,例如在 onClick() 方法中弹出对话框或启动新的Activity 等。

除此之外还可以使用自定义的 ClickableSpan 对象来实现不同链接的事件处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class MyClickableSpan extends ClickableSpan {
private String mHref;

public MyClickableSpan(String href) {
mHref = href;
}

@Override
public void onClick(View widget) {
Context context = widget.getContext();

if (mHref.startsWith("myapp://activity_a")) {
Intent intent = new Intent(context, ActivityA.class);
context.startActivity(intent);
} else if (mHref.startsWith("myapp://activity_b")) {
Intent intent = new Intent(context, ActivityB.class);
context.startActivity(intent);
}
}
}

// 使用方式
String html = "<a href=\"myapp://activity_a\">Activity A</a>" +
"<a href=\"myapp://activity_b\">Activity B</a>";

TextView textView = findViewById(R.id.text_view);
textView.setText(Html.fromHtml(html));
textView.setMovementMethod(LinkMovementMethod.getInstance());
SpannableString text = (SpannableString) textView.getText();
MyClickableSpan[] links = text.getSpans(0, text.length(), MyClickableSpan.class);
for (MyClickableSpan span : links) {
int start = text.getSpanStart(span);
int end = text.getSpanEnd(span);
text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}

图片标签

TextView 支持的图片标签有 <img>,在加载 HTML 时会自动将其转换为 ImageSpan 对象,并将图片显示在对应的位置上。

例如:

1
myTextView.setText(Html.fromHtml("<img src=\"https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png\"/>"));

上面所列举的标签和样式只是 TextView支持的一部分,实际上还有很多其它的标签和样式可以通过 Html.fromHtml() 方法解析并显示出来。但需要注意的是,由于安全性考虑,Android 在解析 HTML 内容时禁止加载 JavaScript、CSS 等内容,因此在使用时需要注意避免加载不安全的 HTML 内容。

支持的样式

在Android原生TextView 中,通过 Html.fromHtml() 方法加载 HTML标记时,是可以支持部分 CSS样式的。下面是一些常见的 CSS 样式以及它们在 Android原生 TextView 中的表现效果:

  1. 字体大小:font-size

    可以使用 font-size 属性来设置字体大小,例如:

    1
    <p style="font-size: 20px;">这是一个字体大小为 20px 的段落。</p>
  2. 颜色:color

    可以使用 color 属性来设置字体颜色,例如:

    1
    <p style="color: red;">这是一个红色的段落。</p>
  3. 字体粗细:font-weight

    可以使用 font-weight 属性来设置字体粗细,例如:

    1
    <p style="font-weight: bold;">这是一个粗体的段落。</p>
  4. 文本对齐:text-align

    可以使用 text-align 属性来设置文本对齐方式,例如:

    1
    <p style="text-align: center;">这是一个居中对齐的段落。</p>
  5. 背景颜色:background-color

    可以使用 background-color 属性来设置背景颜色,例如:

    1
    <p style="background-color: yellow;">这是一个黄色背景的段落。</p>
  6. 下划线:text-decoration

    可以使用 text-decoration 属性来设置下划线,例如:

    1
    <p style="text-decoration: underline;">这是一个带下划线的段落。</p>

需要注意的是,并不是所有的 CSS 样式都会被 Android 原生 TextView 支持。同时,在 HTML 标记中使用样式时,需要使用行内样式属性(如上面的示例代码所示),而不能使用外部样式表。如果需要添加进一步的样式,可以考虑使用 SpannableString 或自定义View来进行实现。

本文内容来自 : ChatGPT

乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站

1…678…51

乱码三千

android程序员一枚,擅长java,kotlin,python,金融投资,欢迎交流~

507 日志
145 标签
RSS
© 2026 乱码三千
本站总访问量次
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4
0%