【Kotlin-JetPack】融合组件(登录注册,bottombar)

全体包

 implementation 'io.supercharge:shimmerlayout:2.1.0'
    implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0'
    implementation 'androidx.navigation:navigation-ui-ktx:2.1.0'
    //添加anko库
    implementation 'org.jetbrains.anko:anko:0.10.8'
    //添加ButtonBar组件
    implementation 'com.roughike:bottom-bar:2.3.1'

    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-beta01'

    def room_version = "2.2.5"

    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"

    // optional - Kotlin Extensions and Coroutines support for Room
    implementation "androidx.room:room-ktx:$room_version"

    // optional - Test helpers
    testImplementation "androidx.room:room-testing:$room_version"

    implementation 'com.roughike:bottom-bar:2.3.1'
    implementation 'androidx.fragment:fragment-ktx:1.2.2'
    implementation 'com.github.bumptech.glide:glide:4.10.0'

1. 登录模块

1.界面绘制,圆角和方块弧通过drawable控制shape绘制,背景图来自Iphone壁纸

  1. 假定默认登录注册密码为root 12345
    在这里插入图片描述

2. Room初始三件套(实体类,Dao层,DataBase库)

  1. 实体类(只有主键可设定自增,一般登录注册是从网上接口拿数据的)
@Entity//Room表示创建实体类
class User(account: Long, psd: String) {
    
    

    @PrimaryKey
    var account: Long = account

    @ColumnInfo(name = "password")
    var psd: String = psd
    
}
  1. Dao层
@Dao //Database access object
interface UserDao {
    
    

    @Insert
    fun insertUsers(vararg users: User?)

    @Update//返回修改的记录条数
    fun updateUsers(vararg users: User?) //通过id进行替换内容

    @Delete
    fun deleteUsers(vararg users: User?)

    @Query("DELETE FROM User")//删除所有内容
    fun deleteAllUsers();

    @Query("SELECT * FROM User ")//降序查询
    fun getAllUsers():List<User>

    @Query("SELECT * FROM User WHERE account In(:account)")//查询账号是否存在
    fun getUser(account:Long):LiveData<User>

    @Query("SELECT * FROM User ")
    fun getAllWordsLive():LiveData<List<User>>
}
  1. Database控制
@Database(entities = [User::class],version = 2,exportSchema = false)
 abstract class UserDatabase: RoomDatabase() {
    
    
    //若有多个entities则返回多个Dao

    companion object {
    
    
        var INSTANCE: UserDatabase? = null

        @Synchronized//如果有多个客户端  且同时instance时保证不会有碰撞 只有一个instance生成
        open fun getDatabase(context: Context): UserDatabase? {
    
    //静态类的静态方法写open
            if (INSTANCE == null) {
    
    
                INSTANCE = Room.databaseBuilder(context.applicationContext, UserDatabase::class.java, "user_database")
                    .fallbackToDestructiveMigration()
                    //.allowMainThreadQueries()//先允许主线程运行
                    //.addMigrations(MIGRATION_6_7)
                    .build()
            }
            return INSTANCE
        }
    }

    abstract fun getUserDao(): UserDao
}
  1. 导入自己喜欢的BaseActivity包,目前userdatabase对象和userdao只是为了登录注册服务的,以后可以尝试一下范型。并且单是抽取积累的话登录注册基类+封装也挺好的看个人需求。

//所有Activity基类
abstract class BaseActivity: AppCompatActivity(), AnkoLogger {
    
    
    private var userdatabase: UserDatabase?=null
    lateinit var userdao: UserDao

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(getLayoutid())//基类抽取界面组
        initListener()//子类中并非一定要实现,创建一个function即可
        initDate()//数据支持
    }
    //    初始化数据,非私有加入open关键字才能复写
    open protected fun initDate() {
    
    
        userdatabase=UserDatabase.getDatabase(applicationContext)!!
        userdao=userdatabase?.getUserDao()!!
    }

    //    adapter listener
    open protected fun initListener(){
    
    }

    //创建抽象类以供获取Layout,abstract不用加
    abstract fun getLayoutid():Int

    //在基类线中弹toast解决线的问题   1?
    protected fun myToast(msg:String){
    
    
        runOnUiThread{
    
    toast(msg)}
    }

    //开启activity并且finish当前界面,添加内联支持inline 与reified
    //进入看发现限制是Activity或Activity子类  reified用于找到传入泛型具体的类 下面内部就可以获取Tclass名(所以直接传泛型无法获取名称)
   inline  fun <reified T:BaseActivity>startActivityAndFinish(){
    
    
        startActivity<T>()
        finish()
    }
}
  1. 具体登录代码,用onclick绑定界面,写监听怪麻烦的,以后用databind时改也方便。

