当前位置:   article > 正文

Android类似微信首页的页面开发教程(Kotlin)二_android首页界面

android首页界面

前提条件

安装并配置好Android Studio

Android Studio Electric Eel | 2022.1.1 Patch 2
Build #AI-221.6008.13.2211.9619390, built on February 17, 2023
Runtime version: 11.0.15+0-b2043.56-9505619 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Windows 11 10.0
GC: G1 Young Generation, G1 Old Generation
Memory: 1280M
Cores: 6
Registry:
    external.system.auto.import.disabled=true
    ide.text.editor.with.preview.show.floating.toolbar=false
    ide.balloon.shadow.size=0
 
Non-Bundled Plugins:
    com.intuit.intellij.makefile (1.0.15)
    com.github.setial (4.0.2)
    com.alayouni.ansiHighlight (1.2.4)
    GsonOrXmlFormat (2.0)
    GLSL (1.19)
    com.mistamek.drawablepreview.drawable-preview (1.1.5)
    com.layernet.plugin.adbwifi (1.0.5)
    com.likfe.ideaplugin.eventbus3 (2020.0.2)

gradle-wrapper.properties

#Tue Apr 25 13:34:44 CST 2023
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

build.gradle(:Project)

  1. // Top-level build file where you can add configuration options common to all sub-projects/modules.
  2. plugins {
  3.     id 'com.android.application' version '7.3.1' apply false
  4.     id 'com.android.library' version '7.3.1' apply false
  5.     id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
  6. }

setting.gradle

  1. pluginManagement {
  2. repositories {
  3. google()
  4. mavenCentral()
  5. gradlePluginPortal()
  6. maven { url 'https://jitpack.io' }
  7. }
  8. }
  9. dependencyResolutionManagement {
  10. repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  11. repositories {
  12. google()
  13. mavenCentral()
  14. gradlePluginPortal()
  15. maven { url 'https://jitpack.io' }
  16. }
  17. }
  18. rootProject.name = "logindemo"
  19. include ':app'

build.gralde(:app)

  1. plugins {
  2. id 'com.android.application'
  3. id 'org.jetbrains.kotlin.android'
  4. }
  5. android {
  6. namespace 'com.example.logindemo'
  7. compileSdk 33
  8. defaultConfig {
  9. applicationId "com.example.logindemo"
  10. minSdk 26
  11. targetSdk 33
  12. versionCode 1
  13. versionName "1.0"
  14. testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  15. }
  16. buildTypes {
  17. release {
  18. minifyEnabled false
  19. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  20. }
  21. }
  22. compileOptions {
  23. sourceCompatibility JavaVersion.VERSION_11
  24. targetCompatibility JavaVersion.VERSION_11
  25. }
  26. kotlinOptions {
  27. jvmTarget = '1.8'
  28. }
  29. }
  30. dependencies {
  31. implementation 'androidx.core:core-ktx:1.7.0'
  32. implementation 'androidx.appcompat:appcompat:1.6.1'
  33. implementation 'com.google.android.material:material:1.8.0'
  34. implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
  35. testImplementation 'junit:junit:4.13.2'
  36. androidTestImplementation 'androidx.test.ext:junit:1.1.3'
  37. androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
  38. // 沉浸式状态栏 https://github.com/gyf-dev/ImmersionBar
  39. api 'com.gyf.immersionbar:immersionbar:3.0.0'
  40. api 'com.gyf.immersionbar:immersionbar-components:3.0.0' // fragment快速实现(可选)
  41. api 'com.gyf.immersionbar:immersionbar-ktx:3.0.0' // kotlin扩展(可选)
  42. }

对Kotlin语言有基本了解

内容在前一篇博客中写了基础配置,如果本篇内容看不懂,可以先去上一篇。

