Xamarin.Android实现界面自动添加控件

news2024/12/26 12:09:21

目录

  • 1、背景说明
  • 2、效果
  • 3、代码
    • 3.1、UI代码
    • 3.2、实现代码
  • 4、代码下载
  • 5、相关知识点
    • 5.1、原理说明
    • 5.2、其他说明
  • 6、参考资料

1、背景说明

有时需要在APP中动态的添加控件,因此记录下在Xamarin中的实现步骤。
VS2022社区版

2、效果

在这里插入图片描述

3、代码

3.1、UI代码

UI的代码如何

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/activity_main">

  <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1">  <!--注意,这儿的权重是1-->

        <ScrollView
            android:id="@+id/scrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none">

            <LinearLayout
                android:id="@+id/linearlayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:isScrollContainer="false"
                android:padding="10dp">

                <!--下面这个布局主要是方便计算的-->
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:baselineAligned="true"
                    android:orientation="horizontal">

                </LinearLayout>

            </LinearLayout>
        </ScrollView>
    </LinearLayout>

  <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#34ab8b"
            android:layout_margin="10dip"
            android:text="添加"
            android:textSize="18dp"
            android:textColor="#fff"/>
        <Button
            android:id="@+id/btn_edit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#34ab8b"
            android:layout_margin="10dip"
            android:text="编辑"
            android:textSize="18dp"
            android:textColor="#fff"/>
    </LinearLayout>

</LinearLayout>

3.2、实现代码

活动中的代码如下:

using System;
using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Views;
using AndroidX.AppCompat.Widget;
using AndroidX.AppCompat.App;
using Google.Android.Material.FloatingActionButton;
using Google.Android.Material.Snackbar;
using Android.Widget;
using Java.Lang;
using System.Collections.Generic;
using System.Drawing;

namespace DynamicAddControls
{
    [Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {

        private LinearLayout linearLayout;
        //Button索引
        private List<Button> ListBtn_Show;
        //TextView索引
        private List<TextView> ListText_Def;
        private Button btn_add, btn_edit;
        //判断btn_edit的状态
        private int EDITSTATE = 0;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            SetContentView(Resource.Layout.activity_main);

            AndroidX.AppCompat.Widget.Toolbar toolbar = FindViewById<AndroidX.AppCompat.Widget.Toolbar>(Resource.Id.toolbar);
            SetSupportActionBar(toolbar);

            FloatingActionButton fab = FindViewById<FloatingActionButton>(Resource.Id.fab);
            fab.Click += FabOnClick;

            inited();
        }

        public override bool OnCreateOptionsMenu(IMenu menu)
        {
            MenuInflater.Inflate(Resource.Menu.menu_main, menu);
            return true;
        }

        public override bool OnOptionsItemSelected(IMenuItem item)
        {
            int id = item.ItemId;
            if (id == Resource.Id.action_settings)
            {
                return true;
            }

            return base.OnOptionsItemSelected(item);
        }

        private void FabOnClick(object sender, EventArgs eventArgs)
        {
            View view = (View) sender;
            Snackbar.Make(view, "Replace with your own action", Snackbar.LengthLong)
                .SetAction("Action", (View.IOnClickListener)null).Show();
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }



        private void inited()
        {
            linearLayout = (LinearLayout)FindViewById(Resource.Id.linearlayout);
            ListBtn_Show = new List<Button>();
            ListText_Def = new List<TextView>();
            btn_edit = (Button)FindViewById(Resource.Id.btn_edit);
            btn_add = (Button)FindViewById(Resource.Id.btn_add);
            btn_add.Click += Btn_add_Click;
            btn_edit.Click += Btn_edit_Click;


        }

        private void Btn_edit_Click(object sender, EventArgs e)
        {
            if (EDITSTATE == 0)
            {
                btn_edit.Text = "确定";
                EDITSTATE = 1;
            }
            else if (EDITSTATE == 1)
            {
                btn_edit.Text = "编辑";
                EDITSTATE = 0;
            }
        }

        private void Btn_add_Click(object sender, EventArgs e)
        {
            addBtn();//动态添加按钮
        }

        private void addBtn()
        {//动态添加按钮
         //添加承载两个按钮的LinearLayout
            LinearLayout linear_layout = new LinearLayout(this);
            linear_layout.Orientation= Orientation.Horizontal;//在同一个linearLayout中水平放置两个控件
            LinearLayout.LayoutParams liParam = new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.MatchParent,
                    ViewGroup.LayoutParams.WrapContent);
            linear_layout.LayoutParameters = liParam;

            //添加左侧的Button
            Button btnShow = new Button(this);
            LinearLayout.LayoutParams btnAddPar = new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.WrapContent, 
                108, 3);//设置宽高及占比
            btnAddPar.SetMargins(0, 10, 0, 10);
            btnShow.LayoutParameters=btnAddPar;
            //设置文本及颜色
            btnShow.Text=ListBtn_Show.Count + ""+ linear_layout.Id;
            btnShow.SetTextColor(Android.Graphics.Color.Argb(255, 255, 255, 255));
            btnShow.SetBackgroundColor(Android.Graphics.Color.Argb(255, 52, 171, 139));
            btnShow.Click += BtnShow_Click;//注册事件
            linear_layout.AddView(btnShow);//把btnShow添加到linear_btn中
            ListBtn_Show.Add(btnShow);//把btnShow添加到索引中
            