class LoginActivity : BaseActivity() {
    
    
    lateinit var  userviewModel:FindUserModel
    var loginFlag:Boolean=false
    override fun getLayoutid(): Int {
    
    
        return R.layout.activity_login
    }

    override fun initDate() {
    
    
        super.initDate()
        userviewModel = ViewModelProvider(this).get(FindUserModel::class.java)
    }


    fun LoginUser(v:View) {
    
    
        loginFlag=true
        var textcount = Account_text.text.toString()
        var textpws = Password_text.text.toString()


        if (textcount.isEmpty()) {
    
    
            myToast("请输入用户名")
        }
        if (textpws.isEmpty()) {
    
    
            myToast("请输入密码")
        }

        if (!textcount.isEmpty() && !textpws.isEmpty()) {
    
    
            userviewModel.findUser = userdao.getUser(textcount.toLong())



            userviewModel.findUser?.let {
    
    
                userviewModel.findUser!!.observe(this, Observer {
    
    
                    if (loginFlag==true){
    
    
                        if ((it!=null)){
    
    
                            if (  it.psd.equals(textpws)) {
    
    
                                myToast("登录成功")
                                startActivityAndFinish<MainActivity>()
                            } else {
    
    
                                myToast("账号或密码错误")
                            }
                        }else{
    
    
                            myToast("用户不存在")
                        }
                    }

                })
            }

        }
    }
    

    fun IntoRegist(v:View){
    
    
        startActivity<RegistActivity>()
    }

}

2. 注册模块

1.界面绘制,圆角和方块弧通过drawable控制shape绘制

在这里插入图片描述

  1. 代码

class RegistActivity : BaseActivity() {
    
    

    lateinit var  userviewModel:FindUserModel
    var registFlag:Boolean=false

    override fun getLayoutid(): Int {
    
    
        return R.layout.activity_regist
    }

    override fun initDate() {
    
    
        super.initDate()
        userviewModel = ViewModelProvider(this).get(FindUserModel::class.java)
    }

    fun RegistUser(v: View) {
    
    
        //会自动绑定get方法 插入成功后会自动get 设置个变量
        registFlag=true
        var textcount = Input_account.text.toString()
        var textpws = Input_password.text.toString()
        var textpwsre = Input_passwordreput.text.toString()

        if (textcount.isEmpty())
        {
    
     myToast("请输入用户名") }
        if (textpws.isEmpty())
        {
    
     myToast("请输入密码") }
        if (textpwsre.isEmpty())
        {
    
     myToast("请确认密码") }
        if (!textpwsre.equals(textpws))
        {
    
     myToast("两次密码输入不一致") }


        if (!textcount.isEmpty() && !textpws.isEmpty() && !textpwsre.isEmpty() && textpwsre.equals(textpws)) {
    
    
            userviewModel.findUser = userdao.getUser(textcount.toLong())


            userviewModel.findUser?.let {
    
    
                userviewModel.findUser!!.observe(this, Observer {
    
    
                    if (registFlag==true){
    
    
                        if ((it!=null)){
    
    
                            Input_account.text.clear()
                            myToast("账户已存在")
                        }else{
    
    
                            registFlag=false
                            var user = User(textcount.toLong(), textpws)
                            InsertAsyncTask(userdao).execute(user)
                            //增设查询该条记录
                            myToast("插入成功")
                            Handler().postDelayed(Runnable {
    
     startActivityAndFinish<LoginActivity>() }, 1000)
                        }
                    }

                })
            }


        }

    }

