学习.NET MAUI Blazor(三)、创建.NET MAUI Blazor应用并使用AntDesignBlazor

news2024/12/28 19:31:57

大致了解了Blazor和MAUI之后,尝试创建一个.NET MAUI Blazor应用。
需要注意的是: 虽然都叫MAUI,但.NET MAUI.NET MAUI Blazor 并不相同,MAUI还是以xaml为主,而MAUI Blazor则是以razor为主。

这个系列还是以MAUI Blazor为主,要创建一个MAUI Blazor应用,需要安装Visual Studio 2022 17.3 或更高版本,并在安装程序上,勾选.NET Multi-platform App UI 开发!最好是升级到最新的.NET 7。
在这里插入图片描述

目录

  • 创建.NET MAUI Blazor应用
  • .NET MAUI Blazor 需要注意的地方
  • 调试.NET MAUI Blazor
  • 使用AntDesignBlazor 组件库
    • 安装依赖:
    • 注入AntDesign
    • 引入样式
    • 加入命名空间
    • 设置容器
    • 修改 MainLayout
    • 改造默认页面
      • index.razor
      • Counter.razor
      • FetchData.razor
  • 运行效果:
  • 总结

创建.NET MAUI Blazor应用

打开Visual Studio 2022,选择创建新项目

在这里插入图片描述
在搜索框输入MAUI,选择.NET MAUI Blazor应用,点下一步

在这里插入图片描述
给项目起一个好听的名字,选择项目存在的位置,点下一步

在这里插入图片描述
选择目标框架,这里选择的是.NET 7,点击创建
在这里插入图片描述
等待创建项目及其依赖项还原。完成后的目录结构如下:
在这里插入图片描述

.NET MAUI Blazor 需要注意的地方

.NET MAUI Blazor 运行在WebView2上,WebView2是微软推出的新一代用于桌面端混合开发的解决方案。它可以让本地应用程序(WinForm、WPF、WinUI、Win32)、移动应用程序(MAUI)轻松嵌入Web技术。WebView2 控件使用 Microsoft Edge 作为呈现引擎在客户端应用程序及App中显示 Web 内容。使用 WebView2 可以将 Web 代码嵌入到客户端应用程序及App中的不同部分,或在单个 WebView 实例中构建所有本机应用程序。

可以这么看MAUI Blazor, .NET MAUI 包含 BlazorWebView 控件,该控件运行将 Razor 组件呈现到嵌入式 Web View 中。 通过结合使用 .NET MAUI 和 Blazor,可以跨移动设备、桌面设备和 Web 重复使用一组 Web UI 组件。

说人话就是,它就是一个Hybrid App(混合应用) !

调试.NET MAUI Blazor

在windows上调试 MAUI Blazor应用,需要Windows 10 1809及更高版本上,并打开开发者模式。
windows 11上,位于设置->隐私和安全性->开发者选项->开发人员模式
在这里插入图片描述
在这里插入图片描述
点击Windows Machine,运行程序!
在这里插入图片描述
如无意外,运行成功!
在这里插入图片描述
这时,MAUI Blazor使用的是bootstrap样式以及open-iconic图标。
wwwroot/index.html中也可以看到

<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />

现在已经有个很多基于Blazor的组件库,所以暂时把默认的bootstrap替换成第三方组件库,这里使用的是AntDesignBlazor

使用AntDesignBlazor 组件库

安装依赖:

PM> NuGet\Install-Package AntDesign.ProLayout -Version 0.13.1

注入AntDesign

MauiProgram.cs注入AntDesign 服务与设置基本配置,完整的MauiProgram.cs代码

using Microsoft.Extensions.Logging;
using MauiBlazorApp.Data;

namespace MauiBlazorApp;

