Android定制组件之图文展示之中国好声音

GPT-4o全模态交互实战指南:语音/视觉/实时协同工作流 多模态大模型正从‘文本为中心’转向‘感知即计算’的新范式,其核心是语音、图像与文本在统一神经空间中的联合表征与实时对齐。GPT-4o通过端到端音频编码、跨模态视觉理解与流式生成架构,实现了320毫秒级神经同步响应,突破传统ASR+LLM分段处理瓶颈。该技术显著提升会议纪要重构、手写批注识别、多语言商品图解析等场景的准确率与上下文连贯性,尤其适用于教育个性化诊断、工业缺陷检测、视障环境描述等强实时性与高语义耦合需求领域。本文聚焦GPT-4o新功能落地路径,提供零门槛激活、避坑设置与行业定制化工作流。 阅读详情

传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229

        今天我们学习如何自定义TextView组件,让它既能显示文本,又能显示图像,达到“图文并茂”的效果。这种图文混搭的方式常常被用来展现新闻、文章、彩信等内容。下面给出该情景的案例:

1案例技术要点

1.1创建attrs.xml文件用于设置自定义组件的属性、类型和样式。
1.2利用android.content.res.TypedArray类将自定义组件装载到程序,以供程序调用。

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.customTextView);

1.3布局文件引入自定义组件需要如下设置
自定义组件命名空间:

xmlns:custom="http://schemas.android.com/apk/res/com.custom.textview"

自定义组件标签:

<com.custom.textview.CustomTextView .../>

1.4构造一个HashMap数据结构,用于保存自定义组件的内容类型和值。

key:自定义组件的内容类型(image、text)

value:自定义组件的内容值(imageUrl,CharSequence)

1.5利用android.widget.LinearLayout.LayoutParams类用于设置组件的布局参数。这里需要根据显示内容的类型动态地设置组件的布局参数。

2案例代码陈列

2.1工程包目录


2.2AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.custom.textview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    
    <uses-permission android:name="android.permission.INTERNET"/>
    
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    
</manifest>

2.3strings.xml

<resources>
    <string name="app_name">自定义TextView实现图文并茂</string>
</resources>

2.4自定义TextView组件的属性类型样式文件:attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="customTextView">
        <attr name="image_width" format="dimension" />
        <attr name="image_height" format="dimension" />
        <attr name="text_color" format="color" />
        <attr name="text_size" format="dimension" />
    </declare-styleable>
</resources>

2.5main.xml

<?xml version="1.0" encoding="utf-8" ?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res/com.custom.textview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@android:color/white" >

    <com.custom.textview.CustomTextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        custom:image_width="200dp"
        custom:image_height="50dp" />

</LinearLayout>

2.6自定义组件类:CustomTextView.java

