kotlin简易微信实现

代码文件:http://120.76.200.79/wp-content/uploads/2022/06/Hslven.zipicon-default.png?t=M5H6http://120.76.200.79/wp-content/uploads/2022/06/Hslven.zip

实验实现如下功能:

①五个Activity页面主体内容及跳转

加载页面:

9afb6aa4cc4f544d0b7604a4728c0a19.png

活动代码:
Class Loadingactivity : BaseActivity()
Over fun...{
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_loading)
val main = Intent(this,MainActivity::class.java)
    var timer= Timer()
    class MyTimerTask():TimerTask(){
        override fun run() {
            startActivity(main)
            finish()
        }
    }
// 4秒后跳转
    timer.schedule(MyTimerTask(),4000)
 }
}

登录页面:

8434fda3a40df2e5f95ad1316de6582c.png

1:退出程序

2:保留此次登录信息,重启或者重新返回登录页面后保留

3:跳转到朋友页面

4:跳转到注册页面

活动代码:
class MainActivity : BaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
​
        // 1)定义函数
        val login: Button = findViewById(R.id.login1)
        val reg: Button = findViewById(R.id.reg)
        val rem: CheckBox = findViewById(R.id.remember)
        val back: ImageView = findViewById(R.id.error_png)
​
        // 2)调用数据库--存入和取出
        val prefs = getSharedPreferences("data", MODE_PRIVATE)
        val editor = prefs.edit()
​
        // 2.1)返回上一次勾选
        rem.isChecked = prefs.getBoolean("isRem", false)  // 返回isRem的数据,如果没有数据,则默认false
​
        // 3)获取数据库中已存在的用户名和密码
        val exist_user = prefs.getString("user", "")
        val exist_pass = prefs.getString("pass", "")
        // 3.1)定义文本框的函数,同样是局部变量修改后转的 全局变量
        val userEdit: TextView = findViewById(R.id.user)
        val passEdit: TextView = findViewById(R.id.pass)
​
        // 5)不会使用类,开机后如果有存有数据则自动写入,和下方的代码是一样的
        if (rem.isChecked) {
            // 5.2)从刚才的数据库获取
            val now_user = prefs.getString("now_user", "")
            val now_pass = prefs.getString("now_pass", "")
​
            // 5.4)把记住的数据写入文本框
            userEdit.setText(now_user)
            passEdit.setText(now_pass)
        }
​
        // 6)从BaseActivity来的--在BaseAcivity传入了是否清空文本框密码
        val pass_clean = prefs.getBoolean("cleanpass", false)// 如果没有数据则默认不是
​
        // 6.1)清空密码文本框
        if (pass_clean) {
            passEdit.setText("")
​
            // 6.2)取消勾选‘记住我’,并且传入数据库
            rem.isChecked = false
            editor.putBoolean("isRem",rem.isChecked)
​
            // 6.3) 把是否清空密码改成false
            editor.putBoolean("cleanpass",false)
            // 6.4)提交数据
            editor.apply() // 提交数据
        }
​
        login.setOnClickListener() {
            // 3.2)获取输入的用户名和密码
            val user = user.text.toString()
            val pass = pass.text.toString()
​
            //4)如果账户密码数据库已存在则登录成功
            if (user == exist_user && pass == exist_pass) {
​
                // 5)如果点击了‘记住我’登录,
                if (rem.isChecked) {
                    // 5.1)存入输入的文本
                    editor.putString("now_user", user)
                    editor.putString("now_pass", pass)
                    editor.apply() // 提交数据
​
                    // 5.2)从刚才的数据库获取
                    val now_user = prefs.getString("now_user", "")
                    val now_pass = prefs.getString("now_pass", "")
​
                    // 5.4)把记住的数据写入文本框
                    userEdit.setText(now_user)
                    passEdit.setText(now_pass)
​
                    // 5.5)判断是否勾选‘记住我’,并保存到数据库,方便下一次在此界面包留是否勾选
                    val isRem = rem.isChecked
                    editor.putBoolean("isRem", isRem)
                    editor.apply() // 提交数据
​
                } else {
                    // 5.6)如果没有勾选,清空文本框
                    userEdit.setText("")
                    passEdit.setText("")
                }
​
                Toast.makeText(this, "登陆成功", Toast.LENGTH_LONG).show()
                // 进行跳转
                val it = Intent(this, MsgListActivity::class.java)
                startActivity(it)
            } else if (user != exist_user) {
                Toast.makeText(this, "登陆失败,用户名不存在", Toast.LENGTH_LONG).show()
            } else {
                Toast.makeText(this, "登陆失败,请检查密码是否正确", Toast.LENGTH_LONG).show()
            }
        }