public static class MauiProgram
{
	public static MauiApp CreateMauiApp()
	{
		var builder = MauiApp.CreateBuilder();
		builder
			.UseMauiApp<App>()
			.ConfigureFonts(fonts =>
			{
				fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
			});

		builder.Services.AddMauiBlazorWebView();

#if DEBUG
		builder.Services.AddBlazorWebViewDeveloperTools();
		builder.Logging.AddDebug();
#endif

		builder.Services.AddSingleton<WeatherForecastService>();
        //注入AntDesign
        builder.Services.AddAntDesign();
		//基本配置
		builder.Services.Configure<ProSettings>(settings =>
		{
            settings.NavTheme = "light";
            settings.Layout = "side";
            settings.ContentWidth = "Fluid";
			settings.FixedHeader = false;
			settings.FixSiderbar = true;
            settings.Title = "DotNet宝藏库";
			settings.PrimaryColor = "daybreak";
			settings.ColorWeak = false;
			settings.SplitMenus= false;
			settings.HeaderRender= true;
			settings.FooterRender= false;
			settings.MenuRender= true;
			settings.MenuHeaderRender= true;
			settings.HeaderHeight = 48;

		});
		return builder.Build();
	}
}

配置项都写上了。参数含义从表达的意思就能看出来,不做注释了!

引入样式

打开wwwroot/index.html。由于我们使用的是AntDesign,所以需要改造下index.html,修改后内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
    <title>DotNet宝藏库</title>
    <base href="/" />
    
    <link href="_content/AntDesign/css/ant-design-blazor.css" rel="stylesheet" />
    <link rel="stylesheet" href="_content/AntDesign.ProLayout/css/ant-design-pro-layout-blazor.css" />
</head>

<body>

    <div class="status-bar-safe-area"></div>

    <div id="app">
        <style>
            html,
            body,
            #app {
                height: 100%;
                margin: 0;
                padding: 0;
            }

            #app {
                background-repeat: no-repeat;
                background-size: 100% auto;
            }

            .page-loading-warp {
                padding: 98px;
                display: flex;
                justify-content: center;
                align-items: center;
            }

            .ant-spin {
                -webkit-box-sizing: border-box;
                box-sizing: border-box;
                margin: 0;
                padding: 0;
                color: rgba(0, 0, 0, 0.65);
                font-size: 14px;
                font-variant: tabular-nums;
                line-height: 1.5;
                list-style: none;
                -webkit-font-feature-settings: 'tnum';
                font-feature-settings: 'tnum';
                position: absolute;
                display: none;
                color: #1890ff;
                text-align: center;
                vertical-align: middle;
                opacity: 0;
                -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
                transition: -webkit-transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
                transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
                transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86), -webkit-transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
            }

            .ant-spin-spinning {
                position: static;
                display: inline-block;
                opacity: 1;
            }

            .ant-spin-dot {
                position: relative;
                display: inline-block;
                font-size: 20px;
                width: 20px;
                height: 20px;
            }

            .ant-spin-dot-item {
                position: absolute;
                display: block;
                width: 9px;
                height: 9px;
                background-color: #1890ff;
                border-radius: 100%;
                -webkit-transform: scale(0.75);
                -ms-transform: scale(0.75);
                transform: scale(0.75);
                -webkit-transform-origin: 50% 50%;
                -ms-transform-origin: 50% 50%;
                transform-origin: 50% 50%;
                opacity: 0.3;
                -webkit-animation: antSpinMove 1s infinite linear alternate;
                animation: antSpinMove 1s infinite linear alternate;
            }

            .ant-spin-dot-item:nth-child(1) {
                top: 0;
                left: 0;
            }

            .ant-spin-dot-item:nth-child(2) {
                top: 0;
                right: 0;
                -webkit-animation-delay: 0.4s;
                animation-delay: 0.4s;
            }

            .ant-spin-dot-item:nth-child(3) {
                right: 0;
                bottom: 0;
                -webkit-animation-delay: 0.8s;
                animation-delay: 0.8s;
            }

            .ant-spin-dot-item:nth-child(4) {
                bottom: 0;
                left: 0;
                -webkit-animation-delay: 1.2s;
                animation-delay: 1.2s;
            }

            .ant-spin-dot-spin {
                -webkit-transform: rotate(45deg);
                -ms-transform: rotate(45deg);
                transform: rotate(45deg);
                -webkit-animation: antRotate 1.2s infinite linear;
                animation: antRotate 1.2s infinite linear;
            }

            .ant-spin-lg .ant-spin-dot {
                font-size: 32px;
                width: 32px;
                height: 32px;
            }

            .ant-spin-lg .ant-spin-dot i {
                width: 14px;
                height: 14px;
            }
            .status-bar-safe-area {
                display: none;
            }

            @supports (-webkit-touch-callout: none) {
                .status-bar-safe-area {
                    display: flex;
                    position: sticky;
                    top: 0;
                    height: env(safe-area-inset-top);
                    background-color: #f7f7f7;
                    width: 100%;
                    z-index: 1;
                }

                .flex-column, .navbar-brand {
                    padding-left: env(safe-area-inset-left);
                }
            }
            @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
                .ant-spin-blur {
                    background: #fff;
                    opacity: 0.5;
                }
            }

            @-webkit-keyframes antSpinMove {
                to {
                    opacity: 1;
                }
            }

            @keyframes antSpinMove {
                to {
                    opacity: 1;
                }
            }

            @-webkit-keyframes antRotate {
                to {
                    -webkit-transform: rotate(405deg);
                    transform: rotate(405deg);
                }
            }

            @keyframes antRotate {
                to {
                    -webkit-transform: rotate(405deg);
                    transform: rotate(405deg);
                }
            }
        </style>
        <div style="
          display: flex;
          justify-content: center;
          align-items: center;
          flex-direction: column;
          min-height: 420px;
          height: 100%;
        ">
            <div class="page-loading-warp">
                <div class="ant-spin ant-spin-lg ant-spin-spinning">
                    <span class="ant-spin-dot ant-spin-dot-spin">
                        <i class="ant-spin-dot-item"></i><i class="ant-spin-dot-item"></i><i class="ant-spin-dot-item"></i><i class="ant-spin-dot-item"></i>
                    </span>
                </div>
            </div>
            <div style="display: flex; justify-content: center; align-items: center;">
                 <div class="loading-progress-text"></div>
            </div>
        </div>
    </div>

   

    <script src="_framework/blazor.webview.js" autostart="false"></script>
    <script src="_content/AntDesign/js/ant-design-blazor.js"></script>