            //添加右侧的TextView
            TextView textDef = new TextView(this);
            //设置文本的格式
            LinearLayout.LayoutParams btnDefPar = new LinearLayout.LayoutParams
                    (ViewGroup.LayoutParams.WrapContent, 108, 1);//设置宽高及占比
            btnDefPar.SetMargins(0, 10, 0, 10);
            textDef.LayoutParameters=btnDefPar;

            textDef.Text="设为默认";
            textDef.Gravity=GravityFlags.Center;
            textDef.SetTextColor(Android.Graphics.Color.Argb(255, 255, 255, 255));
            textDef.SetBackgroundColor(Android.Graphics.Color.Argb(255, 52, 171, 139));
            textDef.Click += TextDef_Click;

  

            linear_layout.AddView(textDef);//把textDef添加到linear_btn中
            ListText_Def.Add(textDef);//把textDef添加到索引中
        
            linearLayout.AddView(linear_layout);//把linear_btn添加到外层linearLayout中
        }

        //设为默认的功能
        private void TextDef_Click(object sender, EventArgs e)
        {
            View view = sender as View;
            setDef(view);//设置默认
        }

        private void BtnShow_Click(object sender, EventArgs e)
        {
            View view = sender as View;

            if (EDITSTATE == 1) { }
                delBtn(view);//动态删除按钮
        }

        private void setDef(View view)
        {//设置默认
         //遍历索引里的所有TextView
            for (int i = 0; i < ListText_Def.Count; i++)
            {
                ListText_Def[i].SetBackgroundColor(Android.Graphics.Color.Argb(255, 52, 171, 139));
                ListText_Def[i].Text="设为默认";
                if (ListText_Def[i] == view)
                {
                    view.SetBackgroundColor(Android.Graphics.Color.Argb(255, 171, 52, 56));
                    ListText_Def[i].Text="默认";
                }
            }
        }
        private void delBtn(View view)
        {//动态删除按钮
            if (view == null)
            {
                return;
            }
            int position = -1;
            for (int i = 0; i < ListBtn_Show.Count; i++)
            {
                if (ListBtn_Show[i] == view)
                {
                    position = i;
                    break;
                }
            }
            if (position >= 0)
            {
                ListBtn_Show.RemoveAt(position);//从索引中移除被删除的Button
                ListText_Def.RemoveAt(position);//从索引中移除被删除的TextView
                linearLayout.RemoveViewAt(position + 1);//在外出linearLayout删除内部指定位置所有控件
            }
        }

    }
}

4、代码下载

正在审核中,待审核通过后,补充链接

5、相关知识点

5.1、原理说明

界面中添加控件,就是通过AddView方法实现的,方法有如下的重载版本:

public unsafe virtual void AddView(View? child)
public unsafe virtual void AddView(View? child, LayoutParams? @params)
public unsafe virtual void AddView(View? child, int index)
public unsafe virtual void AddView(View? child, int index, LayoutParams? @params)
public unsafe virtual void AddView(View? child, int width, int height)