package com.custom.textview;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.text.Html;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class CustomTextView extends LinearLayout {
    private Context context;
    private TypedArray typedArray;
    private LayoutParams params;

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

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        this.setOrientation(LinearLayout.VERTICAL);
        // 从attrs.xml中获取自定义属性
        typedArray = context.obtainStyledAttributes(attrs, R.styleable.customTextView);
    }

    public void setText(ArrayList<HashMap<String, String>> data) {
        for (HashMap<String, String> hashMap : data) {
            String type = hashMap.get("type");
            String value = hashMap.get("value");
            // 如果内容类型是图片
            if (type.equals("image")) {
                // 设置图片显示宽高、集中
                int imageWidth = typedArray.getDimensionPixelOffset(R.styleable.customTextView_image_width, 100);
                int imageHeight = typedArray.getDimensionPixelOffset(R.styleable.customTextView_image_height, 100);
                ImageView imageView = new ImageView(context);
                params = new LayoutParams(imageWidth, imageHeight);
                params.gravity = Gravity.CENTER_HORIZONTAL;
                imageView.setLayoutParams(params);
                // 显示默认图片
                imageView.setImageResource(R.drawable.ic_launcher);
                // 将ImageView添加到CustomTextView中
                addView(imageView);
                // 开启工作线程异步加载图片
                new DownloadWork(value, imageView).start();
            } else if (type.equals("text")) {
                int textColor = typedArray.getColor(R.styleable.customTextView_text_color, 0xFF0000FF);
                float textSize = typedArray.getDimension(R.styleable.customTextView_text_size, 16);
                TextView textView = new TextView(context);
                textView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
                textView.setText(Html.fromHtml(value));
                textView.setTextColor(textColor);
                textView.setTextSize(textSize);
                addView(textView);
            }
        }
    }

    private class DownloadWork extends Thread {
        private String imageUrl;
        private ImageView imageView;

        public DownloadWork(String imageUrl, ImageView imageView) {
            this.imageUrl = imageUrl;
            this.imageView = imageView;
        }

        @Override
        public void run() {
            URL url = null;
            Drawable drawable = null;
             int newImageWidth = 0;
             int newImageHeight = 0;
            try {
                url = new URL(imageUrl);
                drawable = Drawable.createFromStream(url.openStream(), "image");
                // 对图片进行缩放
                newImageWidth = drawable.getIntrinsicWidth() / 3;
                newImageHeight = drawable.getIntrinsicHeight() / 3;
            } catch (Exception e) {
                e.printStackTrace();
            }
            SystemClock.sleep(2000);

            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("imageView", imageView);
            map.put("drawable", drawable);
            Message msg = handler.obtainMessage();
            msg.obj = map;
            msg.arg1 = newImageWidth;
            msg.arg2 = newImageHeight;
            handler.sendMessage(msg);
        }
    }

    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            @SuppressWarnings("unchecked")
            HashMap<String, Object> map = (HashMap<String, Object>) msg.obj;
            ImageView imageView = (ImageView) map.get("imageView");
            LayoutParams params = new LayoutParams(msg.arg1, msg.arg2);
            params.gravity = Gravity.CENTER_HORIZONTAL;
            imageView.setLayoutParams(params);
            Drawable drawable = (Drawable) map.get("drawable");
            imageView.setImageDrawable(drawable);
        }
    };
}

2.7MainActivity.java

package com.custom.textview;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
    
    private final String text = " <p>  今年浙江卫视凭《中国好声音》一举做大" +
            ",其巨大的影响力直接波及到了各家卫视“跨年晚会”的战略部署。日前" +
            ",“跨年晚会”概念的鼻祖湖南卫视率先表示“退出跨年烧钱大战”。" +
            "但据湖南卫视内部人士透露,即使如此,今年的湖南跨年晚会也将会掂出“跨年季”这个概念" +
            ",“也就是从12月27日到12月31日,连续五天,我们将相继用《百变大咖秀》、《快乐大本营》" +
            "、《女人如歌》、《天天向上》的特别节目来连续打造这个”季“的概念,直到12月31日的那场晚会。”</p>";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // 采集显示内容数据
        ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String,String>>();
        HashMap<String, String> part1 = new HashMap<String, String>();
        part1.put("type", "image");
        part1.put("value", "http://www.linuxidc.com/upload/2012_12/121218101020341.png");
        HashMap<String, String> part2 = new HashMap<String, String>();
        part2.put("type", "text");
        part2.put("value", text);
        HashMap<String, String> part3 = new HashMap<String, String>();
        part3.put("type", "image");
        part3.put("value", "http://www.linuxidc.com/upload/2012_12/121218101020341.png");
        data.add(part1);
        data.add(part2);
        data.add(part3);
        
        CustomTextView customTextView = (CustomTextView) findViewById(R.id.textView);
        customTextView.setText(data);
    }
}

3案例效果展示

 

2026主流手机AI横评:端侧大模型、NPU算力与系统整合深度解析 端侧人工智能(AI)与神经网络处理单元(NPU)是当前移动计算的核心技术。其原理在于通过专用硬件加速与轻量化模型算法,在设备本地高效处理AI任务,从而保障用户隐私、实现毫秒级响应与离线可用性。这项技术的核心价值在于将AI从云端依赖转变为设备的基础能力,推动智能手机从被动工具向主动智能体演进。其典型应用场景已深入影像处理、实时翻译、文档智能整理与个性化服务等日常高频领域。本文基于对三星、苹果、华为等十三家主流品牌旗舰机型的深度横评,聚焦端侧大模型的落地实效与NPU算力军备竞赛,剖析了不同技术路径下AI与系统整 阅读详情

