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

安卓动态添加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

在安卓应用中&#xff0c;有很多时候需要动态添加View。比如从后台获取商品列表&#xff0c;根据商品数量在页面渲染对应数量的条目&#xff0c;这时候就需要动态添加View。 1.动态添加View的方法 动态添加View有两种方法&#xff1a; 由代码生成子View&#xff1a;这种方式…...

前端预览pdf文件流

需求 后端接口返回pdf文件流&#xff0c;实现新窗口预览pdf。 解决方案 把后端返回的pdf文件流转为blob路径&#xff0c;利用浏览器直接预览。 具体实现步骤 1、引入axios import axios from axios;2、创建预览方法&#xff08;具体使用时将axios的请求路径替换为你的后端…...

【测试工具JMeter篇】JMeter性能测试入门级教程(一)出炉,测试君请各位收藏了!!!

一、前言 Apache JMeter是纯Java的开源软件&#xff0c;最初由Apache软件基金会的Stefano Mazzocchi开发&#xff0c;旨在加载测试功能行为和测量性能。可以使用JMeter进行性能测试&#xff0c;即针对重负载、多用户和并发流量测试Web应用程序。 我们选择JMeter原因 是否测试过…...

【zookeeper03】消息队列与微服务之zookeeper集群部署

ZooKeeper 集群部署 1.ZooKeeper 集群介绍 ZooKeeper集群用于解决单点和单机性能及数据高可用等问题。 集群结构 Zookeeper集群基于Master/Slave的模型 处于主要地位负责处理写操作)的主机称为Leader节点&#xff0c;处于次要地位主要负责处理读操作的主机称为 follower 节点…...

从 Llama 1 到 3.1:Llama 模型架构演进详解

编者按&#xff1a; 面对 Llama 模型家族的持续更新&#xff0c;您是否想要了解它们之间的关键区别和实际性能表现&#xff1f;本文将探讨 Llama 系列模型的架构演变&#xff0c;梳理了 Llama 模型从 1.0 到 3.1 的完整演进历程&#xff0c;深入剖析了每个版本的技术创新&#…...

UE5肉鸽游戏教程学习

学习地址推荐&#xff1a;UE5肉鸽项目实战教程_哔哩哔哩_bilibili...

Vue3 - 详细实现虚拟列表前端虚拟滚动列表解决方案,vue3长列表优化之虚拟列表,解决列表动态高度不固定高度及图片视频图文异步请求加载问题,虚拟列表DOM大量数据同时加载渲染卡顿太慢及下滑列表闪烁

前言 Vue2 版本,请访问 这篇文章 在 vue3 项目开发中,详解实现虚拟列表高度不固定(不定高)且复杂含有图片视频等复杂虚拟列表教程,决列表每项高度不确定及img图像或视频的加载方案,利用缓冲区技术解决用户浏览时渲染不及时列表闪烁白屏/列表加载闪屏,解vue3实现虚拟列表优…...

英语知识网站开发:Spring Boot框架技巧

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了英语知识应用网站的开发全过程。通过分析英语知识应用网站管理的不足&#xff0c;创建了一个计算机管理英语知识应用网站的方案。文章介绍了英语知识应用网站的系…...

基于lvgl+ST7735制作一款esp8285的控制面板程序

要在ESP8285上使用LVGL和ST7735创建一个控制面板程序,你需要遵循以下步骤。这个过程包括设置开发环境,连接硬件,编写代码,以及调校和优化。 所需硬件 ESP8285 开发板:像NodeMCU之类的开发板。ST7735 显示屏:通常是1.8英寸或2.0英寸的SPI接口显示屏。电源和连接线:用于连…...

MySQL 索引详解

在数据库的世界中&#xff0c;索引就像是一本巨大书籍的目录&#xff0c;它能够极大地提高数据检索的效率。在 MySQL 中&#xff0c;索引的合理使用对于数据库的性能至关重要。本文将深入探讨 MySQL 索引的各个方面。 一、索引的概念与作用 1. 什么是索引&#xff1f; 索引是一…...

区块链学习笔记(1)--区块、链和共识 区块链技术入门

