首页 > 其他分享 >Android 持久化技术

Android 持久化技术

时间:2024-08-03 12:27:18浏览次数:15  
标签:findViewById 持久 val text 技术 id import Android android

目录

1. 用户登陆界面

2. 图书信息数据库和显示界面

3.应用运行功能的截图

4.源码


1. 用户登陆界面

  ( 1 ) 创建一个 LoginActivity ,对应的布局文件 activity_login 。   ( 2 ) 具备两个 TextView 和两个 EditText 控件,分别用于显示和输入用户名和密码。   ( 3 ) 添加 “ 注册 ” 和 “ 登陆 ” 两个按钮( Button )。   ( 4 ) 添加 “ 记住我 ” 功能:插入一个 CheckBox 控件,当用户勾选该勾选框,当点击 “ 登陆 ” 按钮时,判断该勾选框,如果勾选,则把用户名和密码保存起来,要求采用文本存储方式保 存下来。   ( 5 ) 点击 “ 注册 ” ,可以根据用户名和密码对应的 EditText ,将用户名和密码保存起来, 要求采用 SharedPreferences 保存用户名和密码数据,同时需要确保用户名不重复(区分 大小写)。   ( 6 ) 点击 “ 登陆 ” ,通过 SharedPreferences 读取用户密码数据,并进行匹配,只有匹 配成功,才能成功登陆,跳转到 MainActivity (下一个设计内容)

2. 图书信息数据库和显示界面

( 1 ) 需要保存的信息:书本信息(下表左),和书本所属类别(下表右)。每本书有其 所属的类别。

create table Book (
id integer primary key autoincrement,
author text,
price real,
pages integer,
name text

category_id integer

)

create table Category (
id integer primary key autoincrement
category_name text,
category_code integer)

使用 SqlLite 数据库创建数据库 library ,并创建 Book 和 Category 这两个表。往 Category 里插入 2 条默认书类别数据(如:经济类, 1 )。 ( 2 ) 界面设计:         ① 创建一个 MainActivity ,对应的布局为 activity_main 。         ② 添加一个 RecyclerView ,用于显示所有的图书条目信息,每个条目显示书的名字、         作者、类别和价格。         ③ 添加一个 “ 添加书目 ” 的按钮,用于跳转进入 AddBookActivity 。         ④ 在 AddBookActivity 中 , 可 以 添 加 一 本 书 的 信 息 到 数 据 库 中 。 提 示 :         AddBookActivity 需要的组件包括: EditText 、 TextView 、 Button 或 Spinner 。         提醒:可以在 RecyclerView 的适配器里面进行数据库的查询操作。

3.应用运行功能的截图

登录、注册、检查重名、检查账户密码是否正确、密码是否正确、记住密码 登录成功后进入首页面:

4.源码