    internal class InsertAsyncTask(private val userdao: UserDao) : AsyncTask<User?, Unit, Unit>() {
    
    
        //在后台工作
        override fun doInBackground(vararg params: User?) {
    
    
            publishProgress()//该方法用于一段时间报告工作进度
            userdao.insertUsers(*params)
        }
    }
}



3.FragmentUtil控制首页与bottombar切换

1. 在fragment中获取AC和对应Context方式,

在这里插入图片描述

2. 建立App类,用于处理主线程回调,并且声明

  1. android:name ,它是用来app启动时来关联一个application的,默认关联的是android.app.Application,当app启动时,会默认创建一个application的实例 ,当在Activity中调用getApplication()方法时 ,就会返回这个实例,所以这个android:name 指定的类就有点似于全局变量的作用吧 , 用来存储数据供给整个 Activity 使用
class App: Application() {
    
    

    companion object{
    
    
        val handler= Handler()//主线程静态handler
    }

    override fun onCreate() {
    
    
        super.onCreate()
    }
}

  1. 样例
    在这里插入图片描述

4. 建立对应的货物三件套

1. 三件套

在这里插入图片描述

2.货物实体类

@Entity
class Goods(
    goodscode: Int, goodsname: String, goodssort: String, goodsprice: Int,
    goodspricecount: Float, goodssum: Int, goodsstate: Boolean, goodsimageuri: String?
)  {
    
    
    @PrimaryKey(autoGenerate = true)
    var id = 0

    @ColumnInfo(name = "goods_code")
    var goodscode: Int = goodscode
    @ColumnInfo(name = "goods_name")
    var goodsname: String = goodsname
    @ColumnInfo(name = "goods_sort")
    var goodssort: String = goodssort
    @ColumnInfo(name = "goods_price")
    var goodsprice: Int = goodsprice
    @ColumnInfo(name = "goods_count")
    var goodspricecount: Float = goodspricecount//折扣 0.23
    @ColumnInfo(name = "goods_sum")
    var goodssum: Int = goodssum
    //控制上架下架
    @ColumnInfo(name = "goods_state")
    var goodsstate: Boolean = goodsstate
    @ColumnInfo(name = "goods_imageuri")
    var goodsimageuri:String?=goodsimageuri
}

2.BaseFragment中初始化dao和database,来到主fragment,点击插入,搞定。


class HomeFragment: BaseFragment() {
    
    

    override fun initView(): View? {
    
    
        return View.inflate(context, R.layout.fragment_home, null)
    }

    override fun initData() {
    
    
        super.initData()


        Insert_button.setOnClickListener {
    
    
            var goods:Goods = Goods(1,"充电宝","10",100,1.0f,200,true,null)
            var  goods1:Goods = Goods(1,"充电宝","10",100,1.0f,200,true,null)
            goodsdao.insertGoods( goods, goods1)
            updateView();
        }
 /*       Delete_button.setOnClickListener {
            var word:Word = Word("Word","世界")
            word.setId(40)
            worddao.deleteWords(word)
            updateView()
        }*/
        Deleteall_button.setOnClickListener{
    
    
            goodsdao.deleteAllGoods()
            updateView()
        }
/*        Update_button.setOnClickListener {
            var word:Word = Word("Word","世界")
            word.setId(40)
            worddao.updateWords(word)
            updateView()
        }*/

    }

    fun updateView(){
    
    
        var list:List<Goods> =goodsdao.getAllGoods()
        var text=""

        for (i in (0 until list.size)){
    
    
            var goods:Goods =list.get(i)
            text+=""+goods.goodsname+goods.goodsprice;
        }
        Text_goodsname.text=text
    }



}

在这里插入图片描述

3. 迁移,将商品上架放其他位置-第三个,然后首页展示,测试没问题

在这里插入图片描述


class InGoodsFragment: BaseFragment() {
    
    

    var goodsCode: Int?=null
    var goodsname: String?=null
    var goodssort: String?=null
    var goodsprice: Int?=null
    var goodspricecount: Float?=null
    var goodssum: Int?=null
    var goodsstate: Boolean=true
    var goodsimageuristring: String?=null
    var goodsimageuri: Uri?=null

    companion object {
    
    
        val TAKE_PHOTO = 1
        val CHOOSE_PHOTO = 2

    }