</body>

</html>

加入命名空间

_Imports.razor添加AntDesign命名空间:

@using System.Net.Http
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using MauiBlazorApp
@using MauiBlazorApp.Shared
//引入AntDesign
@using AntDesign

设置容器

Main.razor中加入<AntContainer />

<Router AppAssembly="@typeof(Main).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>
<!--设置容器-->
<AntContainer />

修改 MainLayout

  • 修改MainLayout.razor
  • MainLayout.razor中默认布局删除
  • 引入AntDesign.ProLayout
  • 设置布局为AntDesign.ProLayout
  • 构造菜单、页脚的链接、版权
  • wwwroot目录下新建个文件夹images,把提前准备好的logo放进去

完整代码如下:

@using AntDesign.ProLayout
@inherits LayoutComponentBase

<AntDesign.ProLayout.BasicLayout 
    Logo="@("images/logo.png")"
    MenuData="MenuData">
    <ChildContent>
        @Body
    </ChildContent>
    <FooterRender>
        <FooterView Copyright="MauiBlazorApp" Links="Links"></FooterView>
    </FooterRender>
</AntDesign.ProLayout.BasicLayout>
<SettingDrawer />

@code
{
    private readonly MenuDataItem[] MenuData =
        {
        new MenuDataItem
        {
            Path = "/",
            Name = "Home",
            Key = "Home",
            Icon = "home"
        },
        new MenuDataItem
        {
            Path = "/Counter",
            Name = "Counter",
            Key = "Counter",
            Icon = "plus"
        },
        new MenuDataItem
        {
            Path = "/FetchData",
            Name = "FetchData",
            Key = "FetchData",
            Icon = "cloud"
        }
    };
    private readonly LinkItem[] Links =
    {
        new LinkItem
        {
            Key = "DotNet宝藏库",
            Title = "基于Ant Design Blazor",
            Href = "https://antblazor.com",
            BlankTarget = true
        }
    };
}

这时可以把项目中无用的内容删除掉了,如Shared/NavMenu.razorwwwroot/css文件。
由于删除掉了css文件夹,页面元素肯定没有样式了。那么就简单的改造下默认的几个页面!

改造默认页面

index.razor

打开Pages/Index.razor,将演示组件SurveyPrompt 删掉。顺便把Shared/SurveyPrompt.razor也删除掉。将<h1>Hello, world!</h1>
替换为Ant Design组件。

@page "/"

<Title Level="1">Hello,DotNet宝藏库</Title>

<br />
<Text Type="success">欢迎关注我的公众号!</Text>