Book.kt data class Book( val author : String , val price : Double , val pages : Int , val name : String , val categoryId : Int ) Category.kt package com.example.mylibrary data class Category( val id : Int , val categoryName : String , val categoryCode : Int ) LoginActivity.kt package com.example.mylibrary import android.content.Context import android.content.Intent import android.content.SharedPreferences import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.CheckBox import android.widget.EditText import android.widget.Toast class LoginActivity : AppCompatActivity() { private lateinit var usernameEditText : EditText private lateinit var passwordEditText : EditText private lateinit var rememberMeCheckBox : CheckBox private lateinit var sharedPreferences : SharedPreferences override fun onCreate (savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) setContentView(R.layout. activity_login ) usernameEditText = findViewById(R.id. usernameEditText ) passwordEditText = findViewById(R.id. passwordEditText ) rememberMeCheckBox = findViewById(R.id. rememberMeCheckBox ) val loginButton: Button = findViewById(R.id. loginButton ) val registerButton: Button = findViewById(R.id. registerButton ) sharedPreferences = getSharedPreferences( "MyPrefs" , Context. MODE_PRIVATE ) loginButton.setOnClickListener { val username = usernameEditText . text .toString() val password = passwordEditText . text .toString() if (validateLogin(username , password)) { if ( rememberMeCheckBox . isChecked ) { rememberUser(username , password) } val intent = Intent( this @LoginActivity , MainActivity:: class . java ) startActivity(intent) // finish() } else { Toast.makeText( this @LoginActivity , "Invalid username or password" , Toast. LENGTH_SHORT ).show() } } registerButton.setOnClickListener { val username = usernameEditText . text .toString() val password = passwordEditText . text .toString() if (registerUser(username , password)) { Toast.makeText( this @LoginActivity , "Registration successful" , Toast. LENGTH_SHORT ).show() } else { Toast.makeText( this @LoginActivity , "Username already exists" , Toast. LENGTH_SHORT ).show() } } } private fun validateLogin (username: String , password: String): Boolean { val storedPassword = sharedPreferences .getString(username , null ) return storedPassword == password } private fun rememberUser (username: String , password: String) { val editor = sharedPreferences .edit() editor.putString(username , password) editor.apply() } private fun registerUser (username: String , password: String): Boolean { if (! sharedPreferences .contains(username)) { val editor = sharedPreferences .edit() editor.putString(username , password) editor.apply() return true } return false } } activity_login.xml <? xml version ="1.0" encoding ="utf-8" ?> <RelativeLayout xmlns: android ="http://schemas.android.com/apk/res/android" android :layout_width ="match_parent" android :layout_height ="match_parent" android :padding ="16dp" > <TextView android :id ="@+id/usernameTextView" android :layout_width ="wrap_content" android :layout_height ="wrap_content" android :text ="Username" android :layout_marginBottom ="8dp" /> <EditText android :id ="@+id/usernameEditText" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :layout_below ="@id/usernameTextView" android :hint ="Enter username" android :padding ="12dp" 10 android :layout_marginBottom ="16dp" /> <TextView android :id ="@+id/passwordTextView" android :layout_width ="wrap_content" android :layout_height ="wrap_content" android :layout_below ="@id/usernameEditText" android :text ="Password" android :layout_marginBottom ="8dp" /> <EditText android :id ="@+id/passwordEditText" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :layout_below ="@id/passwordTextView" android :inputType ="textPassword" android :hint ="Enter password" android :padding ="12dp" android :layout_marginBottom ="16dp" /> <CheckBox android :id ="@+id/rememberMeCheckBox" android :layout_width ="wrap_content" android :layout_height ="wrap_content" android :text ="Remember me" android :layout_below ="@id/passwordEditText" android :layout_marginBottom ="16dp" /> <Button android :id ="@+id/loginButton" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :text ="Login" android :layout_below ="@id/rememberMeCheckBox" android :layout_marginBottom ="8dp" /> <Button android :id ="@+id/registerButton" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :text ="Register" android :layout_below ="@id/loginButton" /> </RelativeLayout> MainActivity.kt package com.example.mylibrary import android.content.Intent import android.os.Bundle import android.view.View import android.widget.Button import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView class MainActivity : AppCompatActivity() { private lateinit var recyclerView : RecyclerView private lateinit var bookAdapter : BookAdapter private lateinit var emptyView : TextView override fun onCreate (savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) setContentView(R.layout. activity_main ) recyclerView = findViewById(R.id. recyclerView ) recyclerView . layoutManager = LinearLayoutManager( this ) bookAdapter = BookAdapter(getAllBooksFromDatabase()) recyclerView . adapter = bookAdapter checkEmptyViewVisibility() // val dbHelper = DatabaseHelper(this, "BookStore.db", 2) // val createDatabase = findViewById<Button>(R.id.createDatabase) // createDatabase.setOnClickListener { // dbHelper.writableDatabase // } val addData = findViewById<Button>(R.id. addData ) addData.setOnClickListener { val intent = Intent( this @MainActivity , AddBookActivity:: class . java ) startActivity(intent) } } private fun getAllBooksFromDatabase (): List<Book> { val dbHelper = DatabaseHelper( this, "BookStore.db" , 2 ) val db = dbHelper. readableDatabase val query = "SELECT * FROM Book" val cursor = db.rawQuery(query , null ) val books = mutableListOf <Book>() while (cursor.moveToNext()) { val nameIndex = cursor.getColumnIndex( "name" ) val authorIndex = cursor.getColumnIndex( "author" ) val priceIndex = cursor.getColumnIndex( "price" ) val categoryIdIndex = cursor.getColumnIndex( "categoryId" ) val name: String? = cursor.getString(nameIndex) val author: String? = cursor.getString(authorIndex) val price: Double = cursor.getDouble(priceIndex) val categoryId: Int = cursor.getInt(categoryIdIndex) // 使用空字符串作为默认值 val book = Book(author ?: "" , price , 0 , name ?: "" , categoryId) books.add(book) } cursor.close() return books } private fun checkEmptyViewVisibility () { emptyView = findViewById(R.id. emptyTextView ) if ( bookAdapter . itemCount == 0 ) { emptyView . visibility = View. VISIBLE } else { emptyView . visibility = View. GONE } } } activity_main.xml <? xml version ="1.0" encoding ="utf-8" ?> <LinearLayout xmlns: android ="http://schemas.android.com/apk/res/android" android :orientation ="vertical" android :layout_width ="match_parent" android :layout_height ="match_parent" > <androidx.recyclerview.widget.RecyclerView android :id ="@+id/recyclerView" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :layout_weight ="1" android :scrollbars ="vertical" /> <TextView android :id ="@+id/emptyTextView" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :gravity ="center" android :visibility ="gone" android :text ="No books available" android :textSize ="20sp" /> <!-- <Button--> <!-- android:id="@+id/createDatabase"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="wrap_content"--> <!-- android:text="Create Database" />--> <Button android :id ="@+id/addData" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :text ="Add Book" /> <!-- <TextView--> <!-- android:id="@+id/androidTextView"--> <!-- android:layout_width="wrap_content"--> <!-- android:layout_height="wrap_content"--> <!-- android:text="Android Text" />--> <!-- <Button--> <!-- android:id="@+id/updateData"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="wrap_content"--> <!-- android:text="Update Data" />--> <!-- <Button--> <!-- android:id="@+id/deleteData"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="wrap_content"--> <!-- android:text="Delete Data" />--> <!-- <Button--> 15 <!-- android:id="@+id/queryData"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="wrap_content"--> <!-- android:text="Query Data"/>--> </LinearLayout> DataBaseHelper.kt package com.example.mylibrary import android.content.ContentValues import android.content.Context import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper import android.widget.Toast class DatabaseHelper(context: Context , name: String , version: Int) : SQLiteOpenHelper(context , name , null, version) { private val createBook = "create table Book (" + "id integer primary key autoincrement," + "author text," + "price real," + "pages integer," + "name text," + "categoryId integer)" private val createCategory = "create table Category (" + "id integer primary key autoincrement," + "category_name text," + "category_code integer)" override fun onCreate (db: SQLiteDatabase) { db.execSQL( createBook ) db.execSQL( createCategory ) // Toast.makeText(this@DatabaseHelper, "Tables created successfully", Toast.LENGTH_SHORT).show() // 插入经济类别记录 val contentValues = ContentValues(). apply { put( "category_name" , " 经济类 " ) put( "category_code" , 1 ) } 16 db.insert( "Category" , null, contentValues) } override fun onUpgrade (db: SQLiteDatabase , oldVersion: Int , newVersion: Int) { db.execSQL( "DROP TABLE IF EXISTS Book" ) db.execSQL( "DROP TABLE IF EXISTS Category" ) onCreate(db) } } AddBookActivity.kt package com.example.mylibrary import android.content.ContentValues import android.content.Intent import android.os.Bundle import android.widget.Button import android.widget.EditText import android.widget.Toast import androidx.appcompat.app.AppCompatActivity class AddBookActivity : AppCompatActivity() { // private lateinit var dbHelper: DatabaseHelper override fun onCreate (savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) setContentView(R.layout. activity_add_book ) // dbHelper = DatabaseHelper(this) val dbHelper =DatabaseHelper( this, "BookStore.db" , 2 ) val addBookButton: Button = findViewById(R.id. addBookButton ) addBookButton.setOnClickListener { val nameEditText: EditText = findViewById(R.id. nameEditText ) val authorEditText: EditText = findViewById(R.id. authorEditText ) // val category: EditText = findViewById(R.id.categoryIdEditText) val priceEditText: EditText = findViewById(R.id. priceEditText ) val categoryIdEditText: EditText = findViewById(R.id. categoryIdEditText ) val name = nameEditText. text .toString() val author = authorEditText. text .toString() 17 // val pages = pagesEditText.text.toString().toIntOrNull() ?: 0 // 处理无效输入 val price = priceEditText. text .toString(). toDoubleOrNull () ?: 0.0 // 处理无效输入 val categoryId = categoryIdEditText. text .toString(). toIntOrNull () ?: 0 // 处理无效输入 val db = dbHelper. writableDatabase val values = ContentValues(). apply { put( "name" , name) put( "author" , author) put( "categoryId" , categoryId) put( "price" , price) // put("categoryId", categoryId) } val newRowId = db.insert( "Book" , null, values) if (newRowId == - 1L ) { // 插入失败 Toast.makeText( this, " 添加书籍到数据库失败 " , Toast. LENGTH_SHORT ).show() } else { // 插入成功 Toast.makeText( this, " 书籍已添加到数据库 " , Toast. LENGTH_SHORT ).show() } // 清空输入框 nameEditText. text .clear() authorEditText. text .clear() categoryIdEditText. text .clear() priceEditText. text .clear() // categoryIdEditText.text.clear() val intent = Intent( this @AddBookActivity , MainActivity:: class . java ) startActivity(intent) // finish(); } } } activity_add_book.xml <? xml version ="1.0" encoding ="utf-8" ?> <RelativeLayout xmlns: android ="http://schemas.android.com/apk/res/android" android :layout_width ="match_parent" android :layout_height ="match_parent" android :padding ="16dp" > <EditText android :id ="@+id/authorEditText" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :hint ="Author" android :layout_marginBottom ="16dp" android :minWidth ="200dp" android :minHeight ="48dp" android :padding ="8dp" /> <EditText android :id ="@+id/priceEditText" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :inputType ="numberDecimal" android :hint ="Price" android :layout_below ="@id/authorEditText" android :layout_marginBottom ="16dp" android :minWidth ="200dp" android :minHeight ="48dp" android :padding ="8dp" /> <EditText android :id ="@+id/pagesEditText" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :inputType ="number" android :hint ="Pages" android :layout_below ="@id/priceEditText" android :layout_marginBottom ="16dp" android :minWidth ="200dp" android :minHeight ="48dp" android :padding ="8dp" /> <EditText android :id ="@+id/nameEditText" android :layout_width ="match_parent" android :layout_height ="wrap_content" 18 android :hint ="Name" android :layout_below ="@id/pagesEditText" android :layout_marginBottom ="16dp" android :minWidth ="200dp" android :minHeight ="48dp" android :padding ="8dp" /> <EditText android :id ="@+id/categoryIdEditText" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :inputType ="number" android :hint ="Category ID" android :layout_below ="@id/nameEditText" android :layout_marginBottom ="16dp" android :minWidth ="200dp" android :minHeight ="48dp" android :padding ="8dp" /> <Button android :id ="@+id/addBookButton" android :layout_width ="wrap_content" android :layout_height ="wrap_content" android :text ="Add Book" android :layout_centerInParent ="true" /> <androidx.recyclerview.widget.RecyclerView android :id ="@+id/recyclerView" android :layout_width ="match_parent" android :layout_height ="match_parent" android :layout_above ="@id/addBookButton" android :layout_marginBottom ="16dp" /> </RelativeLayout> BookAdapter.kt // BookAdapter.kt package com.example.mylibrary import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView class BookAdapter( private val bookList : List<Book>) : RecyclerView.Adapter<BookAdapter.BookViewHolder>() { class BookViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val titleTextView : TextView = itemView.findViewById(R.id. textViewTitle ) val authorTextView : TextView = itemView.findViewById(R.id. textViewAuthor ) val categoryTextView : TextView = itemView.findViewById(R.id. textViewCategory ) val priceTextView : TextView = itemView.findViewById(R.id. textViewPrice ) } override fun onCreateViewHolder (parent: ViewGroup , viewType: Int): BookViewHolder { val itemView = LayoutInflater.from(parent. context ) .inflate(R.layout. item_book , parent , false ) return BookViewHolder(itemView) } override fun onBindViewHolder (holder: BookViewHolder , position: Int) { val currentItem = bookList [position] holder. titleTextView . text = currentItem. name holder. authorTextView . text = currentItem. author holder. categoryTextView . text = currentItem. categoryId .toString() holder. priceTextView . text = currentItem. price .toString() } override fun getItemCount () = bookList . size } item_book,xml <? xml version ="1.0" encoding ="utf-8" ?> <LinearLayout xmlns: android ="http://schemas.android.com/apk/res/android" android :layout_width ="match_parent" android :layout_height ="wrap_content" android :orientation ="vertical" > <TextView android :id ="@+id/textViewTitle" android :layout_width ="wrap_content" android :layout_height ="wrap_content" android :textSize ="18sp" android :textStyle ="bold" android :text ="Title" /> <TextView android :id ="@+id/textViewAuthor" android :layout_width ="wrap_content" android :layout_height ="wrap_content" android :textSize ="16sp" android :text ="Author" /> <TextView android :id ="@+id/textViewCategory" android :layout_width ="wrap_content" android :layout_height ="wrap_content" android :textSize ="14sp" android :text ="Category" /> <TextView android :id ="@+id/textViewPrice" android :layout_width ="wrap_content" android :layout_height ="wrap_content" android :textSize ="14sp" android :text ="Price" /> </LinearLayout>

标签:findViewById,持久,val,text,技术,id,import,Android,android
From: https://blog.csdn.net/2201_75709573/article/details/140880339

相关文章

  • 模型量化技术综述:揭示大型语言模型压缩的前沿技术
    大型语言模型(LLMs)通常因为体积过大而无法在消费级硬件上运行。这些模型可能包含数十亿个参数,通常需要配备大量显存的GPU来加速推理过程。因此越来越多的研究致力于通过改进训练、使用适配器等方法来缩小这些模型的体积。在这一领域中,一个主要的技术被称为量化。在这篇文章中,我......
  • 通用测试技术5
    一、缺陷的基本概述缺陷的定义缺陷的属性缺陷类型:缺陷的类型包括功能(Function)、界面(UI)、文档(Documentation)、软件包(Package)、性能(Performance)、接口(Interface)[注意]需求分析、设计阶段,文档类型的缺陷多;集成测试阶段,一般接口类型的缺陷多一些;系统测试阶......
  • 关于技术资产建设
    目录现象“技术资产”的概念“技术资产”的意义效率质量成本“技术资产”的建设二方库建设二方库的概念二方库的开发原则与思路技术底座建技术底座建设原则技术底座的必要性“技术资产”的演进思路现象先说一个经典案例:程序员小a长期在A项目进行开发编码工......
  • 技术资产建设
    一个案例先说一个经典案例:程序员小a长期在A项目进行开发编码工作,突然同部门下的B项目紧急缺人,小A被调到B项目进行开发,小a在看过多轮“五花八门”的项目文档之后,终于打开了idea,结果发现pom文件一堆爆红,排查后发现是自己本地的配置的A项目组内网远程仓地址缺少很多B项目代码的依赖,......
  • 我的新书《Android系统多媒体进阶实战》正式发售了!!!
    我的新书要正式发售了,把链接贴在下面,感兴趣的朋友可以支持下。❶发售平台:当当,京东,抖音北航社平台,小红书,b站❷目前当当和京东已开启预售❸当当网https://u.dangdang.com/KIDHJ❹京东商城https://item.m.jd.com/product/10109083199634.html?gx=RnAoqRAjajbdh8lR5Q&gxd......
  • 159.336 application for Android
    159.336Assignment1Due14thAugust2024ForthisassignmentyouneedtowriteasimpledialerapplicationforAndroidtomakephonecalls.ThedialermusthavethefollowingUIelements:Anumberdisplaytoshowthephonenumberwhichwillbecalled.A......
  • Query Rewriting 优化技术
    在检索增强生成(RetrievalAugmentedGeneration,RAG)系统中,经常会出现与 user’soriginalqueries(译者注:用户最开始输入的搜索问题或者其他需求。)有关的问题(例如,词汇不准确或缺乏语义信息),导致 RAG 系统难以理解。比如像 “2020 年 NBA 冠军是洛杉矶湖人队!请告诉我 langc......
  • (计算机三级网络)网络管理技术<总结>
    能用作安全评估的工具:ISS、MBSA、X-ScannerSQL注入伤害利用主机应用系统漏洞进行攻击ICMP报文类型值为3时表示目标不可达在Cisco路由器上进行SNMP设置时,如果团体名为admin,访问权限为只读,那么正确的配置语句是5.通过伪造某台主机的IP地址窃取特权的攻击方式属于协议欺骗攻击......
  • android12编译三方提供的bin文件,通过selinux配置并实现rc开机启动
    为三方bin建立工程在vendor/自己公司目录下建立工程文件夹,我这里以CarpalyMonter工程,新建如下文件CarplayMonitor为三方bin文件Android.mk模块编译配置如下:LOCAL_PATH:=$(callmy-dir)include$(CLEAR_VARS)LOCAL_MODULE:=carplaymonitor #模块名字LOCAL_SRC......
  • 【攻防技术系列+SQL注入】mysql靶场
    墨者靶场(SQL手工注入漏洞测试(MySQL数据库))工具dirsearchsqlmappythondirsearch.py-uhttp://<IP>:<端口>/在登录界面,没有账户和密码,也进不去,就在没啥收获的时候,直觉告诉我要打开F12开发者模式,这次信它,就在东点点西点点的时候,我发现了什么。如果遇到扫描漏网之鱼......