第63章 以泛型方式定义的递归方法构建树型结构数据的2种实现方法

这篇具有很好参考价值的文章主要介绍了第63章 以泛型方式定义的递归方法构建树型结构数据的2种实现方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.1 Core.Extensions.TreeExtension

namespace Core.Extensions

{

    /// <summary>

    /// 【树型结构扩展--类】

    /// <remarks>

    /// 摘要:

    ///    以泛型方式定义递归方法把具有父子关系的类中的所有实例,以树型结构进行存储。

    /// </remarks>

    /// </summary>

    public static class TreeExtension

    {

        ///<typeparam name="T">泛型类型实例(1个指定类的类型实例)</typeparam>

        ///<param name="all">列表实例,该实例存储着1个指定类的所有实例。</param>

        ///<param name="currentParentItem">将要添加所有子节点实例的父节点实例。</param>

        ///<param name="parentId">父节点实例所对应的长整型编号值,默认值:null</param>

        ///<param name="idProperty">1个指定类中指定编号属性成员的名称,默认值:"Id"</param>

        ///<param name="parentIdProperty">1个指定类中指定父编号属性成员的名称,默认值:"ParentId"</param>

        ///<param name="childrenProperty">1个指定类中指定子类型集属性成员的名称,默认值:"ChildrenCollection"</param>

        /// <summary>

        /// 【树型数据实例构建】

        /// <remarks>

        /// 摘要:

        ///     该方法通过泛型方式定义递归方法把具有父子关系的类中的所有实例,以树型结构进行存储。

        /// </remarks>

        /// </summary>

        public static void TreeBuilder<T>(List<T> all, T currentParentItem, long? parentId = null,

            string idProperty = "Id", string parentIdProperty = "ParentId", string childrenProperty = "ChildrenCollection")

        {

            List<T> _childrenList = new List<T>();

            if (parentId == null || parentId == 0)

            {

                _childrenList = all.Where(a => a.GetType().GetProperty(parentIdProperty)?.GetValue(a) == (object)parentId).ToList();

            }

            else

            {

                _childrenList = all.Where(a => a.GetType().GetProperty(parentIdProperty)?.GetValue(a)?.ToString() == parentId.ToString()).ToList();

            }

            if(_childrenList.Count > 0)

                currentParentItem.GetType().GetProperty(childrenProperty)?.SetValue(currentParentItem, _childrenList);

            foreach (var item in _childrenList)

            {

                long _parentId = Convert.ToInt64(item.GetType().GetProperty(idProperty)?.GetValue(item));

                TreeBuilder(all, item, _parentId);

            }

        }

    }

}

1.2 WebApi.Models. SelectListTreeModel

namespace WebApi.Models

{

    /// <summary>

    /// 【下拉框控件的树型结构扩展--类】

    /// <remarks>

    /// 摘要:

    ///    以泛型方式定义递归方法把具有父子关系的类中的所有实例,以树型结构进行存储,为下拉框控件以树型结构渲染显示提供数据支撑。

    /// </remarks>

    /// </summary>

    public record SelectListTreeModel

    {

        /// <summary>

        /// 【编号】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定节点实例的长整型编号值。

        /// </remarks>

        /// </summary>

        public long Id { get; set; }

        /// <summary>

        /// 【上级编号】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定节点实例的上级节点实例的长整型编号值(根级的父编号值为:null/0)

        /// </remarks>

        /// </summary>

        public long? ParentId { get; set; }

        /// <summary>

        /// 【名称】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定节点实例所对应的名称。

        /// </remarks>

        /// </summary>

        public string Text { get; set; }

        /// <summary>

        /// 【最后?】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个值false(不是最后节点,无下级节点)/true(是最后节点,有下级节点),该值指示个指定节点实例是否是最后节点,有下级节点。

        /// </remarks>

        /// </summary>

        public bool Last { get; set; }

        /// <summary>

        /// 【选中?】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个值false(未选中)/true(选中),该值指示个指定节点实例是否是下拉框控件中被选中的节点(用于多选下拉框控件?)

        /// </remarks>

        /// </summary>

        public string Checked { get; set; } = "0";

