ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Android Studio线性布局仿微信登录界面:从Layout_weight到嵌套布局实战

Android Studio线性布局仿微信登录界面:从Layout_weight到嵌套布局实战 简介这是一份基于Android Studio与Java语言实现的仿微信登录、注册界面项目资源适合Android初学者或需要快速搭建认证模块的开发者参考。资源以线性布局LinearLayout为核心覆盖界面设计、状态选择器、主题样式、登录状态持久化等关键知识点并附有完整工程文件与XML布局源码。压缩包共1289个文件主要包含apk、dex、class、java、xml、json、gradle及png图片等类型其中java、xml为界面逻辑与布局核心apk可直接安装体验整体约21.28MB。当前已有2732人学习下载可作为动手练习或项目改造的实用素材。通过研读该工程可掌握登录注册双界面切换、输入校验反馈、SharedPreferences数据持久化、微信风格绿色主题配置等实战技能为独立开发App账号体系打下基础。1. 一个 .rar 里的登录页Android Studio 仿微信界面到底该从哪抄起拿到Android Studio仿微信登录、注册界面——线性布局.rar这类压缩包第一反应是解压、导入、改包名结果多半是 Gradle 版本对不上、兼容包报错、一堆 style 找不到。其实这个题目的重点不在那个 rar而在线性布局四个字——用 LinearLayout 把微信登录页的上下结构堆出来是 Android 入门阶段最值得练手的一课既涉及到嵌套布局、layout_weight 权重分配又涉及到按钮状态、输入框焦点和 Activity 跳转。这篇笔记不扒那个包的内容只按这个标题背后真正要解决的方案来讲。适合刚装了 Android Studio、打算复刻一个像样登录界面的初学者也适合想用线性布局规范自己表单页面的新手工程师。看完你就能在本地从空工程徒手搭出微信风格的登录、注册两个页面踩过的坑也写在后面。2. 为什么用线性布局仿微信登录页的界面拆解与选型理由2.1 微信登录页的控件层级三个 block 的线性关系先把微信登录页的手机端截图在脑子里切一刀。页面从上到下可以切成三块顶部标识区微信号/手机端登录页的顶部 Logo 和产品名中间输入区手机号输入框、密码输入框以及可能存在的更多登录方式底部操作区主登录按钮、底部协议文字、注册入口。这三个区域天然就是垂直排列的。每一个区域内控件之间又是水平排列的。比如输入框左侧一个小图标、右侧一个清除按钮或者左侧标签、右侧输入框。这种外垂直、内水平的嵌套结构正是 LinearLayout 最擅长的。垂直方向的根布局只管把三个 block 依次压下去水平方向的子布局只管把一行里的控件排开。整个 XML 结构可以看成LinearLayout orientationvertical LinearLayout orientationvertical !-- 顶部标识 -- /LinearLayout LinearLayout orientationvertical !-- 中间输入区 -- LinearLayout orientationhorizontal !-- 一行手机号 -- /LinearLayout /LinearLayout LinearLayout orientationvertical !-- 底部操作区 -- /LinearLayout /LinearLayout为什么不用 RelativeLayout 或者约束布局因为登录页是一个典型的表单页表单的特性就是逐行罗列。线性布局的 orientation 能把逐行这个语义直接写进 XML 里后接手的人看一眼根布局就知道页面顺序。约束布局虽然能缩短层级但当你需要等分高度或宽度时线性布局的 layout_weight 是现成的机制不需要拉一条条约束线。而如果你用 RelativeLayout顶部标识区、中间输入区、底部按钮区之间的对齐关系就要反复用 alignTop、alignBottom 去维护嵌套一多反而更难读。所以这个场景下线性布局是最省心的选型这也是市面上一堆安卓课程拿登录页做线性布局教学的原因。2.2 线性布局 vs 相对布局 vs 约束布局仿微信界面到底选谁如果你已经在 Android Studio 里建过几个页面可能会想现在不都推荐约束布局吗为什么不直接用 ConstraintLayout 一把梭对登录注册这种固定两屏的页面约束布局确实能做出来但有两个问题约束布局的学习成本不在控件排列而在约束逻辑。一个输入框要水平居中、另一个按钮要贴底这些约束语句写多了界面哪里密、哪里疏不如 linear layout 直观。仿写微信界面要像关键在间距和比例而间距和比例用 LinearLayout 的 layout_margin 和 layout_weight 更容易微调。约束布局里调权重需要写 chain 和 bias 才碰得到同等效果对新手是黑匣子。线性布局还有一个隐藏优势它对嵌套的容忍度比相对布局高而且运行时的测量逻辑简单。Android 渲染一个 LinearLayout 时先确认 orientation 再按顺序摆放子 View而 RelativeLayout 要两次遍历计算位置ConstraintLayout 需要先解析约束方程组。在登录页这种低频页面里性能差异根本感知不到所以选型不用为性能纠结看的是哪个更容易手写、更容易调试。不过也要记住线性布局的边界一旦页面里既有左上角图标、又有右下角悬浮按钮、还有跟随内容的流式标签线性布局就会变成套娃地狱。那时候别硬撑切到约束布局才是对的。仿微信登录注册页还远没到那个复杂度根布局一个垂直 LinearLayout 足够。3. 从零到可运行Android Studio 线性布局登录页的搭建步骤3.1 新建项目先让空工程跑起来老手拿到 .rar 会先看里面有没有 .gradle 和 local.properties对新手建议别解压别人的工程直接在 Android Studio 里新建。常见做法是选择 Empty Views Activity语言选 Java 或 Kotlin 都行下面示例用 Kotlin。注意 SDK 版本不用追最新compileSdk 用 34 或 35 就够了minSdk 24。新建完成后第一步不是写布局而是先跑一次原始模板确认 Android Studio 下载依赖、Gradle 同步没有问题。这一步省很多事因为后面写代码报错时至少能排除环境问题。如果你想要双击导入 .rar 里的工程常见问题是 Gradle 版本和 wrapper 不匹配会看到类似 Failed to sync Gradle project 的红字所以自己建工程反而是最快的路。Android Studio 的下载安装和 SDK 配置这些前置步骤照着官网默认选项走即可这里不展开。3.2 登录页 XML根布局为垂直 LinearLayout 的最简实现新建完工程后先把 activity_login.xml 的默认布局替换掉。下面的 XML 是仿微信登录页的核心结构去掉了无关的 AppBar只保留三块?xml version1.0 encodingutf-8? LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightmatch_parent android:orientationvertical android:paddingLeft32dp android:paddingRight32dp android:background#F7F7F7 !-- 顶部标识区 -- LinearLayout android:layout_widthmatch_parent android:layout_height0dp android:layout_weight3 android:orientationvertical android:gravitycenter TextView android:layout_widthwrap_content android:layout_heightwrap_content android:text微信 android:textSize28sp android:textColor#333333 / /LinearLayout !-- 中间输入区 -- LinearLayout android:layout_widthmatch_parent android:layout_heightwrap_content android:orientationvertical EditText android:idid/et_phone android:layout_widthmatch_parent android:layout_height52dp android:hint手机号 android:inputTypephone android:backgrounddrawable/bg_input_top / EditText android:idid/et_password android:layout_widthmatch_parent android:layout_height52dp android:hint密码 android:inputTypetextPassword android:backgrounddrawable/bg_input_bottom / /LinearLayout !-- 登录按钮区 -- LinearLayout android:layout_widthmatch_parent android:layout_height0dp android:layout_weight2 android:orientationvertical android:gravitycenter_horizontal Button android:idid/btn_login android:layout_widthmatch_parent android:layout_height48dp android:text登录 android:textSize16sp android:textColor#FFFFFF android:backgrounddrawable/bg_btn_login / /LinearLayout /LinearLayout这段代码的逻辑根布局是垂直 LinearLayout三块区域全部由 orientation 和 weight 控制。顶部区高度用 0dp 加 layout_weight3底部按钮区用 0dp 加 layout_weight2中间输入区 wrap_content。为什么顶部和底部高度要用 0dp weight因为要让登录页在屏幕高度不固定的情况下把输入区托在视觉中间偏上位置比例接近微信原版的上宽下窄。参数上需要注意EditText 高度写死 52dp是为了让两个框严丝合缝拼在一起形成微信那种连续输入框的感觉中间不能有 margin。输入框背景是分开 drawable 的上面输入框只画顶部的圆角下面输入框只画底部圆角这样拼起来才像一个整体。你一眼看过去会发现微信登录框是圆角矩形连在一起的这就是这两个 drawable 的功劳。3.3 注册页 XML嵌套线性布局与权重分配注册页的结构就不只是垂直堆叠了。手机号、验证码、密码、昵称每一行都可能是一个左标签 右输入框的水平线性布局。这里用注册页做嵌套演示LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightmatch_parent android:orientationvertical android:padding24dp TextView android:layout_widthwrap_content android:layout_heightwrap_content android:text注册 android:textSize24sp android:textColor#222222 android:layout_marginBottom24dp / LinearLayout android:layout_widthmatch_parent android:layout_heightwrap_content android:orientationhorizontal TextView android:layout_width80dp android:layout_height52dp android:text昵称 android:gravitycenter_vertical android:textSize15sp / EditText android:idid/et_name android:layout_width0dp android:layout_height52dp android:layout_weight1 android:hint请输入昵称 android:backgroundandroid:color/transparent / /LinearLayout !-- 分割线 -- View android:layout_widthmatch_parent android:layout_height1dp android:background#E5E5E5 / LinearLayout android:layout_widthmatch_parent android:layout_heightwrap_content android:orientationhorizontal TextView android:layout_width80dp android:layout_height52dp android:text手机号 android:gravitycenter_vertical android:textSize15sp / EditText android:idid/et_reg_phone android:layout_width0dp android:layout_height52dp android:layout_weight1 android:hint请输入手机号 android:inputTypephone android:backgroundandroid:color/transparent / /LinearLayout /LinearLayout代码里的核心是水平嵌套时layout_width0dp配合layout_weight1。左侧标签宽度固定为 80dp右侧输入框占满剩余空间。这个写法和直接写layout_widthmatch_parent的区别在于match_parent 会把左侧标签挤出屏幕因为父布局宽度已经满了而 0dp weight 表示剩余空间分配权重左侧固定、右侧自适应。这是线性布局做表单最常用的比例控制手段也是android studio 自定义组件之前必须吃透的基础规则。注册页的验证码行更典型左边手机号输入框占 1 份权重右边获取验证码按钮宽度固定 110dp。你只需要把上面水平 LinearLayout 里的 EditText 再包一层 LinearLayout或者直接让 EditText 与 Button 作为两个子 View 放在同一个水平 LinearLayout 中权重给 EditTextButton 不给权重Button 就会自动贴右侧。3.4 绑定逻辑登录失败提示与注册跳转布局写完后还要把 Activity 里的逻辑挂上。登录页至少要有两个交互点击登录按钮后校验手机号和密码点击某个链接跳转到注册页。下面是最小可用的 Kotlin 写法class LoginActivity : AppCompatActivity() { private lateinit var etPhone: EditText private lateinit var etPassword: EditText private lateinit var btnLogin: Button override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) etPhone findViewById(R.id.et_phone) etPassword findViewById(R.id.et_password) btnLogin findViewById(R.id.btn_login) btnLogin.setOnClickListener { val phone etPhone.text.toString().trim() val password etPassword.text.toString().trim() if (phone.isEmpty()) { Toast.makeText(this, 请输入手机号, Toast.LENGTH_SHORT).show() returnsetOnClickListener } if (password.length 6) { Toast.makeText(this, 密码至少6位, Toast.LENGTH_SHORT).show() returnsetOnClickListener } // 模拟登录真实项目在这里替换成接口调用 Toast.makeText(this, 登录成功演示, Toast.LENGTH_SHORT).show() } } }逻辑说明这里没有接后端校验规则写得非常简单手机号非空、密码大于等于 6 位。returnsetOnClickListener是 Kotlin 里 lambda 的提前返回写法作用是校验失败时不执行后面的代码。新手容易漏掉.trim()导致输入框带空格时误判另外text在 Android Studio 2021 之后会提示可以直接用text.toString()老代码里getText().toString()写法也能跑但新项目统一用text.toString()更干净。注册页的跳转建议放在登录页底部一个 TextView 的点击事件里而不是用 Button。微信的注册入口从视觉效果看是一个超链接文本。给这个 TextView 加下划线或者单独颜色即可。跳转代码用startActivity(Intent(this, RegisterActivity::class.java))别忘了在 AndroidManifest.xml 里注册 RegisterActivity否则点击时会闪退并抛ActivityNotFoundException。这是 Android Studio 使用里最常见的低级错误之一。4. 仿得到位形状背景、分割线与权重参数的三个细节4.1 layout_weight 的两种计算场景填满与按比例分配很多人把 layout_weight 理解成权重越大控件越大其实这个说法在垂直布局下不够准确。计算的核心是先按所有子 View 声明的 height或 width分配空间剩余空间再按 weight 比例分配。如果你给两个子 View 都声明layout_height0dp也就是让它们不预先占用空间那么剩余空间就是整个父布局weight 就直接决定最终高度占比。上一章登录页顶部区 weight3、底部区 weight2父容器总高扣除中间 wrap_content 部分剩下的高度按 3:2 分给顶部和底部。另一种常见场景是填满剩余空间。比如水平布局里左边一个图标宽度 24dp右边说明文字希望占满剩下的所有宽度可以这样写ImageView android:layout_width24dp android:layout_height24dp / TextView android:layout_width0dp android:layout_heightwrap_content android:layout_weight1 android:text占满剩余空间 /这里的 TextView 的宽度是 0dp权重 1意思是我不抢空间父布局分完图标后剩下多少我占多少。如果你给这个 TextView 写match_parent而不是 0dp右边的空间会被它占满左边图标就被挤出可视区域。这个差异在仿微信的协议说明 勾选框一行里特别容易出现勾选框固定 20dp协议文字应该用0dp weight1写错就翻车。4.2 shape 背景与 selector圆角输入框和按下反馈微信登录页两个输入框是一个整体圆角矩形中间没有缝隙。这个效果靠给两个 EditText 分别设置不同只圆角的 shape drawable。在 res/drawable 下新建 bg_input_top.xmlshape xmlns:androidhttp://schemas.android.com/apk/res/android solid android:color#FFFFFF / corners android:topLeftRadius8dp android:topRightRadius8dp / /shape再新建 bg_input_bottom.xml把 corners 换成android:bottomLeftRadius和android:bottomRightRadius。登录按钮的绿色背景通常也要做成 shape这里可以用一个带按下状态的 selectorselector xmlns:androidhttp://schemas.android.com/apk/res/android item android:state_pressedtrue shape solid android:color#1AAD19 / corners android:radius6dp / /shape /item item shape solid android:color#07C160 / corners android:radius6dp / /shape /item /selectorselctor 的顺序有个必须记住的坑state_pressed的状态项要写在最上面默认状态的 item 放最后。如果把默认 item 放前面按压状态永远不会匹配到因为系统按顺序匹配状态默认 item 后写才对。这些 drawable 就是android studio 自定义组件里的自定义背景不需要写任何 Java 代码纯 XML 就能实现。4.3 字号、颜色与分割线从能用到像微信对比原版截图你会发现微信登录页的输入框内文字颜色是 #333333hint 文字是 #999999按钮颜色是绿色 #07C160分割线是 #E5E5E5。这些数值不是玄学是微信设计规范里沉淀下来的灰度层级。你自己仿写的时候别用默认的黑色和 theme 自带的按钮紫色否则一眼假。字号上主按钮文字 16sp、输入框文字 15sp、协议说明 12sp三个层级对应三个字号。间距上输入框距屏幕左右各 32dp输入框之间无间距登录按钮距输入区 24dp。这些值都可以从微信截图里用 Pixel 尺量出来Android Studio 里可以用 Layout Inspector 直接看像素距离后面章节会专门讲验证方法。另外注册页和登录页之间的切换往往在登录页底部放一个使用协议的勾选框和一行注册文本。这里的勾选框不要在 XML 里用 CheckBox微信是自定义的圆形图标建议用 ImageView selector 切换两张图点击时改 isSelected 状态ivCheck.setOnClickListener { ivCheck.isSelected !ivCheck.isSelected }再用android:backgrounddrawable/bg_check把选中和未选中状态通过 selector 交给系统处理。这种交互虽然小却是界面上像不像微信的胜负手。5. 避坑线性布局做登录页常踩的 5 个坑5.1 输入框被键盘顶飞adjustPan 还是滚动布局现象在模拟器或真机上点击手机号输入框弹出的软键盘把整个登录按钮顶出屏幕或者顶部 Logo 被压缩页面看起来像被折叠了。原因Activity 默认的窗口调整模式是 adjustResize但你的根布局里没有可滚动的容器当软键盘弹出时系统压缩可视高度LinearLayout 底部的按钮区就被挤出了可视范围。解决最省事的做法是在 AndroidManifest.xml 的 Activity 上设置android:windowSoftInputModeadjustResize让根布局在键盘弹出时重新测量高度。但这样按钮还是可能被顶到键盘上方视觉上拥挤。微信自己的做法是什么微信登录页是“输入框上移但按钮保持在键盘上方或者变成滚动”。常见做法是把根布局换成 ScrollView 包一层 LinearLayout让内容在键盘弹出时可以向上滚动ScrollView android:layout_widthmatch_parent android:layout_heightmatch_parent android:fillViewporttrue LinearLayout android:layout_widthmatch_parent android:layout_heightwrap_content android:orientationvertical !-- 原有登录内容 -- /LinearLayout /ScrollView注意android:fillViewporttrue必须加上否则内容不足一屏时 ScrollView 里的 LinearLayout 高度不会撑满父容器背景颜色就会失效看起来像下面的区域掉色了。加了这个属性子布局高度小于一屏时也会自动 match_parent背景才能铺满。5.2 权重 宽度 match_parent 导致按钮变形现象在水平布局里给两个按钮分别设置了 layout_weight1 和 layout_widthmatch_parent运行后两个按钮宽度不是 1:1甚至整个布局乱掉。原因这是线性布局最经典的误用。前面讲过权重计算是先按声明分配空间再对剩余空间按权重分配。声明 match_parent 时每个按钮先抢占了整个父容器宽度剩余空间为负数权重就会按负比例拉扯最后表现完全无法预测。解决只要在水平方向参与权重分配的 View宽度一律写0dp垂直方向参与权重分配则高度写 0dp不要写 match_parent或 wrap_content。这也是 lint 工具会给你黄色警告的原因。养成习惯看到布局里有layout_weight立刻检查对应轴的长度尺寸是否为 0dp。登录页顶部区 height0dp 配合 weight3 也是同一原则。5.3 背景 shape 不生效drawable 路径和 selector 状态顺序现象仿微信输入框时给 EditText 设置了android:backgrounddrawable/bg_input_top结果运行后输入框还是默认的下划线底边框或者背景完全空白。原因第一种情况是 drawable 文件没放在res/drawable/下而是放错了模块目录或者文件名带了大写字母Android 资源文件要求小写字母和下划线命名不合法时 IDE 会直接标红。第二种情况是 selector 的状态顺序写反了按下的绿色背景永远显示不出来。解决确认 res/drawable 下的文件名全小写然后检查 EditText 的背景是在android:background属性里设置而不是android:backgroundTint。backgroundTint 只对默认背景生效不会渲染你的 shape 文件。selector 顺序调整成 pressed 在上、default 在下。另外个别主题会强制把按钮背景替换掉需要在主题里自定义 buttonStyle或者干脆用TextView加android:clickabletrue模拟按钮这样背景形状完全由你控制不被 Material 组件覆盖。5.4 登录按钮点击无响应id 绑定错误或 AVD 键盘事件现象代码里写了btnLogin.setOnClickListener点击时按钮没有任何反馈既不跳转也没 Toast。原因这类问题多出在三个位置一是findViewById(R.id.btn_login)在 setContentView 之前调用导致空指针二是 XML 布局里的按钮 id 和代码里的 id 不一致常见于从别人工程里复制布局时改了一半三是 Android Studio 自带模拟器同时打开了硬件键盘回车键事件被焦点控件消费点击事件没有触发。解决先确认 setContentView 在 findViewById 之前然后把布局 XML 和 Activity 里的 R.id 对比着看。经验是直接在 xml 里用tools:context绑定 Activity然后使用binding或者findViewById时注意导包——android.R.id.btn_login和你的包名.R.id.btn_login两个 R 类不一样一旦导错 IDE 不会报错但运行时就崩。模拟器问题改用鼠标点击按钮测试不要用键盘回车键触发。5.5 不同分辨率下布局错位固定 dp 值与基准屏的选择现象同一个登录页在 Pixel 2 上显示正常在真机 6.5 寸屏上顶部 Logo 与输入框的距离变大登录按钮像被往下推了在平板上又糊成一团。原因你把顶部区和底部区的高度固定写死了比如 100dp、120dp屏幕越大中间 wrap_content 区域就会被撑在中间比例看起来跟微信原版差别就越大。微信原版不是简单垂直居中而是 Logo 区占屏幕约 1/3输入区固定高度底部按钮区占剩余空间的 1/3整体视觉中心略偏上。解决把顶部区和底部区的高度都改成 0dp weight让系统动态分配剩余空间。具体权重值不用纠结一次到位先在模拟器上跑通 1920x1080 和 2400x1080 两种分辨率再微调 weight。常见经验是顶部 weight3、底部 weight2 接近微信视觉如果是小屏可以把顶部 weight 改成 2.5底部不变。注意权重是 float可以写小数。不要依赖android:layout_marginTop去推位置那会让你在一台手机上对一个值换个分辨率就得重调。6. 进阶验证你的登录页像微信的一个技巧——用 View 树检查层级很多时候你觉得做了个登录页但味道不对问题不在颜色而在间距比例。这里教一个我常用的验证方法把微信真机截图放进 Android Studio 的 Layout Inspector 对比。先运行你的工程点击 Layout Inspector选中当前 LoginActivity就能看到一棵 View 树。每一条子 View 的右侧都显示它在屏幕里的实际像素范围和 margin、padding 值。然后打开微信登录页的截图用截图工具量一下头像到底部输入框的距离和输入框到按钮的距离再把这两个数字换算成 dp。一般来说标准和 30 到 32 dp 左右的间距头像区高度占屏幕总高约 30%按钮与输入框间距接近 1624 dp。照着把 XML 里的 margin 和 weight 微调相似度立竿见影。另一个进阶操作是给登录页加沉浸式状态栏。微信登录页的状态栏和页面背景同色没有黑条。实现方式是在 LoginActivity 里调用window.statusBarColor ContextCompat.getColor(this, R.color.login_bg)并把根布局背景设成同一张颜色。如果你用深色模式切换还需要在 values-night 下再放一份颜色资源否则夜间模式下拉状态栏会露馅。这一步做完整个页面的像会再上一个台阶。最后我自己的习惯是每次学一个新的布局技巧都拿微信或者支付宝的页面截图照着调一次不做成像素级复制而是理解它为什么把间距定成这样——这个习惯帮我避掉了无数按钮跑偏的返工。希望帮到你。本文还有配套的精品资源点击获取
返回列表