​
        reg.setOnClickListener() {
            val it1 = Intent(this, register::class.java)
            startActivity(it1)
        }
​
        back.setOnClickListener() {
            ActivityCollector.finishAll()
        }
    }
}

注册页面:

8bc0c3ca57d14dfe8defca90e8a1b552.png

1:返回到上一个活动页面

2:输入信息,用于保留数据并上传

3:点击后上传数据

​
活动代码:
class register : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_register1)
​
        val back:ImageView = findViewById(R.id.error_png)
        register.setOnClickListener() {
            // 定义函数
            val user = ruser.text.toString()
            val pass = rpassword.text.toString()
​
            // 判断男女
            val sex_nan = sexButton1.isChecked()
            val sex_nav = sexButton2.isChecked()
            // 调用数据库--存入和取出
            val prefs = getSharedPreferences("data", Context.MODE_PRIVATE)
            val editor = prefs.edit() //存入
​
            // 如果已有相同用户名--注册失败
            // 1) 获取已存用户名
            val exist_user = prefs.getString("user", "")
​
            // 2) 进行判断
            if (user == exist_user) {
                Toast.makeText(this, "用户名已存在,无法注册!", Toast.LENGTH_LONG).show()
            } else {
                // 3) 注册成功--把各种数据存入数据库
                editor.putString("user", user)
                editor.putString("pass", pass)
                if (sex_nan) {
                    editor.putString("sex", "man")
                } else if (sex_nav) {
                    editor.putString("sex", "woman")
                } else {
                    editor.putString("sex", "hermaphrodite")
                }
                editor.apply() // 提交数据
​
                // 3.1)注册成功--跳转
                Toast.makeText(this, "注册成功", Toast.LENGTH_LONG).show()
                val it = Intent(this, MainActivity::class.java)
                startActivity(it)
            }
        }
​
        back.setOnClickListener(){
            finish()
        }
    }
}

朋友界面:

 

1:返回到登录页面

2:点击后进入聊天界面

3:实现强制下线功能

活动代码:

// 朋友界面
class MsgListActivity : BaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_friend1)
        val back:TextView = findViewById(R.id.error_dark_png)

        //把聊天的最后一句话放在页面
        val now_text:TextView = findViewById(R.id.now_text)
        val prefs = getSharedPreferences("data", MODE_PRIVATE)
        now_text.setText(prefs.getString("now_neirong","没有找到内容..."))

        back.setOnClickListener(){
            //退出当前活动
            finish()
        }
        // 强制下线
        val go_out:Button = findViewById(R.id.go_out)
        go_out.setOnClickListener(){
            val intent = Intent("go")
            sendBroadcast(intent)
        }
        // 跳转到天气列表
        val weather:Button = findViewById(R.id.weatherlook)
        weather.setOnClickListener() {
            Toast.makeText(this, "ok", Toast.LENGTH_SHORT).show()
            SendRquestOkhttp()
        }
        //和朋友聊天
        val chat:TextView = findViewById(R.id.now_text)
        val chatone:TextView = findViewById(R.id.text0)
        val chattwo:ImageView = findViewById(R.id.img0)
        val it2 = Intent(this,ChatActivity::class.java)
        chat.setOnClickListener(){
            startActivity(it2)
            finish()
        }
        chatone.setOnClickListener(){
            startActivity(it2)
            finish()
        }
        chattwo.setOnClickListener(){
            startActivity(it2)
            finish()
        }
    }
    private fun SendRquestOkhttp()
    // 开启线程发起网络请求
    {thread {
            try {
                val client = OkHttpClient()
                val request = Request.Builder()
                    .url("https://www.yiketianqi.com/free/day?appid=95979945&appsecret=pg8gdx39&unescape=1&cityid=101280803")
                    .build()
                // execute发送请求返回数据
                val response = client.newCall(request).execute()
                val responseData = response.body?.string()
                if (responseData != null) {
                    show(responseData)
                } 
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    private  fun show(res:String) {
        try {
            val jsondata= JSONObject(res)
            val cityname=jsondata.getString("city")
            val date=jsondata.getString("date")
            val wea=jsondata.getString("wea")
            val week=jsondata.getString("week")
            val nowtem=jsondata.getString("tem")
            val tem_day=jsondata.getString("tem_day")
            val tem_night=jsondata.getString("tem_night")
            val win=jsondata.getString("win")
            val res="$date 城市:$cityname $week,天气如下,天气情况:$wea \n 现在温度:$nowtem 白天最高温度:$tem_day 晚上最高温度:$tem_night 风向:$win "
            showResponse(res)

        }catch (e:Exception)
        {e.printStackTrace()
        }
    }

    private fun showResponse(response: String) {
        val weather_text: TextView = findViewById(R.id.weather_text)
        runOnUiThread {
            //这里进行UI操作,将结果显示到界面上
            weather_text.text = response
        }
    }
}

聊天界面:

caf331ff1a8e4dc0b2961ba6b03d2574.png

1:返回聊天界面

2:发送的信息被放在这里,重新进入或者重启后会保留

3:用于发送内容,发送后清空文本框

活动代码:
class ChatActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_chat)
​
        val send:Button = findViewById(R.id.send)
        val replay:TextView = findViewById(R.id.replay)
        val text:TextView = findViewById(R.id.input_text)
        val back_now:ImageView = findViewById(R.id.back_now)
​
        // 建立数据库
        val prefs = getSharedPreferences("data", MODE_PRIVATE)
        val editor = prefs.edit()
​
        // 进入保留内容(只保留一次)
        replay.setText(prefs.getString("neirong","")+ "\n")
​
        // 然后清空
        editor.putString("neirong","")
        editor.apply()
​
        send.setOnClickListener(){
            // 存入最后一句话
            val textEdit = text.text.toString()
            editor.putString("now_neirong",textEdit)
            editor.apply()
            // 给文本框写入输入的内容
            replay.setText(prefs.getString("neirong","")+ textEdit + "\n")
            // 保留文本
            editor.putString("neirong",replay.text.toString())
            editor.apply()
            // 发送后清空
            text.setText("")
        }
        // 退出活动
        back_now.setOnClickListener(){
            val it2 = Intent(this,MsgListActivity::class.java)
            startActivity(it2)
            finish()
        }
    }
}