        /// <summary>

        /// 【子节点实例集】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定节点实例所对应的所有子节点实例。

        /// </remarks>

        /// </summary>

        public List<SelectListTreeModel> ChildrenCollection { get; set; }

    }

}

1.3 WebApi.Extensions. SelectListTreeExtension

using WebApi.Models;

namespace WebApi.Extensions

{

     /// <summary>

    /// 【下拉框控件树型结构模型--纪录】

    /// </summary>

    /// <remarks>

    /// 摘要:

    ///     通过该纪录的属性成员对下拉框控件以树型结构渲染显示提供数据支撑。

    /// </remarks>

    public static class SelectListTreeExtension

    {

        ///<typeparam name="T">泛型类型实例(1个指定类的类型实例)</typeparam>

        ///<param name="all">列表实例,该实例存储着1个指定类的所有实例。</param>

        ///<param name="parentId">父节点实例所对应的长整型编号值,默认值:null</param>

        ///<param name="idProperty">1个指定类中指定编号属性成员的名称,默认值:"Id"</param>

        ///<param name="parentIdProperty">1个指定类中指定父编号属性成员的名称,默认值:"ParentId"</param>

        ///<param name="nameProperty">1个指定类中指定名称属性成员的名称,默认值:"Name"</param>

        /// <summary>

        /// 【下拉框控件的树型结构】

        /// <remarks>

        /// 摘要:

        ///     该方法通过泛型方式定义递归方法把具有父子关系的类中的所有实例,以树型结构进行存储,为下拉框控件以树型结构渲染显示提供数据支撑。

        /// </remarks>

        /// </summary>

        public static List<SelectListTreeModel> SelectListTree<T>(List<T> all,  long? parentId = null,

            string idProperty = "Id", string parentIdProperty = "ParentId", string nameProperty = "Name")

        {

            List<SelectListTreeModel> _selectListTreeModel = new List<SelectListTreeModel>();

            List<T> _childrenList = new List<T>();

            if (parentId == null || parentId == 0)

            {

                _childrenList = all.Where(a => a.GetType().GetProperty(parentIdProperty)?.GetValue(a) == (object)parentId).ToList();

            }

            else

            {

                _childrenList = all.Where(a => a.GetType().GetProperty(parentIdProperty)?.GetValue(a)?.ToString() == parentId.ToString()).ToList();

            }

            foreach (var item in _childrenList)

            {

                var parentTree = new SelectListTreeModel();

                parentTree.Id = Convert.ToInt64(item.GetType().GetProperty(idProperty).GetValue(item));

                parentTree.ParentId = item.GetType().GetProperty(parentIdProperty)?.GetValue(item) == null ? 0 : Convert.ToInt64(item.GetType().GetProperty(parentIdProperty)?.GetValue(item));                      

                parentTree.Text = item.GetType().GetProperty(nameProperty).GetValue(item).ToString();

                parentTree.Last = parentId == null? !all.Exists(a => a.GetType().GetProperty(parentIdProperty)?.GetValue(a) == (object)parentId)

                    : !all.Exists(a => a.GetType().GetProperty(parentIdProperty)?.GetValue(a)?.ToString() == parentId.ToString());

                _selectListTreeModel.Add(parentTree);

                parentTree.ChildrenCollection = SelectListTree(all, parentTree.Id);

            }

            return _selectListTreeModel;

        }

    }

}

2 准备工作

2.1 Core.Domain. Category

namespace Core.Domain.Catalog

{

    /// <summary>

    /// 【产品类型--类】

    /// <remarks>

    /// 摘要:

    ///     通过该实体类及其属性成员,用于实现当前程序【Core.【领域】.【产品类型】.【产品类型】实体与“[ShopDemo].[Category]”表之间的CURD的交互操作,并把这些数据存储到数据库设置实例中(内存)

    /// </remarks>

    /// </summary>

    public class Category : BaseEntity

    {

        #region 属性

        /// <summary>

        /// 【上级产品类型编号】

        /// <remarks>

        /// 摘要:

        ///     获取/设置上级菜单实体1个指定实例上级产品类型的长整型编号值(根级的父编号值为:0)