参数child就是要添加的控件元素;LayoutParams代表待添加元素的样式。但也不一定非得添加这个参数,因为可以在控件的LayoutParameters属性中设置样式。index是索引,从0开始;widthheight设置控件的大小。具体可以参考上面的代码。

5.2、其他说明

还有一个方法是直接将样式文件加载成View,然后再通过addView直接实现

//获取视图,其中R.layout.CodeView是xml布局
View v1 =LayoutInflater.from(context).inflate(R.layout.CodeView,null,false);

//添加视图v1到容器v		
v.addView(v1);

6、参考资料

1、Android笔记——动态添加删除控件,及添加点击事件,本文主要参考这一篇,其介绍通过Android实现动态加载,本人主要是将其转为了C#版本
2、简析Android 动态添加控件的几种方式
3、关于 layout_weight,你到底知多少,这一篇主要讲述UI中布局的,讲得浅显易懂,推荐

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/745181.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文件块读写

写文件&#xff1a; size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 功能&#xff1a;以数据块的方式给文件写入内容 参数&#xff1a; &#xff1a;准备写入文件数据的地址ptr &#xff1a; 为 类型&#xff0c;此参数指定写入文件内容的块数据大…

面试官:说说Redis的持久化以及主从同步呗

目录 1、秃顶面试官&#xff1a;今天我们聊了聊redis的主从模式啊~ 2、秃顶面试官&#xff1a;Redis有哪几种方式进行数据的持久化&#xff1f; 3、秃顶面试官&#xff1a;RDB持久化是什么呢&#xff1f;触发机制又是什么呢&#xff1f; 4、秃顶面试官&#xff1a;嗯&#…

海外问卷调查怎么做?要准备什么?

科思创业汇 大家好&#xff0c;这里是科思创业汇&#xff0c;一个轻资产创业孵化平台。赚钱的方式有很多种&#xff0c;我希望在科思创业汇能够给你带来最快乐的那一种&#xff01; 海外问卷调查业务一直存在。与国内不同&#xff0c;国外有大量的支付问卷资源&#xff0c;所…

一招永久解决github上不去问题,秒开

步骤 进入如下路径&#xff0c;把hosts复制到桌面 在桌面将hosts以记事本方式打开&#xff0c;复制下面内容&#xff0c;退出保存 20.205.243.166 github.com # GitHub Start 140.82.114.4 github.com 199.232.69.194 github.global.ssl.fastly.net # GitHub End3. 将修改好…

S7-200 SMART PLC PID向导详细介绍(如何实现P、PD、PID控制器)

这篇博客主要介绍SMART PLC PID向导的使用,PID控制相关的其它内容请查看专栏系列文章,常用链接如下: SMART PLC PID负压控制(过程量为负数)_负压控制pid控制程序_RXXW_Dor的博客-CSDN博客1、如何实现PID反作用调节? 在有些控制中需要PID反作用调节。例如:在夏天控制空调…

doubletrouble1靶场详解

doubletrouble1靶场复盘 首先扫描到ip后对ip单独一个全面扫描。 nmap -sP 192.168.102.0/24同时扫描一下目录&#xff0c;扫到一个secret&#xff0c;打开看一下。 dirsearch -u http://192.168.102.165发现里面是一个图片&#xff0c;下载到我们kali 中去&#xff0c;因为都…

关于E-PGM+ 烧录器烧录失败的原因分析

最近在调试A96L416方案的一款产品&#xff0c;发现有时候无法烧录成功&#xff0c;当然多数时候你可以通过&#xff1a; 1.多试几次 2.替换烧录线 3. 替换烧录器 予以解决。 但我试了上述方法发现问题依旧&#xff0c;该设备A之前还烧录过&#xff0c;所以我并没有怀疑设…

C#基础学习_集合中对象的排序

C#基础学习_集合中对象的排序 基本数据类型的排序: 集合名.Sort(); //通过Sort方法进行排序,默认按照英文的字母先后顺序集合名.Reverse(); //通过Reverse方法进行排序,按照英文字母倒序进行排列对象类型的元素排序: 因为对象有若干个属性,所以执行排序时应该指定按照哪一…