增加title

 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:fitsSystemWindows="true"
  8. tools:context=".MainActivity">
  9. <TextView
  10. android:id="@+id/titleTv"
  11. android:layout_width="match_parent"
  12. android:layout_height="50dp"
  13. android:text="微信"
  14. android:textColor="#000000"
  15. android:textSize="20sp"
  16. android:gravity="center"
  17. android:background="@color/title"
  18. app:layout_constraintTop_toTopOf="parent"/>
  19. <com.google.android.material.tabs.TabLayout
  20. android:id="@+id/tabLayout"
  21. android:layout_width="match_parent"
  22. android:layout_height="wrap_content"
  23. app:layout_constraintBottom_toBottomOf="parent"
  24. app:tabIndicatorColor="@color/teal_200"
  25. app:tabSelectedTextColor="@color/teal_200"
  26. app:tabTextColor="@color/black" />
  27. <androidx.viewpager.widget.ViewPager
  28. android:id="@+id/viewPager"
  29. android:layout_width="match_parent"
  30. android:layout_height="0dp"
  31. app:layout_constraintTop_toBottomOf="@+id/titleTv"
  32. app:layout_constraintBottom_toTopOf="@+id/tabLayout"/>
  33. </androidx.constraintlayout.widget.ConstraintLayout>

增加了title之后,在切换fragment时,需要对应的title文字变化

  1. package com.example.logindemo
  2. import android.os.Bundle
  3. import android.widget.TextView
  4. import androidx.appcompat.app.AppCompatActivity
  5. import androidx.fragment.app.Fragment
  6. import androidx.fragment.app.FragmentPagerAdapter
  7. import androidx.viewpager.widget.ViewPager
  8. import com.example.logindemo.fragment.ChatFragment
  9. import com.example.logindemo.fragment.ContactsFragment
  10. import com.example.logindemo.fragment.DiscoverFragment
  11. import com.google.android.material.tabs.TabLayout
  12. import com.gyf.immersionbar.ImmersionBar
  13. class MainActivity : AppCompatActivity() {
  14. private lateinit var viewPager: ViewPager
  15. private lateinit var tabLayout: TabLayout
  16. private lateinit var titleTv: TextView
  17. override fun onCreate(savedInstanceState: Bundle?) {
  18. super.onCreate(savedInstanceState)
  19. ImmersionBar.with(this)
  20. .statusBarDarkFont(true)
  21. .statusBarColor(R.color.title)
  22. .navigationBarColor(R.color.white)
  23. .navigationBarDarkIcon(true)
  24. .init()
  25. setContentView(R.layout.activity_main)
  26. val fragments = listOf(
  27. ChatFragment(),
  28. ContactsFragment(),
  29. DiscoverFragment()
  30. )
  31. titleTv = findViewById(R.id.titleTv)
  32. viewPager = findViewById(R.id.viewPager)
  33. tabLayout = findViewById(R.id.tabLayout)
  34. viewPager.adapter = ViewPagerAdapter(supportFragmentManager, fragments)
  35. tabLayout.setupWithViewPager(viewPager)
  36. tabLayout.getTabAt(0)?.text = "聊天"
  37. tabLayout.getTabAt(1)?.text = "联系人"
  38. tabLayout.getTabAt(2)?.text = "发现"
  39. tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
  40. override fun onTabSelected(tab: TabLayout.Tab?) {
  41. titleTv.text = tab?.text
  42. }
  43. override fun onTabUnselected(tab: TabLayout.Tab?) {
  44. }
  45. override fun onTabReselected(tab: TabLayout.Tab?) {
  46. }
  47. })
  48. }
  49. class ViewPagerAdapter(
  50. fragmentManager: androidx.fragment.app.FragmentManager,
  51. private val fragments: List<Fragment>
  52. ) : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
  53. override fun getItem(position: Int): Fragment {
  54. return fragments[position]
  55. }
  56. override fun getCount(): Int {
  57. return fragments.size
  58. }
  59. }
  60. }

修改fragment

布局中增加了RecyclerView显示多条目

fragment_chat.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <androidx.recyclerview.widget.RecyclerView
  6. android:id="@+id/recyclerView"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"/>
  9. </androidx.constraintlayout.widget.ConstraintLayout>

fragment_contacts.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <androidx.recyclerview.widget.RecyclerView
  6. android:id="@+id/recyclerView"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"/>
  9. </androidx.constraintlayout.widget.ConstraintLayout>