    override fun initView(): View? {
    
    
        return View.inflate(context, R.layout.fragment_ingoods, null)
    }

    override fun initListener() {
    
    
        Switch_state.setOnCheckedChangeListener {
    
     buttonView, isChecked ->
            goodsstate=isChecked
        }
        Button_inphoto.setOnClickListener {
    
    
            if (getActivity()?.applicationContext?.let {
    
     it1 -> ContextCompat.checkSelfPermission(it1, Manifest.permission.WRITE_EXTERNAL_STORAGE) } !== PackageManager.PERMISSION_GRANTED) {
    
    
                getActivity()?.let {
    
     it1 -> ActivityCompat.requestPermissions(it1, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1) }
            } else {
    
    
                openAlbum()
            }
        }
        Button_incamera.setOnClickListener {
    
    

            val simpleDateFormat = SimpleDateFormat("yyyy_MM_dd_HH_mm_ss") // HH:mm:ss
            val date = Date(System.currentTimeMillis())
            var changeCode=simpleDateFormat.format(date)
            changeCode=changeCode+".jpg"
            println("1111111111111${
      
      changeCode}")

            // 1. 创建File对象,用于存储拍照后的图片
            val outputImage = File(getActivity()?.externalCacheDir, changeCode)
            println("11111111111"+outputImage)
            try {
    
    
                if (outputImage.exists()) {
    
    
                    outputImage.delete()
                }
                outputImage.createNewFile()
            } catch (e: IOException) {
    
    
                e.printStackTrace()
            }
            if (Build.VERSION.SDK_INT < 24) {
    
    
                goodsimageuri = Uri.fromFile(outputImage)
            } else {
    
    
                goodsimageuri = getActivity()?.applicationContext?.let {
    
     it1 ->
                    FileProvider.getUriForFile(
                        it1,
                        "com.ywjh.cameraalbumtest.fileprovider",
                        outputImage
                    )
                }
            }
            // 启动相机程序
            val intent = Intent("android.media.action.IMAGE_CAPTURE")
            intent.putExtra(MediaStore.EXTRA_OUTPUT, goodsimageuri)

            startActivityForResult(intent, TAKE_PHOTO)

        }



        Button_submitgoods.setOnClickListener {
    
    
            if (In_code.text!=null &&  In_goodsname.text!=null && In_goodssort.text!=null && In_goodsprice!=null
                    && In_goodscount.text!=null && In_goodssum.text!=null && goodsimageuristring!=null){
    
    
                
                goodsCode=In_code.text.toString().toInt()
                goodsname=In_goodsname.text.toString()
                goodssort=In_goodssort.text.toString()
                goodsprice=In_goodsprice.text.toString().toInt()
                goodspricecount=In_goodssort.text.toString().toFloat()
                goodssum=In_goodssum?.text.toString().toInt()
                var goods: Goods = Goods(goodsCode!!,goodsname!!,goodssort!!,goodsprice!!, goodspricecount!!, goodssum!!, goodsstate,goodsimageuristring)
                goodsdao.insertGoods( goods)
            }else{
    
    

   /*             println("1111"+In_code.text!=null)
                println("1112"+ In_goodsname.text!=null)
                println("1113"+In_goodssort.text!=null)
                println("1114"+In_goodsprice==null)
                println("1115"+In_goodscount.text)
                println("1116"+In_goodssum.text)
                println("1117"+goodsimageuristring)*/
                myToast("请补全信息及上传图片")
            }


        }


    }

    override fun initData() {
    
    
        super.initData()
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    
    

        when (requestCode) {
    
    
            TAKE_PHOTO -> if (resultCode == Activity.RESULT_OK) {
    
    
                try {
    
    
                    goodsimageuristring=goodsimageuri.toString()

                    // 将拍摄的照片显示出来
                    val bitmap = BitmapFactory.decodeStream(goodsimageuristring?.let {
    
    
                        getActivity()?.contentResolver?.openInputStream(
                                it.toUri())
                    })

                    imageView.setImageBitmap(bitmap)
                } catch (e: Exception) {
    
    
                    e.printStackTrace()
                }
            }
            CHOOSE_PHOTO -> if (resultCode == Activity.RESULT_OK) {
    
    
                // 判断手机系统版本号
                if (Build.VERSION.SDK_INT >= 19) {
    
    
                    // 4.4及以上系统使用这个方法处理图片
                    if (data != null) {
    
    
                        handleImageOnKitKat(data)
                    }
                } else {
    
    
                    // 4.4以下系统使用这个方法处理图片
                    if (data != null) {
    
    
                        handleImageBeforeKitKat(data)
                    }
                }
            }

        }
    }