海康摄像头开发笔记(一):连接防爆摄像头、配置摄像头网段、设置rtsp码流、播放rtsp流、获取rtsp流、调优rtsp流播放延迟以及录像存储

文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/131679108 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

c++方向服务器开发和数据库哪个更好?

选择C方向的服务器开发还是数据库开发&#xff0c;取决于你的兴趣、职业目标以及行业需求。以下是一些考虑因素&#xff1a; 我这里刚好有嵌入式、单片机、plc的资料需要可以私我或在评论区扣个6 服务器开发&#xff1a; 兴趣和技能&#xff1a;如果你对网络编程、分布式系统…

【万字解析】JS逆向由浅到深,3个案例由简到难,由练手到项目解析(代码都附详细注释)

目录 介绍简单案例简单案例二项目实战案例-某查查 介绍 大家好&#xff0c;我是辣条哥&#xff01; 今天给大家上点难度&#xff0c;不然总觉得辣条哥太菜了&#xff01;我们今天聊聊JS逆向&#xff0c;首先JS逆向是指对使用JavaScript编写的代码进行逆向工程&#xff0c;以获…

JAVA数据结构—飞机售票系统

飞机售票系统 1. 题目要求&#xff1a; 1.1 通过该系统可以实现如下功能。 录入功能&#xff1a;可以录入航班情况。 查询功能&#xff1a;可以查询某个航线的情况&#xff0c;如输入航班号&#xff0c;可以查询起降时间、起飞抵达城市、航班票价、票价折扣、确定航班是否满…

我爱学QT-QT上位机开发之串口助手-上

学习链接&#xff1a; QT上位机开发之串口助手&#xff08;上&#xff09;_哔哩哔哩_bilibili 一.QT下的串口编程 1.qt下的串口编程 2.qt下的网络编程 3.qt下操作GPIO 二.仿写串口助手 步骤一.做好UI界面 接收窗口组件&#xff1a; 选择窗口组件&#xff1a; 发送窗口组…

如何在Linux下搭建接口自动化测试平台

&#x1f4cc; 博客主页&#xff1a; 程序员念姐 &#x1f4cc; 专注于软件测试领域相关技术实践和思考&#xff0c;持续分享自动化软件测试开发干货知识&#xff01; &#x1f4cc; 如果你也想学习软件测试&#xff0c;文末卡片有我的交流群632880530&#xff0c;加入我们&…

【淘宝API接口开发系列】商品页面数据,接口可高并发,Python语言请求示例,其他语言请求示例可进参考

首先以taobao商品数据为例 item_get-获得taobao商品详情 taobao.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;注册Key和secret接入secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址…

【软件测试】Windows下同一电脑配置多个Git公钥(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 首先在配置多个本…

数据备份和还原的简单操作

两个表如图所示&#xff0c;完成一下操作 1、使用mysqldump命令备份数据库中的所有表 先创建存储数据的目录 使用mysqldump命令备份数据库中的所有表 去查看已经备份 2、备份booksDB数据库中的books表 备份数据库中的某些表&#xff0c;在库后面空格间隔 备份完毕 3、使用…

紫光展锐CEO任奇伟博士:用芯赋能,共建XR新生态

7月6日&#xff0c;2023世界人工智能大会在上海世博中心及世博展览馆盛大开幕。紫光集团高级副总裁、紫光展锐CEO任奇伟博士受邀出席芯片主题论坛&#xff0c;并发表题为《用芯赋能&#xff0c;共建XR新生态》的演讲。 世界人工智能大会自2018年创办以来已成功举办五届&#xf…

力扣332. 重新安排行程 Java dfs回溯

给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票都属于一个从 JFK&#xff08;肯尼迪国际机场&#xff09;出发的先生&#xff0c;所以该行程必须从 JFK 开始。如果存在多种…

AutoDL使用教程

AutoDl是一个租用GPU显卡的平台&#xff0c;我们可以在上面租用显卡。我训练模型的时候租用了一块V100。 下面介绍一下使用AutoDL 来租用GPU显卡&#xff0c;并将自己的代码上传&#xff0c;运行代码。 目录&#xff1a; 创建实例配置环境 pytorch环境上传文件运行代码 一、…