相关推荐

Android TextView中显示图片的4种方式

我们知道,TextView控件一般是用来显示文本的,而图片一般是用ImageView控件来显示。那TextView能否显示图片呢?答案是肯定的!下面列出常见的4种方式。

blastxc 4万+

Android图文混排实现方式详解

在使用TextView的时候,我们经常需要在TextView中进行图文混排,比如在QQ中聊天的消息中的表情,底部tab图标等。 一、场景 二、实现方式 Android官方对TextView的图文混排提供了支持,我们可以从以下三种方式实现TextView的图文混排: 1.在TextView中使用Compound Drawable属性;2.在TextView中使用Spannable多样式显示;3...

weixin_33806300的博客 814

android多张图片展示

类似微信发朋友圈时的添加图片,,可以多选,方式包括从相册选择多张图片,拍照;添加后可删除

android图文混排的组件,Android 自定义控件进阶:图文混排

首先我们来看一下要达到的效果: 继续自定义View之旅,前面已经介绍过一个自定义View的基础的例子,Android 自定义控件起步:自定义TextView,如果你还对自定义View不了解可以去看看。今天给大家带来一个稍微复杂点的例子。自定义View显示一张图片,下面包含图片的文本介绍,类似相片介绍什么的,不过不重要,主要是学习自定义View的用法么。还记得上一篇讲的4个步骤么:1、自定义View...

weixin_39798031的博客 324

蓝桥杯FPGA赛道积分赛

代码如下: 按键驱动 代码如下 按键驱动 代码如下: 顶层文件 按键驱动 数码管驱动 声明:本代码借鉴网络资料,如有侵权和错误请联系作者删除。我是从寒假开始备赛的,由于我基础不行,备赛过程中也是混混呃呃的,备赛效率不高,总体来说备赛不认真,有点拖拉,但是最后我也坚持备赛到了今天,在备赛过程中,即复习了旧的东西,也学到了新的东西,总结起来还是有点收获的,后天北京、天津、河北地区就要进行省赛了,我会全力以赴,不管结果怎么样,尽力就好,最后祝大家都能

weixin_69804913的博客 1986

(超详细)Qt入门和配置Visual Studio的Qt环境

内容写了Qt入门,创建并编写第一个Qt程序,以及配置VS编写Qt程序的环境。(超级详细)

LY549826LY549264的博客 7678

Android textView展示html图片,实现图文混排,点击查看大图片

textView展示html,实现图文混排,点击查看大图片最近要展示html在textView上,实现图文混排,并且图片可以点击放大,所以去研究了一下,效果图如下: 我们知道textView的setText(Html.fromHtml(html))可以直接展示html的内容,但是如果html的标签包含imgd的话,直接用这个方法图片会展示不出来,然后我们看fromHtml的另一个构造方法的源码:p

gemgao的博客 9299

ACPWorkbench_for_BP10

ADC支持9种采样率:8000Hz、11025Hz、12000Hz、16000Hz、22050Hz、24000Hz、32000Hz、44100Hz 以及 48000Hz。选择5种MCLK源时, 模块内部的MCLK源无效。I2S 采样率支持:8K,11.025K,12K,16K, 22.05K, 24K, 32K, 44.1K, 48K, 88.2K, 96K, 176.4K 和 192K。DAC采样率支持:8K,11.025K,12K,16K,22.05K, 24K, 32K, 44.1K和48K。

dddds222_的博客 4554

Android解析后台给的Html格式的图文结合的数据,只需一个TextView就能展示。

本人也是菜鸟一枚,最近在写一个商城的项目,以前后台传过的数据是Json格式的,但是客户突然有了新的需求,要能传多张图片位置也不固定,所以后台就换成了Html格式的数据了。我知道Android自带了一个方法可以解析Html的数据, Html.fromHtml(“需要解析的内容”), 单纯的使用这个方法解析一段带有文字和图片的Html的数据,文字能够显示出来,但是图片就显示不出来。所以这就达不到我