Counter.razor

打开 Pages/Counter.razor,将代码改为如下:

@page "/counter"

<Title Level="2">HCounter</Title>
<Divider />
<p role="status">Current count: @currentCount</p>

<Button @onclick="IncrementCount" Type="primary">AntDesign 按钮</Button>
@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

FetchData.razor

打开Pages/FetchData.razor,将数据表格替换为Ant Design,删除页面所有代码,替换为Ant Design的示例!

@page "/fetchdata"
@using System.ComponentModel
@using AntDesign.TableModels
@using System.Text.Json

@using MauiBlazorApp.Data
@inject WeatherForecastService ForecastService

<Table @ref="table"
       TItem="WeatherForecast"
       DataSource="@forecasts"
       Total="_total"
       @bind-PageIndex="_pageIndex"
       @bind-PageSize="_pageSize"
       @bind-SelectedRows="selectedRows"
       OnChange="OnChange">
    <Selection Key="@(context.Id.ToString())" />
    <PropertyColumn Property="c=>c.Id" Sortable />
    <PropertyColumn Property="c=>c.Date" Format="yyyy-MM-dd" Sortable />
    <PropertyColumn Property="c=>c.TemperatureC" Sortable />
    <PropertyColumn Title="Temp. (F)" Property="c=>c.TemperatureF" />
    <PropertyColumn Title="Hot" Property="c=>c.Hot">
        <Switch @bind-Value="@context.Hot"></Switch>
    </PropertyColumn>
    <PropertyColumn Property="c=>c.Summary" Sortable />
    <ActionColumn>
        <Space>
            <SpaceItem><Button Danger OnClick="()=>Delete(context.Id)">Delete</Button></SpaceItem>
        </Space>
    </ActionColumn>
</Table>
<br />
<p>PageIndex: @_pageIndex | PageSize: @_pageSize | Total: @_total</p>

<br />
<h5>selections:</h5>
@if (selectedRows != null && selectedRows.Any())
{
    <Button Danger Size="small" OnClick="@(e => { selectedRows = null; })">Clear</Button>

    @foreach (var selected in selectedRows)
    {
        <Tag @key="selected.Id" Closable OnClose="e=>RemoveSelection(selected.Id)">@selected.Id - @selected.Summary</Tag>
    }
}

<Button Type="@ButtonType.Primary" OnClick="()=> { _pageIndex--; }">Previous page</Button>
<Button Type="@ButtonType.Primary" OnClick="()=> { _pageIndex++; }">Next Page</Button>

@code {
    private WeatherForecast[] forecasts;
    IEnumerable<WeatherForecast> selectedRows;
    ITable table;
    int _pageIndex = 1;
    int _pageSize = 10;
    int _total = 0;

    protected override async Task OnInitializedAsync()
    {
        forecasts = await GetForecastAsync(1, 50);
        _total = 50;
    }
    public class WeatherForecast
    {
        public int Id { get; set; }

        [DisplayName("Date")]
        public DateTime? Date { get; set; }

        [DisplayName("Temp. (C)")]
        public int TemperatureC { get; set; }

        [DisplayName("Summary")]
        public string Summary { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

        public bool Hot { get; set; }
    }
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };
    public void OnChange(QueryModel<WeatherForecast> queryModel)
    {
        Console.WriteLine(JsonSerializer.Serialize(queryModel));
    }
    public Task<WeatherForecast[]> GetForecastAsync(int pageIndex, int pageSize)
    {
        var rng = new Random();
        return Task.FromResult(Enumerable.Range((pageIndex - 1) * pageSize + 1, pageSize).Select(index =>
        {
            var temperatureC = rng.Next(-20, 55);
            return new WeatherForecast
                {
                    Id = index,
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = temperatureC,
                    Summary = Summaries[rng.Next(Summaries.Length)],
                    Hot = temperatureC > 30,
                };
        }).ToArray());
    }
    public void RemoveSelection(int id)
    {
        var selected = selectedRows.Where(x => x.Id != id);
        selectedRows = selected;
    }

    private void Delete(int id)
    {
        forecasts = forecasts.Where(x => x.Id != id).ToArray();
        _total = forecasts.Length;
    }
}

运行效果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

总结

暂无,下次再会

点击下方公众号卡片,关注我!一起学习,一起进步!

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

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

相关文章

