目录
- 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"?>
<LinearLayoutxmlns: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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"> <!--注意,这儿的权重是1--><ScrollViewandroid:id="@+id/scrollView"android:layout_width="match_parent"android:layout_height="match_parent"android:scrollbars="none"><LinearLayoutandroid:id="@+id/linearlayout"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:isScrollContainer="false"android:padding="10dp"><!--下面这个布局主要是方便计算的--><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:baselineAligned="true"android:orientation="horizontal"></LinearLayout></LinearLayout></ScrollView></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid: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"/><Buttonandroid: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(){//动态添加按钮//添加承载两个按钮的LinearLayoutLinearLayout 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;//添加左侧的ButtonButton 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添加到索引中//添加右侧的TextViewTextView 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){//设置默认//遍历索引里的所有TextViewfor (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);//从索引中移除被删除的ButtonListText_Def.RemoveAt(position);//从索引中移除被删除的TextViewlinearLayout.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开始;width
和height
设置控件的大小。具体可以参考上面的代码。
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中布局的,讲得浅显易懂,推荐