        /// 注意:

        ///     要实现产品类型表本身的1:n级联必须把该属性定义为:可空(long?=null)

        /// </remarks>

        /// </summary>

        public long? ParentId { get; set; }

        /// <summary>

        /// 【名称】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定产品类型的名称。

        /// </remarks>

        /// </summary>

        public string Name { get; set; }

        /// <summary>

        /// 【菜单级别】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定产品类型的级别值(1`2)

        /// </remarks>

        /// </summary>

        public int Level { get; set; }

        /// <summary>

        /// 【激活?】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个值false(默认值:禁用)/true(激活),该值指示产品类型实体的1个指定实例是否处于已经激活状态。

        /// </remarks>

        /// </summary>

        public bool IsActive { get; set; }

        /// <summary>

        /// 【创建时间】

        /// <remarks>

        /// 摘要:

        ///     获取/设置产品类型实体1个指定实例第1次被持久化到产品类型表中的时间。

        /// </remarks>

        /// </summary>

        public DateTime CreatedDateTime { get; set; }

        /// <summary>

        /// 【创建时间】

        /// <remarks>

        /// 摘要:

        ///     获取/设置产品类型实体1个指定实例最后1次被修改后,持久化到产品类型表中的时间。

        /// </remarks>

        /// </summary>

        public DateTime UpdatedDateTime { get; set; }

        #endregion

        #region 属性--映射和级联构建

        /// <summary>

        /// 【子产品类型集】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定产品类型实例所对应的所有子产品类型实例。

        /// 说明:

        ///     构建同1产品类型表中父项与子项之间的1:n映射关系。

        /// </remarks>

        /// </summary>

        public virtual ICollection<Category> ChildrenCollection { get; set; }

        /// <summary>

        /// 【产品集】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定产品类型实例所对应的所有产品实例。

        /// 说明:

        ///     产品类型与产品实体及其表之间的1:n映射关系。

        /// </remarks>

        /// </summary>

        public virtual ICollection<Product> ProductCollection { get; set; }

        #endregion

    }

}

2.2 Data.Mapping.Catalog. CategoryBuilder

//Nuget

//Nuget--Microsoft.EntityFrameworkCore.SqlServer

using Microsoft.EntityFrameworkCore;

using Microsoft.EntityFrameworkCore.Metadata.Builders;

//项目

using Core.Domain.Catalog;

namespace Data.Mapping.Catalog

{

    /// <summary>

    /// 【产品类型生成器--类】

    /// <remarks>

    /// 摘要:

    ///     该类通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<TEntity/>泛型接口的“Configure”方法的定义,以实现把产品类型实体类及其属性成员相关约束规则及其级联关系定义,映射到产品类型表及其的相应字段上。

    /// </remarks>

    /// </summary>

    public class CategoryBuilder : IEntityTypeConfiguration<Category>

    {

        #region 方法--IEntityTypeConfiguration<>

        ///<param name="builder">实体类型生成器实例,用于把当前程序中指定实体和属性所定义的约束规则,映射到数据库指定表及其字段上。</param>

        /// <summary>

        /// 【配置】

        /// <remarks>

        /// 摘要:

        ///     该方法通过对“EntityFrameworkCore”中间件“IEntityTypeConfiguration<TEntity/>泛型接口的“Configure”方法的定义,以实现把产品类型实体类及其属性成员相关约束规则及其级联关系定义,映射到产品类型表及其的相应字段上。

        /// </remarks>

        /// </summary>

        public void Configure(EntityTypeBuilder<Category> builder)