23. 【gRPC系列学习】gRPC安全认证-JWT认证

JWT 即 JSON Web Token,是用 JSON 形式安全传输信息的方法。本节介绍JWT与gRPC结合,关于JWT交互流程的介绍参考文末的链接。 1. 使用JWT客户端与服务端交互 1)客户端使用用户名、密码发送给服务端 2)服务端返回JWT数据,返回数据由三部分组成 Header:TOKEN 的类型,就是JW…

截至2022年12月共计451个信息安全国家标准 汇总

写在前面 早年刚参加信息安全工作更多的学点皮毛技术&#xff0c;到处找安全工具&#xff0c;跟踪poc&#xff0c;拿到一个就全网扫一遍&#xff0c;从来没有想过&#xff0c;系统化的安全工作应该怎样搞?我做的工作在安全体系中处于哪个阶段? 后来有机会做企业安全建设&…

二本跨专业自学编程及程序员就业之路——20W社招进银行

自学编程的道路 先做个自我介绍&#xff0c;我是一名普通二本院校的学生。在广州上学&#xff0c;21年毕业&#xff0c;非科班出身。上大学之前&#xff0c;很少接触电脑&#xff0c;连QQ都是别人送我的&#xff0c;当时还开心了好一阵子。 大学的时候&#xff0c;开始接触的第…

对美国学校制度的一点儿思考

本文作者在美国生活了几十年&#xff0c;随着对这个国家的深入了解&#xff0c;发现原来对美国的一些认知上有偏差。所以其根据在美的所见所闻&#xff0c;结合中国国内的情况&#xff0c;做了分析对照&#xff0c;在此知识人网小编仅摘录关于美国学校制度的内容以飨读者。 美国…

喜报 | 知道创宇ZoomEye Pro获评ISC 2022创新能力百强,实力入选“攻击面与资产管理领域”创新产品榜单!

12月21日&#xff0c;ISC 2022数字安全创新能力百强颁奖典礼在北京举行。 知道创宇的 ZoomEye Pro 以其先进的网络安全技术和创新产品能力&#xff0c;通过层层筛选&#xff0c;从众多产品中脱颖而出&#xff0c;入选“攻击面与资产管理领域”的创新产品榜单&#xff01;知道创…

IDEA运行缓慢,闪退解决方式——增加堆内存

目录方法一&#xff1a;通过IDE修改配置方法二&#xff1a;使用ToolBox进行设置方法三&#xff1a;直接修改vmoptions文件如果遇到速度变慢的情况&#xff0c;可能需要增加内存堆。方法一&#xff1a;通过IDE修改配置 help–>Change Memory Setting–>修改为一个合适的值…

机器学习算法基础——决策树

文章目录决策树算法的定义发展历程适用范围及其优缺点适用范围优点缺点代码实现决策树算法的定义 决策树&#xff08;Decision Tree&#xff09;是在已知各种情况发生概率的基础上&#xff0c;通过构成决策树来求取净现值的期望值大于等于零的概率&#xff0c;评价项目风险&…

系统设计场景题—MySQL使用InnoDB,通过二级索引查第K大的数,时间复杂度是多少?

系统设计场景题—MySQL使用InnoDB&#xff0c;通过二级索引查第K大的数&#xff0c;时间复杂度是多少&#xff1f;前言明确场景对齐表的结构分析时间复杂度执行一条 select 语句&#xff0c;期间发生了什么&#xff1f;分析性能的瓶颈如何做出优化一、从业务上绕过二、使用覆盖…

史上最强人工智能ChatGPT 到底有多强?

ChatGPT 已经踏上了它的成神之路&#xff0c;这绝对是我所用过的&#xff0c;我相信也是你用过的&#xff0c;最让人震撼的人工智能产品&#xff0c;比起 AI 画画&#xff0c;它甚至更具颠覆性。只用短短十分钟&#xff0c;它就耗尽了我毕生所学的感叹词&#xff0c;最后只留下…

I2S和I2C分别如何连接pad

GPIO一共有8种输入输出模式。可参考&#xff1a; GPIO内部结构和各种模式_cy413026的博客-CSDN博客读了该篇文章可以知道&#xff1a;1.gpio可以直接用cpu通过寄存器控制读写2.可以直接与片内外设连接 受外设控制(I2C)3.gpio的push-pull和OD/OC结构4.上下拉在输入输出的使用5.…