常见的hash算法&#xff1a; 文件防篡改&#xff1a;MD5比特币挖矿&#xff1a;SHA256证明数据片段&#xff1a;Merkle root文本去重&#xff1a;SimHash 区块 区块&#xff08;block&#xff09;由区块头&#xff08;block header&#xff09;和交易列表&#xff08;transac…...

【Android+多线程】IntentService 知识总结:应用场景 / 使用步骤 / 源码分析

定义 IntentService 是 Android中的一个封装类&#xff0c;继承自四大组件之一的Service 功能 处理异步请求 & 实现多线程 应用场景 线程任务 需 按顺序、在后台执行 最常见的场景&#xff1a;离线下载不符合多个数据同时请求的场景&#xff1a;所有的任务都在同一个T…...

Python Tornado框架教程:高性能Web框架的全面解析

Python Tornado框架教程&#xff1a;高性能Web框架的全面解析 引言 在现代Web开发中&#xff0c;选择合适的框架至关重要。Python的Tornado框架因其高性能和非阻塞I/O特性而备受青睐。它特别适合处理大量并发连接的应用&#xff0c;比如聊天应用、实时数据处理和WebSocket服务…...

通过端口测试验证网络安全策略

基于网络安全需求&#xff0c;项目中的主机间可能会有不同的网络安全策略&#xff0c;这当然是好的&#xff0c;但很多时候&#xff0c;在解决网络安全问题的时候&#xff0c;同时引入了新的问题&#xff0c;如k8s集群必须在主机间开放udp端口&#xff0c;否则集群不能正常的运…...

Excel把其中一张工作表导出成一个新的文件

excel导出一张工作表 一个Excel表里有多个工作表&#xff0c;怎么才能导出一个工作表&#xff0c;让其生成新的Excel文件呢&#xff1f; 第一步&#xff1a;首先打开Excel表格&#xff0c;然后选择要导出的工作表的名字&#xff0c;比如“Sheet1”&#xff0c;把鼠标放到“She…...

第四份工作的环境配置

最近在内网中工作,会遇到不少的环境问题. 下面记录一下这个过程中的挑战: 环境:内网,连接不到外网. 如何配置开发环境: 方法0: 在服务器上安装环境. 但是服务器上没有相应的python包.因为python包是从外界获得的.并且,这些python包不能同步更新.所以,在服务器上直接搭建环…...

SpringBoot开发——Maven多模块工程最佳实践及详细示例

文章目录 一、前言二、Maven多模块工程的最佳实践1、项目结构清晰2、依赖管理统一3、插件配置统一4、版本控制一致5、模块间通信简化 三、详细示例1、项目结构2、父模块&#xff08;parent&#xff09;的pom.xml文件3、子模块&#xff08;module-api&#xff09;的pom.xml文件4…...

C 语言面向对象

面向对象的基本特性&#xff1a;封装&#xff0c;继承&#xff0c;多态 1.0 面向过程概念 当我们在编写程序时&#xff0c;通常采用以下步骤&#xff1a; 1. 将问题的解法分解成若干步骤 2. 使用函数分别实现这些步骤 3. 依次调用这些函数 这种编程风格的被称作 面向过程…...

无人机探测:光电侦测核心技术算法详解!

核心技术 双光谱探测跟踪&#xff1a; 可见光成像技术&#xff1a;利用无人机表面反射的自然光或主动光源照射下的反射光&#xff0c;通过高灵敏度相机捕捉图像。该技术适用于日间晴朗天气下的无人机探测&#xff0c;具有直观、易于识别目标的特点。 红外成像技术&#xff1…...

ffmpeg视频滤镜:替换部分帧-freezeframes

滤镜描述 freezeframes 官网地址 > FFmpeg Filters Documentation 这个滤镜接收两个输入&#xff0c;然后会将第一个视频中的部分帧替换为第二个视频的某一帧。 滤镜使用 参数 freezeframes AVOptions:first <int64> ..FV....... set first fra…...

用Python玩转大疆Tello无人机:从键盘控制到手势飞行的保姆级实战教程

用Python玩转大疆Tello无人机&#xff1a;从键盘控制到手势飞行的保姆级实战教程 当第一次看到大疆Tello无人机在室内灵巧地完成翻滚动作时&#xff0c;我就被这个巴掌大的飞行器彻底征服了。作为一款专为编程教育设计的迷你无人机&#xff0c;Tello不仅具备稳定的飞行性能&…...