        {

            //由于“EntityTypeBuilder<Category>”的参数已经泛型实例化,因此builder后不能再定义为:“builder.Entity<Category>().HasKey(category => category.Id);”

            //用户表及其字段约束规则,映射定义。

            builder.HasKey(category => category.Id);

            //说明:

            //     1“Microsoft SQL Server”数据库软件对同1个表之中的关联删除操作是不支持的,所以在同1个表的关联约束规则定义中,

            //不能使用“.OnDelete(DeleteBehavior.ClientCascade)”在同1个表中构建关联删除关系,否则在通过Code-First模式生成数据库及其表时会出现逻辑异常。

            //     2“Microsoft SQL Server”数据库软件对两个不同表之间的关联删除操作是支持的,所以在两个不同表之间的关联约束规则定义中,

            //可以能使用“.OnDelete(DeleteBehavior.ClientCascade)”在两个不同表之间构建关联删除关系。

            //     3、默认的关联约束规则枚举实例为:DeleteBehavior.ClientSetNull,实则ClientCascadeRestrict也可以通过Code-First模式生成数据库及其表。

            builder.HasMany(category => category.ChildrenCollection)

                .WithOne()

                .HasForeignKey(category => category.ParentId);

            builder.Property(category => category.Name).IsRequired().HasMaxLength(255);

            builder.Property(category => category.CreatedDateTime).IsRequired();

            builder.Property(category => category.UpdatedDateTime).IsRequired();

        }

        #endregion

    }

}

2.3 Services.Catalog. ICategoryService

using Core.Domain.Catalog;

namespace Services.Catalog

{

    /// <summary>

    /// 【产品类型服务--接口】

    /// <remarks>

    /// 摘要:

    ///    通过继承于该接口具体实现类中的方法成员实现当前程序与产品类型表之间的CURD操作。

    /// </remarks>

    /// </summary>

    public interface ICategoryService

    {

        /// <summary>

        /// 【异步获取所有产品类型】

        /// <remarks>

        /// 摘要:

        ///     获取产品类型的所有所有实例。

        /// </remarks>

        /// <returns>

        /// 返回:

        ///    产品类型的所有所有实例。

        /// </returns>

        /// </summary>

        Task<IList<Category>> GetAllCatalogAsync();

        /// <summary>

        /// 【异步获取所有产品类型】

        /// <remarks>

        /// 摘要:

        ///     以树型结构获取产品类型的所有所有实例。

        /// </remarks>

        /// <returns>

        /// 返回:

        ///    产品类型的树型结构的所有所有实例。

        /// </returns>

        /// </summary>

        Task<IList<Category>> GetAllCatalogTreeAsync();

    }

}

2.4 Services.Catalog. CategoryService

using Core.Caching;

using Core.Domain.Catalog;

using Data;

using Core.Extensions;

using Data.Extensions;

namespace Services.Catalog

{

    /// <summary>

    /// 【产品类型服务--类】

    /// <remarks>

    /// 摘要:

    ///    通过类中的方法成员实现当前程序与产品类型表之间的CURD操作。

    /// </remarks>

    /// </summary>

    public class CategoryService : ICategoryService

    {

        #region 拷贝构造方法与变量

        private readonly IRepository<Category> _categoryRepository;

        private readonly IStaticCacheManager _staticCacheManager;

        /// <summary>

        /// 【拷贝构建方法】

        /// <remarks>

        /// 摘要:

        ///     依赖注入容器通过拷贝构造方法,实例化该类中的变量成员。

        /// </remarks>

        /// </summary>

        public CategoryService(

            IRepository<Category> categoryRepository,

            IStaticCacheManager staticCacheManager)

        {

            _categoryRepository = categoryRepository;

            _staticCacheManager = staticCacheManager;

        }

        #endregion

        #region 方法--接口实现

        /// <summary>

        /// 【异步获取所有产品类型】

        /// <remarks>

        /// 摘要:

        ///     获取产品类型的所有所有实例。

        /// </remarks>

        /// <returns>

        /// 返回:

        ///    产品类型的所有所有实例。

        /// </returns>

        /// </summary>

        public async Task<IList<Category>> GetAllCatalogAsync()

        {

            return await _categoryRepository.GetEntitiesAsync(async () =>

            {

                return await _categoryRepository.Table.ToListAsync();

            },

                cache => _staticCacheManager.PrepareKeyForDefaultCache(EntityCacheDefaults<Category>.AllCacheKey));

        }

        /// <summary>

        /// 【异步获取所有产品类型】

        /// <remarks>

        /// 摘要:

        ///     以树型结构获取产品类型的所有所有实例。

        /// </remarks>

        /// <returns>

        /// 返回:

        ///    产品类型的树型结构的所有所有实例。

