安卓动态添加View
在安卓应用中,有很多时候需要动态添加View。比如从后台获取商品列表,根据商品数量在页面渲染对应数量的条目,这时候就需要动态添加View。
1.动态添加View的方法
动态添加View有两种方法:
- 由代码生成子View:这种方式很繁琐,布局效果也不直观,而且很多属性设置不了(也可能是我没找对方法);
- 从xml读取布局,然后动态设置信息:推荐该方式,配置xml时,可以直接看到效果,可设置的参数也更多。
接下来就用代码演示下如何使用这两种方式动态添加View。
注:子View也可以写在父View中,设置visible为GONE即可,在createItem最后添加一行item.setVisibility(View.VISIBLE);。
2. 代码实现
父View布局activity_list.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ScrollViewandroid:layout_width="match_parent"android:layout_height="480dp"android:layout_gravity="center_horizontal|top"android:layout_margin="10dp"><LinearLayoutandroid:id="@+id/list_items"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical" /></ScrollView><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"><Buttonandroid:id="@+id/list_switch_model"android:layout_width="100dp"android:layout_height="70dp"android:layout_gravity="center"android:layout_marginRight="20dp"android:text="Switch Model" /><Buttonandroid:id="@+id/list_add_item"android:layout_width="100dp"android:layout_height="70dp"android:layout_gravity="center"android:layout_marginLeft="20dp"android:text="Add Item" /></LinearLayout>
</LinearLayout>
子View布局activity_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:id="@+id/item"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:layout_marginBottom="5dp"android:orientation="horizontal"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:gravity="right|center"android:orientation="horizontal"><ImageViewandroid:id="@+id/item_img"android:layout_width="48dp"android:layout_height="48dp"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:padding="10dp"android:src="@drawable/common_item" /></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="match_parent"android:layout_gravity="center"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:gravity="left|center"android:orientation="vertical"><TextViewandroid:id="@+id/item_index"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="index: item name"android:textColor="@color/black"android:textSize="6pt" /><TextViewandroid:id="@+id/item_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="name: item name"android:textColor="@color/black"android:textSize="6pt" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_gravity="center_vertical"android:layout_marginRight="10dp"android:gravity="right|center"android:orientation="horizontal"><ImageViewandroid:id="@+id/item_edit"android:layout_width="48dp"android:layout_height="48dp"android:layout_marginRight="10dp"android:padding="10dp"android:src="@drawable/common_edit" /><ImageViewandroid:id="@+id/item_delete"android:layout_width="48dp"android:layout_height="48dp"android:layout_marginRight="10dp"android:padding="10dp"android:src="@drawable/common_delete" /></LinearLayout></LinearLayout>
</LinearLayout>
activity类:
package org.tao.hetools.activities;import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;import androidx.activity.ComponentActivity;
import androidx.annotation.Nullable;import org.tao.hetools.R;
import org.tao.hetools.entities.ItemInfo;import java.util.ArrayList;
import java.util.List;public class DynamicViewActivity extends ComponentActivity {private int index = 0;private boolean createViewFromXml = true;private List<ItemInfo> itemInfos = new ArrayList<>();private LinearLayout listItemsLayout;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_list);listItemsLayout = findViewById(R.id.list_items);initButton();initDynamicView();}private void initDynamicView() {if (listItemsLayout == null) {return;}listItemsLayout.removeAllViews();for (ItemInfo itemInfo : itemInfos) {listItemsLayout.addView(createViewFromXml ? createViewFromCode(itemInfo) : createViewFromCode(itemInfo));}}private void initButton() {findViewById(R.id.list_add_item).setOnClickListener(view -> {if (listItemsLayout == null) {return;}ItemInfo itemInfo = new ItemInfo(index, "name " + index, R.drawable.common_item);index++;itemInfos.add(itemInfo);listItemsLayout.addView(createViewFromXml ? createItem(itemInfo) : createViewFromCode(itemInfo));});findViewById(R.id.list_switch_model).setOnClickListener(view -> {itemInfos.clear();listItemsLayout.removeAllViews();createViewFromXml = !createViewFromXml;});}/*** 在代码中生成布局作为子view的布局** @param itemInfo item信息* @return item view*/private View createViewFromCode(ItemInfo itemInfo) {// item开头的图标layoutImageView itemImage = new ImageView(this);itemImage.setImageResource(R.drawable.common_item);itemImage.setMaxHeight(136);// 这个高度跟dp的换算,需要根据屏幕分辨率重新计算。下同itemImage.setMaxWidth(136);itemImage.setLeft(10);itemImage.setRight(10);itemImage.setPadding(5, 5, 5, 5);itemImage.setAdjustViewBounds(true);LinearLayout imageLayout = new LinearLayout(this);imageLayout.setOrientation(LinearLayout.HORIZONTAL);imageLayout.addView(itemImage);// item信息layoutTextView index = new TextView(this);index.setText("index: " + itemInfo.getIndex());index.setTextSize(10);TextView name = new TextView(this);name.setText("name: " + itemInfo.getName());name.setTextSize(10);LinearLayout infoLayout = new LinearLayout(this);infoLayout.setOrientation(LinearLayout.VERTICAL);infoLayout.addView(index);infoLayout.addView(name);// 操作layoutImageView edit = new ImageView(this);edit.setImageResource(R.drawable.common_edit);edit.setMaxHeight(136);edit.setMaxWidth(136);edit.setAdjustViewBounds(true);ImageView delete = new ImageView(this);delete.setImageResource(R.drawable.common_delete);delete.setMaxHeight(136);delete.setMaxWidth(136);delete.setAdjustViewBounds(true);LinearLayout operateLayout = new LinearLayout(this);operateLayout.setOrientation(LinearLayout.HORIZONTAL);operateLayout.addView(edit);operateLayout.addView(delete);// 子view的信息LinearLayout layout = new LinearLayout(this);layout.setOrientation(LinearLayout.HORIZONTAL);layout.addView(imageLayout);layout.addView(infoLayout);layout.addView(operateLayout);edit.setOnClickListener(view -> {// todo 此处处理edit的点击事件Log.i("itemInfoList: ", itemInfos.toString());});delete.setOnClickListener(view -> {itemInfos.remove(itemInfo);listItemsLayout.removeView(layout);});return layout;}/*** 从xml文件获取布局作为子view的布局** @param itemInfo item信息* @return item view*/private View createItem(ItemInfo itemInfo) {LinearLayout inflate = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.activity_item, null);LinearLayout item = inflate.findViewById(R.id.item);((ImageView) item.findViewById(R.id.item_img)).setImageResource(itemInfo.getImageResourceId());((TextView) item.findViewById(R.id.item_index)).setText("index: " + itemInfo.getIndex());((TextView) item.findViewById(R.id.item_name)).setText("name: " + itemInfo.getName());item.findViewById(R.id.item_edit).setOnClickListener(view -> {// todo 此处处理edit的点击事件Log.i("itemInfoList: ", itemInfos.toString());});item.findViewById(R.id.item_delete).setOnClickListener(view -> {itemInfos.remove(itemInfo);listItemsLayout.removeView(item);});((ViewGroup) item.getParent()).removeAllViews();return item;}
}
相关文章:
安卓动态添加View
在安卓应用中,有很多时候需要动态添加View。比如从后台获取商品列表,根据商品数量在页面渲染对应数量的条目,这时候就需要动态添加View。 1.动态添加View的方法 动态添加View有两种方法: 由代码生成子View:这种方式…...
前端预览pdf文件流
需求 后端接口返回pdf文件流,实现新窗口预览pdf。 解决方案 把后端返回的pdf文件流转为blob路径,利用浏览器直接预览。 具体实现步骤 1、引入axios import axios from axios;2、创建预览方法(具体使用时将axios的请求路径替换为你的后端…...
【测试工具JMeter篇】JMeter性能测试入门级教程(一)出炉,测试君请各位收藏了!!!
一、前言 Apache JMeter是纯Java的开源软件,最初由Apache软件基金会的Stefano Mazzocchi开发,旨在加载测试功能行为和测量性能。可以使用JMeter进行性能测试,即针对重负载、多用户和并发流量测试Web应用程序。 我们选择JMeter原因 是否测试过…...
【zookeeper03】消息队列与微服务之zookeeper集群部署
ZooKeeper 集群部署 1.ZooKeeper 集群介绍 ZooKeeper集群用于解决单点和单机性能及数据高可用等问题。 集群结构 Zookeeper集群基于Master/Slave的模型 处于主要地位负责处理写操作)的主机称为Leader节点,处于次要地位主要负责处理读操作的主机称为 follower 节点…...
从 Llama 1 到 3.1:Llama 模型架构演进详解
编者按: 面对 Llama 模型家族的持续更新,您是否想要了解它们之间的关键区别和实际性能表现?本文将探讨 Llama 系列模型的架构演变,梳理了 Llama 模型从 1.0 到 3.1 的完整演进历程,深入剖析了每个版本的技术创新&#…...
UE5肉鸽游戏教程学习
学习地址推荐:UE5肉鸽项目实战教程_哔哩哔哩_bilibili...
Vue3 - 详细实现虚拟列表前端虚拟滚动列表解决方案,vue3长列表优化之虚拟列表,解决列表动态高度不固定高度及图片视频图文异步请求加载问题,虚拟列表DOM大量数据同时加载渲染卡顿太慢及下滑列表闪烁
前言 Vue2 版本,请访问 这篇文章 在 vue3 项目开发中,详解实现虚拟列表高度不固定(不定高)且复杂含有图片视频等复杂虚拟列表教程,决列表每项高度不确定及img图像或视频的加载方案,利用缓冲区技术解决用户浏览时渲染不及时列表闪烁白屏/列表加载闪屏,解vue3实现虚拟列表优…...
英语知识网站开发:Spring Boot框架技巧
摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了英语知识应用网站的开发全过程。通过分析英语知识应用网站管理的不足,创建了一个计算机管理英语知识应用网站的方案。文章介绍了英语知识应用网站的系…...
基于lvgl+ST7735制作一款esp8285的控制面板程序
要在ESP8285上使用LVGL和ST7735创建一个控制面板程序,你需要遵循以下步骤。这个过程包括设置开发环境,连接硬件,编写代码,以及调校和优化。 所需硬件 ESP8285 开发板:像NodeMCU之类的开发板。ST7735 显示屏:通常是1.8英寸或2.0英寸的SPI接口显示屏。电源和连接线:用于连…...
MySQL 索引详解
在数据库的世界中,索引就像是一本巨大书籍的目录,它能够极大地提高数据检索的效率。在 MySQL 中,索引的合理使用对于数据库的性能至关重要。本文将深入探讨 MySQL 索引的各个方面。 一、索引的概念与作用 1. 什么是索引? 索引是一…...
区块链学习笔记(1)--区块、链和共识 区块链技术入门
常见的hash算法: 文件防篡改:MD5比特币挖矿:SHA256证明数据片段:Merkle root文本去重:SimHash 区块 区块(block)由区块头(block header)和交易列表(transac…...
【Android+多线程】IntentService 知识总结:应用场景 / 使用步骤 / 源码分析
定义 IntentService 是 Android中的一个封装类,继承自四大组件之一的Service 功能 处理异步请求 & 实现多线程 应用场景 线程任务 需 按顺序、在后台执行 最常见的场景:离线下载不符合多个数据同时请求的场景:所有的任务都在同一个T…...
Python Tornado框架教程:高性能Web框架的全面解析
Python Tornado框架教程:高性能Web框架的全面解析 引言 在现代Web开发中,选择合适的框架至关重要。Python的Tornado框架因其高性能和非阻塞I/O特性而备受青睐。它特别适合处理大量并发连接的应用,比如聊天应用、实时数据处理和WebSocket服务…...
通过端口测试验证网络安全策略
基于网络安全需求,项目中的主机间可能会有不同的网络安全策略,这当然是好的,但很多时候,在解决网络安全问题的时候,同时引入了新的问题,如k8s集群必须在主机间开放udp端口,否则集群不能正常的运…...
Excel把其中一张工作表导出成一个新的文件
excel导出一张工作表 一个Excel表里有多个工作表,怎么才能导出一个工作表,让其生成新的Excel文件呢? 第一步:首先打开Excel表格,然后选择要导出的工作表的名字,比如“Sheet1”,把鼠标放到“She…...
第四份工作的环境配置
最近在内网中工作,会遇到不少的环境问题. 下面记录一下这个过程中的挑战: 环境:内网,连接不到外网. 如何配置开发环境: 方法0: 在服务器上安装环境. 但是服务器上没有相应的python包.因为python包是从外界获得的.并且,这些python包不能同步更新.所以,在服务器上直接搭建环…...
SpringBoot开发——Maven多模块工程最佳实践及详细示例
文章目录 一、前言二、Maven多模块工程的最佳实践1、项目结构清晰2、依赖管理统一3、插件配置统一4、版本控制一致5、模块间通信简化 三、详细示例1、项目结构2、父模块(parent)的pom.xml文件3、子模块(module-api)的pom.xml文件4…...
C 语言面向对象
面向对象的基本特性:封装,继承,多态 1.0 面向过程概念 当我们在编写程序时,通常采用以下步骤: 1. 将问题的解法分解成若干步骤 2. 使用函数分别实现这些步骤 3. 依次调用这些函数 这种编程风格的被称作 面向过程…...
无人机探测:光电侦测核心技术算法详解!
核心技术 双光谱探测跟踪: 可见光成像技术:利用无人机表面反射的自然光或主动光源照射下的反射光,通过高灵敏度相机捕捉图像。该技术适用于日间晴朗天气下的无人机探测,具有直观、易于识别目标的特点。 红外成像技术࿱…...
ffmpeg视频滤镜:替换部分帧-freezeframes
滤镜描述 freezeframes 官网地址 > FFmpeg Filters Documentation 这个滤镜接收两个输入,然后会将第一个视频中的部分帧替换为第二个视频的某一帧。 滤镜使用 参数 freezeframes AVOptions:first <int64> ..FV....... set first fra…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