微信小程序之实时聊天系统——页面介绍

目录 系统结果展示&#xff1a; 系统的页面说明&#xff1a; 1.我们首先再app.json中创建四个tabBar页面&#xff08;消息、联系人、用户列表、我的&#xff09; 2.消息页面&#xff1a; 3.联系人页面&#xff1a; 4.用户列表页面&#xff1a; 5.我的页面&#xff1a; 欢…

buildroot 勾选alsa - utils编译后未 /bin 包含

alsa-lib 这个库在 buildroot 已经默认编译进去我们可以不用管&#xff0c;我们只需要使能 alsa-utils 就 行了&#xff0c;还是在 buildroot 的源码目录下&#xff0c;运行以下命令进入图形化界面配置&#xff1a;make menuconfig 按照以下路径进入配置我们的 alsa-utils&…

【SpringMVC】请求参数的绑定

1.绑定说明 1.1 绑定的机制 我们都知道&#xff0c;表单中请求参数都是基于 keyvalue 的。SpringMVC 绑定请求参数的过程是通过把表单提交请求参数&#xff0c;作为控制器中方法参数进行绑定的。 例如&#xff1a; <a href"account/findAccount?accountId10"&…

Vulnhub靶机:PWNOS_ 2.0 (PRE-RELEASE)

目录介绍信息收集网站探测漏洞发现提权搜寻数据库配置文件SSH爆破第2种打法网站探测Sql注入&#xff08;手工&#xff09;Sql注入&#xff08;sqlmap&#xff09;读取文件写入文件提权参考介绍 系列&#xff1a;pWnOS&#xff08;此系列共2台&#xff09; 发布日期&#xff1a…

【前端-React Native】移动端原生开发整合React Native Elements教程-安卓示例

目录一、移动开发和web开发的区别二、什么是React Native?三、如何实现安卓和IOS用一套代码开发四、React Native开发实战1. 安装Android studio2. 使用Expo创建工程3. 启动4. 使用UI框架React Active Elements5. 扩展&#xff1a;使用UI框架antd Design Mobile RN五、项目结构…

Hadoop综合项目——二手房统计分析(Hive篇)

Hadoop综合项目——二手房统计分析&#xff08;Hive篇&#xff09; 文章目录Hadoop综合项目——二手房统计分析&#xff08;Hive篇&#xff09;0、 写在前面1、Hive统计分析1.1 本地数据/HDFS数据导入到Hive1.2 楼龄超过20年的二手房比例1.3 四大一线城市各楼层地段的平均价格1…

没有基础转行学编程,靠谱吗?能找到工作吗?

在日常生活中&#xff0c;以及在知乎上&#xff0c;有很多人咨询职业生涯的抉择。他们大都对自己的职业现状不满意&#xff0c;打算学习编程成为一名程序员。 为什么想要做程序员&#xff1f; 答案五花八门&#xff0c;其中「工资高」「好找工作」「有职业发展」是很常见的理由…

代码质量管理平台实战| SonarQube 安装、配置及 JaCoCo、Maven 集成

SonarQube 是一个用于代码质量管理的开源平台&#xff0c;用于管理源代码的质量。同时 SonarQube 还对大量的持续集成工具提供了接口支持&#xff0c;可以很方便地在持续集成中使用 SonarQube。此外&#xff0c; SonarQube 的插件还可以对 Java 以外的其他编程语言提供支持&…

请求量太大扛不住怎么办?进来学一招

hello&#xff0c;大家好呀&#xff0c;我是小楼。 上篇文章《一言不合就重构》 说了我最近重构的一个系统&#xff0c;虽然重构完了&#xff0c;但还在灰度&#xff0c;这不&#xff0c;在灰度过程中又发现了一个问题。 背景 这个问题简单说一下背景&#xff0c;如果不明白…

数据结构之排序【直接插入排序和希尔排序的实现及分析】

引言&#xff1a; 今天天气还是依然的冷&#xff0c;码字越来越不容易了&#xff0c;本来上次写了一个比较好的引言&#xff0c;但是因为电脑第二天没电&#xff0c;并且我没有保存&#xff0c;现在找不到了&#xff0c;所以今天我们的引言就这样吧&#xff01;今天给大家介绍…