fragment_discover.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <androidx.recyclerview.widget.RecyclerView
  6. android:id="@+id/recyclerView"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"/>
  9. </androidx.constraintlayout.widget.ConstraintLayout>

fragment中的内容增加如下

  1. package com.example.logindemo.fragment
  2. import android.os.Bundle
  3. import android.view.LayoutInflater
  4. import android.view.View
  5. import android.view.ViewGroup
  6. import androidx.fragment.app.Fragment
  7. import androidx.recyclerview.widget.LinearLayoutManager
  8. import androidx.recyclerview.widget.RecyclerView
  9. import com.example.logindemo.R
  10. import com.example.logindemo.base.BaseAdapter
  11. import com.example.logindemo.bean.ChatBean
  12. class ChatFragment : Fragment() {
  13. private lateinit var recyclerView: RecyclerView
  14. override fun onCreateView(
  15. inflater: LayoutInflater, container: ViewGroup?,
  16. savedInstanceState: Bundle?
  17. ): View? {
  18. val view = inflater.inflate(R.layout.fragment_chat, container, false)
  19. recyclerView = view.findViewById(R.id.recyclerView)
  20. val data = ArrayList<ChatBean>()
  21. data.add(ChatBean("头像0", "用户0", "聊天记录0", "4月25日"))
  22. data.add(ChatBean("头像1", "用户1", "聊天记录1", "4月24日"))
  23. data.add(ChatBean("头像2", "用户2", "聊天记录2", "4月23日"))
  24. data.add(ChatBean("头像3", "用户3", "聊天记录3", "4月22日"))
  25. data.add(ChatBean("头像4", "用户4", "聊天记录4", "4月21日"))
  26. data.add(ChatBean("头像5", "用户5", "聊天记录5", "4月20日"))
  27. data.add(ChatBean("头像6", "用户6", "聊天记录6", "4月19日"))
  28. data.add(ChatBean("头像7", "用户7", "聊天记录7", "4月18日"))
  29. data.add(ChatBean("头像8", "用户8", "聊天记录8", "4月17日"))
  30. data.add(ChatBean("头像9", "用户9", "聊天记录9", "4月16日"))
  31. recyclerView.layoutManager = LinearLayoutManager(context)
  32. recyclerView.adapter = BaseAdapter(data)
  33. return view
  34. }
  35. }
  1. package com.example.logindemo.fragment
  2. import android.os.Bundle
  3. import android.view.LayoutInflater
  4. import android.view.View
  5. import android.view.ViewGroup
  6. import androidx.fragment.app.Fragment
  7. import androidx.recyclerview.widget.LinearLayoutManager
  8. import androidx.recyclerview.widget.RecyclerView
  9. import com.example.logindemo.R
  10. import com.example.logindemo.base.BaseAdapter
  11. import com.example.logindemo.bean.ChatBean
  12. class ContactsFragment : Fragment() {
  13. private lateinit var recyclerView: RecyclerView
  14. override fun onCreateView(
  15. inflater: LayoutInflater, container: ViewGroup?,
  16. savedInstanceState: Bundle?
  17. ): View? {
  18. val view = inflater.inflate(R.layout.fragment_contacts, container, false)
  19. recyclerView = view.findViewById(R.id.recyclerView)
  20. val data = ArrayList<ChatBean>()
  21. data.add(ChatBean("头像0", "用户0", "", ""))
  22. data.add(ChatBean("头像1", "用户1", "", ""))
  23. data.add(ChatBean("头像2", "用户2", "", ""))
  24. data.add(ChatBean("头像3", "用户3", "", ""))
  25. data.add(ChatBean("头像4", "用户4", "", ""))
  26. data.add(ChatBean("头像5", "用户5", "", ""))
  27. data.add(ChatBean("头像6", "用户6", "", ""))
  28. data.add(ChatBean("头像7", "用户7", "", ""))
  29. data.add(ChatBean("头像8", "用户8", "", ""))
  30. data.add(ChatBean("头像9", "用户9", "", ""))
  31. recyclerView.layoutManager = LinearLayoutManager(context)
  32. recyclerView.adapter = BaseAdapter(data)
  33. return view
  34. }
  35. }
  1. package com.example.logindemo.fragment
  2. import android.os.Bundle
  3. import android.view.LayoutInflater
  4. import android.view.View
  5. import android.view.ViewGroup
  6. import androidx.fragment.app.Fragment
  7. import androidx.recyclerview.widget.LinearLayoutManager
  8. import androidx.recyclerview.widget.RecyclerView
  9. import com.example.logindemo.R
  10. import com.example.logindemo.base.BaseAdapter
  11. import com.example.logindemo.bean.ChatBean
  12. class DiscoverFragment : Fragment() {
  13. private lateinit var recyclerView: RecyclerView
  14. override fun onCreateView(
  15. inflater: LayoutInflater, container: ViewGroup?,
  16. savedInstanceState: Bundle?
  17. ): View? {
  18. val view = inflater.inflate(R.layout.fragment_discover, container, false)
  19. recyclerView = view.findViewById(R.id.recyclerView)
  20. val data = ArrayList<ChatBean>()
  21. data.add(ChatBean("头像0", "朋友圈", "", ""))
  22. data.add(ChatBean("头像1", "视频号", "", ""))
  23. data.add(ChatBean("头像2", "直播", "", ""))
  24. data.add(ChatBean("头像2", "扫一扫", "", ""))
  25. data.add(ChatBean("头像2", "摇一摇", "", ""))
  26. data.add(ChatBean("头像2", "看一看", "", ""))
  27. data.add(ChatBean("头像2", "搜一搜", "", ""))
  28. data.add(ChatBean("头像2", "附近", "", ""))
  29. data.add(ChatBean("头像2", "购物", "", ""))
  30. data.add(ChatBean("头像2", "游戏", "", ""))
  31. data.add(ChatBean("头像2", "小程序", "", ""))
  32. recyclerView.layoutManager = LinearLayoutManager(context)
  33. recyclerView.adapter = BaseAdapter(data)
  34. return view
  35. }
  36. }