    //4.4后 判断封装情况
    @TargetApi(19)
    private fun handleImageOnKitKat(data: Intent) {
    
    
        var imagePath: String? = null
        val uri = data.data
        Log.d("TAG", "handleImageOnKitKat: uri is $uri")
        if (DocumentsContract.isDocumentUri(getActivity(), uri)) {
    
    
            // 如果是document类型的Uri,则通过document id处理
            val docId = DocumentsContract.getDocumentId(uri)
            if ("com.android.providers.media.documents" == uri!!.authority) {
    
    
                val id = docId.split(":".toRegex()).toTypedArray()[1] // 解析出数字格式的id
                val selection = MediaStore.Images.Media._ID + "=" + id
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection)
            } else if ("com.android.providers.downloads.documents" == uri.authority) {
    
    
                val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(docId))
                imagePath = getImagePath(contentUri, null)
            }
        } else if ("content".equals(uri!!.scheme, ignoreCase = true)) {
    
    
            // 如果是content类型的Uri,则使用普通方式处理
            imagePath = getImagePath(uri, null)
        } else if ("file".equals(uri.scheme, ignoreCase = true)) {
    
    
            // 如果是file类型的Uri,直接获取图片路径即可
            imagePath = uri.path
        }
        displayImage(imagePath) // 根据图片路径显示图片
    }

    private fun handleImageBeforeKitKat(data: Intent) {
    
    
        val uri = data.data
        val imagePath = getImagePath(uri, null)
        displayImage(imagePath)
    }

    fun openAlbum() {
    
    
        val intent = Intent("android.intent.action.GET_CONTENT")
        intent.type = "image/*"
        startActivityForResult(intent, CHOOSE_PHOTO) // 打开相册
    }
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    
    
        when (requestCode) {
    
    
            1 -> if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
    
                openAlbum()
            } else {
    
    
                myToast("You denied the permission")

            }

        }
    }
    private fun getImagePath(uri: Uri?, selection: String?): String? {
    
    
        var path: String? = null
        // 通过Uri和selection来获取真实的图片路径
        val cursor = getActivity()?.contentResolver?.query(uri!!, null, selection, null, null)
        if (cursor != null) {
    
    
            if (cursor.moveToFirst()) {
    
    
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
            }
            cursor.close()
        }

        goodsimageuristring=path
        return path

    }

    private fun displayImage(imagePath: String?) {
    
    
        if (imagePath != null) {
    
    
            val bitmap = BitmapFactory.decodeFile(imagePath)
            imageView.setImageBitmap(bitmap)
        } else {
    
    
            myToast("failed to get image")

        }
    }


}

class HomeFragment: BaseFragment() {
    
    

    override fun initView(): View? {
    
    
        return View.inflate(context, R.layout.fragment_home, null)
    }

    override fun initData() {
    
    
        super.initData()


        Insert_button.setOnClickListener {
    
    
            var goods:Goods = Goods(1,"充电宝","10",100,1.0f,200,true,null)
            var  goods1:Goods = Goods(1,"充电宝","10",100,1.0f,200,true,null)
            goodsdao.insertGoods( goods, goods1)
            updateView();
        }
 /*       Delete_button.setOnClickListener {
            var word:Word = Word("Word","世界")
            word.setId(40)
            worddao.deleteWords(word)
            updateView()
        }*/
        Deleteall_button.setOnClickListener{
    
    
            goodsdao.deleteAllGoods()
            updateView()
        }
/*        Update_button.setOnClickListener {
            var word:Word = Word("Word","世界")
            word.setId(40)
            worddao.updateWords(word)
            updateView()
        }*/

    }