新手避坑指南:用Arduino Uno和双路L298N驱动麦克纳姆轮小车(附完整接线图)

新手避坑指南&#xff1a;用Arduino Uno和双路L298N驱动麦克纳姆轮小车&#xff08;附完整接线图&#xff09; 第一次接触硬件开发的软件工程师&#xff0c;往往会被看似简单的电路连接搞得焦头烂额。记得我第一次尝试用Arduino Uno和L298N驱动板搭建麦克纳姆轮小车时&#xf…...

YetiClaw Studio:本地部署AI游戏开发工作室实战指南

1. 项目概述&#xff1a;YetiClaw Studio&#xff0c;一个运行在本地硬件上的AI游戏开发工作室如果你是一个独立游戏开发者&#xff0c;或者是一个小型工作室的成员&#xff0c;那么你一定对游戏开发中那些繁琐、重复但又至关重要的环节深有体会&#xff1a;从最初那个模糊的创…...

从个人会用AI到企业真正变强:收藏这份AI升级指南

文章指出&#xff0c;虽然员工开始使用AI工具提升个人效率&#xff0c;但企业整体能力并未因此增强。企业AI升级的关键在于将AI融入流程、业务、协作和组织&#xff0c;而非仅仅停留在工具使用层面。文章强调AI应进入企业运行结构&#xff0c;从个人动作转变为企业能力&#xf…...

软件厂商突然要审计,你们公司 IT 资产管理能扛得住吗

某天下午&#xff0c;公司法务收到一封措辞正式的律师函。发函方是一家知名软件厂商&#xff0c;函件内容大意是&#xff1a;根据他们的监测数据&#xff0c;贵司存在超量使用其软件产品的情况&#xff0c;要求在三十天内配合完成软件资产审计&#xff0c;提供全公司范围内该软…...

Windows远程桌面终极解锁方案:RDP Wrapper完整使用指南

Windows远程桌面终极解锁方案&#xff1a;RDP Wrapper完整使用指南 【免费下载链接】rdpwrap RDP Wrapper Library 项目地址: https://gitcode.com/gh_mirrors/rd/rdpwrap 还在为Windows家庭版无法使用远程桌面而烦恼吗&#xff1f;RDP Wrapper Library这款开源工具能够…...

深入Logos FPGA的PCB布局:如何针对FBG256、FBG484和LPG封装优化你的设计

深入Logos FPGA的PCB布局&#xff1a;如何针对FBG256、FBG484和LPG封装优化你的设计 在硬件设计领域&#xff0c;FPGA的PCB布局一直是工程师面临的核心挑战之一。特别是当项目需要在性能、成本和尺寸之间寻找平衡点时&#xff0c;封装选择往往成为决定成败的关键因素。Logos系列…...

React Hook useVibe:声明式时序管理与交互感知的工程实践

1. 项目概述&#xff1a;一个能“感知”用户意图的React Hook 最近在做一个需要深度交互的前端项目&#xff0c;遇到了一个挺有意思的痛点&#xff1a;如何让UI组件不只是被动地响应事件&#xff0c;而是能更“聪明”地理解用户的交互意图&#xff0c;甚至预判下一步操作&#…...

在线考试系统如何实现随机组卷

在现代教育和企业培训中&#xff0c;考试是评估学习效果、提升培训效率的重要工具。然而&#xff0c;传统的固定试卷模式存在诸多问题&#xff1a;题目重复率高、考试公平性难以保障、人工管理成本高。随着在线培训的发展&#xff0c;尤其是在大规模培训场景下&#xff0c;随机…...

从NASA音频设计看极端约束下的工程权衡:可靠性如何塑造系统特性

1. 项目概述&#xff1a;从一次论坛讨论说起如果你和我一样&#xff0c;是个对技术细节有强迫症的老工程师&#xff0c;或者是个音频发烧友&#xff0c;那你肯定也曾在看NASA的航天直播或纪录片时&#xff0c;皱起眉头嘀咕过&#xff1a;“这声音怎么这么差&#xff1f;” 那种…...