        /// </returns>

        /// </summary>

        public async Task<IList<Category>> GetAllCatalogTreeAsync()

        {

            IList<Category> _categoryAll = await GetAllCatalogAsync();

            IList<Category> _rootList = _categoryAll.Where(c => c.ParentId.Equals(null)).ToList();

            List<Category> _categoryAllTree = new List<Category>();

            foreach (var root in _rootList)

            {

                //通过递归方法,以树型结构构建1个根实例的所有子实例。

                TreeExtension.TreeBuilder(_categoryAll.ToList(), root, root.Id);

                _categoryAllTree.Add(root);

            }

            return _categoryAllTree;

        }

        #endregion

    }

}

3 WebApi.Controllers. CategoryController

using Core.Domain.Catalog;

using Framework.Filters;

using Microsoft.AspNetCore.Mvc;

using Services.Catalog;

using WebApi.Extensions;

using WebApi.Models;

namespace WebApi.Controllers

{

    [Route("[controller]/[action]")]

    [ApiController]

    //[Authorize(PermissionsPolicy.Name)]

    [SaveLastActivity]

    public class CategoryController : ControllerBase

    {

        #region 拷贝构造方法与变量

        private readonly ICategoryService _categoryService;

        /// <summary>

        /// 【拷贝构建方法】

        /// <remarks>

        /// 摘要:

        ///     依赖注入容器通过拷贝构造方法,实例化该类中的变量成员。

        /// </remarks>

        /// </summary>

        public CategoryController(

           ICategoryService categoryService)

        {

            _categoryService = categoryService;

        }

        #endregion

        /// <summary>

        /// 【产品类型表格--需权限】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///    产品类型的所有实例,为产品类型表格的渲染显示提供数据支撑。

        /// </remarks>

        /// <returns>

        /// 返回:

        ///     消息模型纪录的1个指定实例,该实例存储当前“Api”方法的执行操作结果,为客户端页面的渲染提供数据支撑。

        /// </returns>

        [HttpGet]

        public async Task<MessageModel<IList<Category>>> Index()

        {

            IList<Category> _categoryAllList = await _categoryService.GetAllCatalogTreeAsync();

            return MessageModel<IList<Category>>.GetSuccess("成功获取产品类型的所有实例!", _categoryAllList);

        }

        /// <summary>

        /// 【产品类型下拉框控件的树型结构--需权限】

        /// </summary>

        /// <remarks>

        /// 摘要:

        ///   以树型结构进行存储产品类型的所有实例,为下拉框控件以树型结构渲染显示提供数据支撑。。

        /// </remarks>

        /// <returns>

        /// 返回:

        ///     以树型结构进行存储产品类型的所有实例。

        /// </returns>

        [HttpGet]

        public async Task<MessageModel<List<SelectListTreeModel>>> GetSelectListTree()

        {

            List<SelectListTreeModel> _categorySelectListTreeModel = new List<SelectListTreeModel>();

            _categorySelectListTreeModel.Add(new SelectListTreeModel()

            {

                Id = 0,

                ParentId = 0,

                Text = "无父级",

                Last = true,

            });

            IList<Category> _categoryAllList = await _categoryService.GetAllCatalogAsync();

            _categorySelectListTreeModel.AddRange(SelectListTreeExtension.SelectListTree(_categoryAllList.ToList()));

            return MessageModel<List<SelectListTreeModel>>.GetSuccess("成功获取", _categorySelectListTreeModel);

        }

    }

}

对以上功能更为具体实现和注释见:230426_048shopDemo(以泛型方式定义的递归方法构建树型结构数据的2种实现方法)。文章来源地址https://www.toymoban.com/news/detail-426453.html