qq_37693508的博客 2810

【IEEE】从Accept到Online:详解Proof校样阶段的关键操作与避坑指南

本文详细解析了IEEE论文从Accept到Online的Proof校样阶段关键操作流程与避坑指南。重点介绍了IEEE Author Gateway平台的使用技巧、校样稿首页的风险点检查,以及多人协作校对策略,帮助作者高效完成论文出版前的最后审核,确保学术成果准确呈现。

weixin_30591551的博客 357

VS Code 配置 LaTeX 写作环境完全指南

本文详细介绍了如何在 VS Code 中配置 LaTeX 写作环境,涵盖了从安装必备组件到高级功能的全面指南。首先,用户需要安装 LaTeX 发行版(如 TeX Live 或 MiKTeX)和 VS Code 插件(如 LaTeX Workshop)。接着,通过修改 settings.json 和 keybindings.json 文件,用户可以自定义编译、查看快捷键等基础配置。文章还提供了高效写作技巧,如使用代码片段和多文件项目管理,并介绍了高级功能如反向同步、公式预览和参考文献管理。此外,针对常见问题(

weixin_70043030的博客 1984

风筝制作基于HarmonyOS ArkTS API 24全栈解析,TAB_LIST 常量是一个包含六个 TabMeta 对象的数组,按照风筝制作的工艺流程顺序排列

健身管理类应用与之前分析的外卖、招聘等应用有本质差异——它的核心数据不是"交易"或"任务",而是"时间序列的身体状态数据":每次训练有时长、卡路里、组数、重量;每次饮食有热量、蛋白质、碳水、脂肪;每周有运动时长趋势图。这些数据的共同特征是"随时间积累,用户需要横向对比和趋势分析"。这导致健身App的数据层设计必须从第一天就考虑"历史数据查询"和"多维度聚合"的需求,而非仅关注当前单条记录的增删改查。健身应用的用户行为模式也有独特之处:用户使用健身App的目标是"坚持",而不是"一次性完成任务"。这意味着激励

jin421352的博客 181

CATIA CAA 二次开发去除面内开孔

测试模型: 代码说明:以下代码在拓扑级去除Face的内部loop,更改后的Body通过oispBody参数输出。主要使用CATSmartBodyDuplicator拓扑操作实现 HRESULT CAAStarterCmd::RemoveHoleOnFace(CATBody_var &ispBody,CATBody_var &oispBody){ CATLISTP(CATCell)olistFace; ispBody->GetAllCells(olistFace,2); CATF

weixin_45445751的博客 2265

全模态自研与生而全球:AI公司的技术基建与商业化飞轮

多模态大模型正从单一文本理解迈向文本、图像、语音、视频、音乐五大模态协同演进,其核心在于跨模态对齐与联合表征学习,而非功能堆砌。这种能力依赖统一隐空间建模、对比学习与跨模态重建等底层原理,显著降低服务链路延迟与错误率,提升推理效率与商业毛利率。技术价值体现在端到端交付(如代码生成+部署)、批量商用内容生产(如TikTok视频生成)及可信人机交互(如低延时多语种语音)等真实场景。MiniMax通过全模态自研、生而全球架构与AI原生组织,将模型能力深度耦合至产品、API与数据飞轮中,实现72.96%海外收入占比

weixin_34221773的博客 642

EDA虚拟机分享2020版本(Synopsys2020)

EDA虚拟机分享

亦安的数字小站 9189

DeFi核心协议代码解析

本文解析了DeFi两大核心协议Uniswap V2和Compound的智能合约架构与关键代码。Uniswap V2采用恒定乘积公式(x*y=k)实现自动做市,核心合约包括Factory、Pair和Router,具备流动性铸造、代币兑换和TWAP预言机功能。Compound借贷协议通过cToken合约管理存款和借款,采用动态利率模型和抵押率机制,包含资金利用率计算、清算触发等核心算法。两协议均采用模块化设计,通过智能合约实现去中心化金融服务的核心逻辑。

闲人编程的博客 934

CnOpenData 线上招聘网站信息数据

CnOpenData线上招聘网站信息数据库是一个覆盖中国主流招聘平台、时间跨度长、更新频率高的劳动力市场需求侧大数据集合。本数据库汇集了,为学术界和业界提供了一扇实时观察中国劳动力市场动态的窗口。

CnOpenData_wj的博客 2621

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

51c大模型~合集111

OpenAI 的某发言人表示:「为了提高清晰度和安全性,我们增加了一个额外的后处理步骤,其中模型会审查原始的思维链,删除任何不安全的内容,然后简化某些复杂的思维。可以看到,虽然 ChatGPT 确实完成了任务并展示了总结版的思维链,但似乎并未如 OpenAI 发言人说的那样给出与提示词语言同样语言的总结版。北大-灵初联合实验室表示,Align-DS-V的多模态强推理能力是VLA模型大脑端的核心,接下来的研究训练计划,是利用多模态推理模型的跨模态穿透能力,实现action穿透,最终实现真正高效的VLA模型。

whaosoft~aiotの开发板商城 2317

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

AI创作者的六道安全卡点:轻量级干预实战指南

AI生成内容已深度融入日常创作,但‘生成即完成’的惯性工作流正埋下输入失控、逻辑偏差、文化错位、责任模糊等系统性风险。其本质并非模型能力缺陷,而是创作者在prompt设计、数据使用、输出校验等关键环节缺乏可感知、可拦截、可验证的控制机制。本文聚焦AI创作者的核心责任边界,围绕输入指令层、数据喂养层、输出过滤层等六个可操作卡点,提供无需GPU、不依赖大模型API、单机即可部署的轻量级干预方案——包括Prompt三问法、三层过滤网、人工15秒确认点等,覆盖电商文案、医疗提醒、政务问答、教育生成等真实场景,助力普

windshg的专栏 423

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Android 纯原生 图文混排 心得

好久没有上号   今天写一下  纯原生图文混排心得     最近的项目里需要展示图文混排的格式,因为一些特殊原因需要纯原生操作。众所周知,图文混排我们可以使用Html.fromHtml(source, imageGetter, tagHandler)通过自定义imageGetter来异步加载图片 最终展示在TextView上,最后完成图文混排。但是这样做的话对于图片段落之间的距离相对来说不好把控展...

郭文亮的博客 9767

android 图片组件,常用组件:android的图片组件ImageView

android:id="@+id/iv_shadowImage_taiWei"android:layout_width="match_parent"android:layout_height="match_parent"android:alpha="0.5"android:background="#000000"android:src="@mipmap/logo"android:clickable...

weixin_42301816的博客 605

Android最完整的仿QQ表情聊天图文展示代码示例

android 最完整的表情聊天特效 首先我们需要知道Android 输入的是EditText 显示的内容我TextView, 但是TextView里面又只能显示字符串文字, 那怎么能够同时图文展示呢? 接下来带领你们展示是怎么实现的。 既然需要展示表情,所有表情的图片包还是需要大家去网上收集的在这里就不和大家详说了。当我们从网上下载图片后如下图这样放在assets文件夹里面,当前你也可以在里面在建一个自己喜欢的目录 然后我们需要全局首次加载这个图片,使用集合存储起来 public class Appli

qq_37210413的博客 3305

android图片展示图片,Android图片展示详解(一)

Android图片显示详解(一)说明:本讲义分为三部分,较为详细的介绍了Android平台下图片显示,加载等操作的处理原则与办法,以供大家共同学习,转载请注明出处 “From 移动微技”。前提与解释:安卓平台作为一款移动端的应用操作平台,其内存容量是十分有限的,内存资源是十分珍贵的,是无法与传统的桌面平台相比的,因此,在安卓平台下同样的图片操作与处理都要十分谨慎,否则你的程序可以迅速地消耗可用内存...

weixin_32224617的博客 1827
上一篇: Android应用开发之版本更新你莫愁
下一篇: 如何高效使用和管理Bitmap--图片缓存管理模块的设计与实现
innovation
博客等级 码龄14年 251粉丝 136原创
评论 13
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值