条目适配器

  1. package com.example.logindemo.base
  2. import android.view.LayoutInflater
  3. import android.view.View
  4. import android.view.ViewGroup
  5. import android.widget.TextView
  6. import androidx.recyclerview.widget.RecyclerView
  7. import com.example.logindemo.R
  8. import com.example.logindemo.bean.ChatBean
  9. class BaseAdapter(private val data: List<ChatBean>) :
  10. RecyclerView.Adapter<BaseAdapter.BaseHolder>() {
  11. override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseHolder {
  12. val view = LayoutInflater.from(parent.context).inflate(R.layout.base_item, null, false);
  13. return BaseHolder(view)
  14. }
  15. override fun getItemCount(): Int {
  16. return data.size
  17. }
  18. override fun onBindViewHolder(holder: BaseHolder, position: Int) {
  19. holder.headTv.visibility = if (data[position].head.isEmpty()) View.GONE else View.VISIBLE
  20. holder.nickTv.visibility = if (data[position].nick.isEmpty()) View.GONE else View.VISIBLE
  21. holder.newestTv.visibility = if (data[position].newest.isEmpty()) View.GONE else View.VISIBLE
  22. holder.dateTv.visibility = if (data[position].date.isEmpty()) View.GONE else View.VISIBLE
  23. holder.headTv.text = data[position].head
  24. holder.nickTv.text = data[position].nick
  25. holder.newestTv.text = data[position].newest
  26. holder.dateTv.text = data[position].date
  27. }
  28. class BaseHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
  29. val headTv: TextView = itemView.findViewById(R.id.headTv)
  30. val nickTv: TextView = itemView.findViewById(R.id.nickTv)
  31. val newestTv: TextView = itemView.findViewById(R.id.newestTv)
  32. val dateTv: TextView = itemView.findViewById(R.id.dateTv)
  33. }
  34. }

数据类型

  1. package com.example.logindemo.bean
  2. data class ChatBean(val head: String, val nick: String, val newest: String, val date: String) {
  3. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/365047
推荐阅读
相关标签
  

闽ICP备14008679号