到了这里,关于第63章 以泛型方式定义的递归方法构建树型结构数据的2种实现方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 详谈SpringBoot启动项目后执行自定义方法的方式

    这个是在所有启动后执行,也是常用之一。 项目初始化完毕后才会调用方法,提供服务。好处是方法执行时,项目已经初始化完毕,是可以正常提供服务的。 实现 ApplicationRunner 接口和实现 CommandLineRunner 接口基本是一样的。不同的是启动时传参的格式,CommandLineRunner 对于参数

    2024年02月10日
    浏览(41)
  • Qt/C++音视频开发63-设置视频旋转角度/支持0-90-180-270度旋转/自定义旋转角度

    设置旋转角度,相对来说是一个比较小众的需求,如果视频本身带了旋转角度,则解码播放的时候本身就会旋转到对应的角度显示,比如手机上拍摄的视频一般是旋转了90度的,如果该视频文件放到电脑上打开,一些早期的播放器可能播放的时候是躺着的,因为早期播放器设

    2024年02月02日
    浏览(55)
  • TypeScript 关于对【泛型】的定义使用解读

    泛型 (Generics)是指在 定义函数、接口或类 的时候, 不预先指定具体的类型 ,而在 使用的时候再指定类型 的一种特性 。使用泛型 可以 复用类型并且让类型更加灵活 泛型实现类型参数化: 在定义这个函数时, 我不决定这些参数的类型 而是让调用者以参数的形式告知,我

    2024年02月13日
    浏览(36)
  • Java 数据结构篇-二叉树的深度优先遍历(实现:递归方式、非递归方式)

    🔥博客主页: 【 小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍    文章目录         1.0 二叉树的说明         1.1 二叉树的实现         2.0 二叉树的优先遍历说明         3.0 用递归方式实现二叉树遍历         3.1 用递归方式实现遍历 - 前序遍历         3.2 用递归

    2024年02月05日
    浏览(53)
  • 泛型类、泛型接口、泛型方法详解!

    Java泛型中的那些字母是什么意思?(E、T、K、V、S) 当定义类、接口或方法时,可以使用类型参数(Type Parameters)来表示未知的类型,从而使代码更加通用和灵活。下面分别给出类、接口和方法的例子: 在这个例子中, Box 类使用类型参数 T 来表示未知的类型,可以在创建对象

    2023年04月25日
    浏览(48)
  • 构建基于RHEL9系列(CentOS9,AlmaLinux9,RockyLinux9等)的支持63个常见模块的PHP8.1.20的RPM包

    本文适用:rhel9系列,或同类系统(CentOS9,AlmaLinux9,RockyLinux9等) 文档形成时期:2023年 因系统版本不同,构建部署应略有差异,但本文未做细分,对稍有经验者应不存在明显障碍。 因软件世界之复杂和个人能力之限,难免疏漏和错误,欢迎指正。 不同时期因各种原因经常产生部

    2024年01月23日
    浏览(42)
  • 构建基于RHEL8系列(CentOS8,AlmaLinux8,RockyLinux8等)的支持63个常见模块的PHP8.1.20的RPM包

    本文适用:rhel8系列,或同类系统(CentOS8,AlmaLinux8,RockyLinux8等) 文档形成时期:2023年 因系统版本不同,构建部署应略有差异,但本文未做细分,对稍有经验者应不存在明显障碍。 因软件世界之复杂和个人能力之限,难免疏漏和错误,欢迎指正。 不同时期因各种原因经常产生部

    2024年02月02日
    浏览(45)
  • Rust之泛型、特性和生命期(三):Traits:定义共同的行为

    Windows 10 Rust 1.70.0    VS Code 1.79.2 这里继续沿用上次工程rust-demo Trait定义了一个特定类型所具有的功能,并且可以与其他类型共享。我们可以使用特质以抽象的方式来定义共享行为。我们可以使用特质的界限来指定一个通用类型可以是任何具有某些行为的类型。  注意:trait

    2024年02月09日
    浏览(51)
  • 安卓开发——控件AlertDialog实现方式,设置下部三个按钮,自定义布局设置.setView(dialogView)样式,控件PopupWindow1常用方法,showAsDropDown构造方法

     AlertDialog . Builder builder = new AlertDialog . Builder ( context ); 构建 Dialog 的各种参数  Builder . setlcon ( int iconld ); 添加 ICON   Builder . setTitle ( CharSequence title ); 添加标题  Builder . setMessage ( CharSequence message ); 添加消息  Builder . setView ( View view ); 设置自定义布

    2024年02月03日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包