    fun updateView(){
    
    
        var list:List<Goods> =goodsdao.getAllGoods()
        var text=""

        for (i in (0 until list.size)){
    
    
            var goods:Goods =list.get(i)
            text+=""+goods.goodsname+goods.goodsprice;
        }
        Text_goodsname.text=text
    }



}

4. 首页进行列表显示

  1. 建立adapter

class GoodsAdapter: ListAdapter<Goods,GoodsAdapter.MyViewHolder>(DIFFCALLBACK)  {
    
    

    class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

    object DIFFCALLBACK : DiffUtil.ItemCallback<Goods>() {
    
    
        override fun areItemsTheSame(oldItem: Goods, newItem: Goods): Boolean {
    
    
            return oldItem === newItem //判断是否为同一个对象 三等于号
        }

        override fun areContentsTheSame(oldItem: Goods, newItem: Goods): Boolean {
    
    
            return oldItem.id == newItem.id//判断内容是否相同

        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
    
    
        //创建holder
        val holder = MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.goods_cell, parent, false))

        return holder
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
    
    
        val photoItem=getItem(position)
        //使用with语句
        with(holder.itemView) {
    
    
            shimmerLayoutCell.apply {
    
    
                setShimmerColor(0x55FFFFFF)
                setShimmerAngle(0)//闪动角度
                startShimmerAnimation()
            }

            textViewUser.text=photoItem.goodsname
            textViewLikes.text="¥${
      
      photoItem.goodsprice}"
            textViewFavorites.text="打折:${
      
      photoItem.goodspricecount}"
            textViewFavorites2.text="存货:${
      
      photoItem.goodssum}"
            textViewFavorites4.text="种别码:${
      
      photoItem.goodscode}"
            textViewFavorites5.text="id:${
      
      photoItem.id}"


        }

        Glide.with(holder.itemView)
            .load(getItem(position).goodsimageuri)//photo对象
            .placeholder(R.drawable.photo_placeholder)
            .listener(object : RequestListener<Drawable> {
    
    
                override fun onResourceReady(
                    resource: Drawable?,
                    model: Any?,
                    target: Target<Drawable>?,
                    dataSource: DataSource?,
                    isFirstResource: Boolean
                ): Boolean {
    
    
                    return false.also {
    
     holder.itemView.shimmerLayoutCell?.stopShimmerAnimation() }//判断空, 图片未加载完全就切走 但listenrer还在监听
                }

                override fun onLoadFailed(
                    e: GlideException?,
                    model: Any?,
                    target: com.bumptech.glide.request.target.Target<Drawable>?,
                    isFirstResource: Boolean
                ): Boolean {
    
    
                    return false//都return false 不然不显图
                }//监听加载完成后停止shimmer
            }
            )
            .into(holder.itemView.imageView)//加载上去
    }


}
  1. 设置数据源

class HomeFragment: BaseFragment() {
    
    

    override fun initView(): View? {
    
    
        return View.inflate(context, R.layout.fragment_home, null)
    }

    override fun initData() {
    
    
        super.initData()

            var list:List<Goods> =goodsdao.getAllGoods()



        val goodsAdapter = GoodsAdapter()
        recycleView.apply{
    
    
            adapter=goodsAdapter
            layoutManager= GridLayoutManager(requireContext(),2)//两列

        }
        goodsAdapter.submitList(list)
    }

}
  1. sharePerfence储存

class MyData(private val context: Context) {
    
    

    val memoryname by lazy {
    
     context.resources.getString(R.string.Login_state) }
    val itemmemory by lazy{
    
     context.getSharedPreferences(memoryname,Context.MODE_PRIVATE)}

    val deafultbool by lazy {
    
     context.resources.getBoolean(R.bool.default_bool) }
    var defaultboolvalue=false
    


    fun saveSlash( slash: Boolean){
    
    
        Thread {
    
    
            itemmemory.edit().putBoolean("slashs",slash).apply()
        }.start()
    }
    fun loadSlash():Boolean{
    
    

            defaultboolvalue =itemmemory.getBoolean("slashs",deafultbool)
        return defaultboolvalue
    }
}


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

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

在这里插入图片描述
还有第二个地图定位,就不暴露位置了emmmm。

5. 补充

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

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38304672/article/details/111255269