者进入此页面两次就会清空)

d4357a2686afc4270a095a8e05db7d68.png

⑤聊天页返回至消息列表页携带回最后一条消息内容,并更新数据库和消息列表页RecyclerView或者listview

仍然是使用SharedPreferences数据库保留最后一条消息内容,来携带返回

我们尝试发送信息

4a6630a73ddf4997b27e6fd7e5f5e110.png

会携带最后一次输出的信息放在朋友页面的文本框

013759381693b495a656cbfb92bd9311.png

⑥强制下线

在朋友界面“方框3”处,注册了一个按钮来实现强制下线功能,点击之后会弹出文本框并且无法关闭,点击之后跳转到加载页面。

 

点击“强制下线”

70f52aa4c44386c57b6e7deec0d7c9b6.png

点击“好的”,我们会在加载后进入登陆页面

同时为了用户的安全,通过此方法重新进入后会取消勾选“记住我”,并把保存密码的清空,需要用户重新输入密码

38c53460bdabc46b32cea7977f518950.png

⑦在某一页面添加一按钮,点击后进行天气的查询。

至此,基本功能实现

强制下线的实现方法:

1. 新建一个单例类ActivityCollector作为Activity的集合

/* 单例类ActivityCollector作为Activity的集合,对所有的Activity进行管理 */
​
object ActivityCollector {
    private val activities=ArrayList<Activity>()
​
    /* 用于向ArrayList中添加Activity */
    fun addActivity(actity:Activity){
        activities.add(actity)
    }
    
    /* 用于从ArrayList中移除Activity */
    fun removeActivity(actity: Activity){
        activities.remove(actity)
    }
    
    /* 用于将ArrayList中存储的Activity全部销毁 */
    fun finishAll(){
        for (activity in activities){
            if (!activity.isFinishing){
                activity.finish()
            }
        }
        activities.clear()
    }
}

2. 新建Class取名BaseActivity,添加代码让其继承AppCompatActivity,并重写onCreat()方法,重写onDestroy()方法

open class BaseActivity : AppCompatActivity() {
​
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ActivityCollector.addActivity(this)
    }
​
    override fun onDestroy() {
        super.onDestroy()
        ActivityCollector.removeActivity(this)
    }
}

3. 让所有Activity继承BaseActivity,由于BaseActivity继承自AppCompatActivity,所以所有Activity现有功能都不受影响

class MainActivity : BaseActivity()

4. 设置按钮的点击事件,只需调用ActivityCollector的finishAll方法

//退出程序
        set_close.setOnClickListener {
            ActivityCollector.finishAll()
        }

猜你喜欢

转载自blog.csdn.net/lok_p/article/details/125020781
今日推荐