kotlin simple wechat implementation

Code file: http://120.76.200.79/wp-content/uploads/2022/06/Hslven.zip icon-default.png?t=M5H6http://120.76.200.79/wp-content/uploads/2022/06/Hslven.zip

The experiment implements the following functions:

①The main content and jump of the five Activity pages

Load the page:

9afb6aa4cc4f544d0b7604a4728c0a19.png

Activity code:
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)
 }
}

log in page:

8434fda3a40df2e5f95ad1316de6582c.png

1: Exit the program

2: Keep the login information this time, and keep it after restarting or returning to the login page

3: Jump to friend page

4: Jump to the registration page

Activity code:
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()
        }
    }
}

registration page:

8bc0c3ca57d14dfe8defca90e8a1b552.png

1: Return to the previous active page

2: Enter information for retaining data and uploading

3: Upload data after clicking


Activity code:
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()
        }
    }
}

Friends interface:

 

1: Return to the login page

2: Click to enter the chat interface

3: Realize the forced offline function

Activity code:

// 朋友界面
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
        }
    }
}

Chat interface:

caf331ff1a8e4dc0b2961ba6b03d2574.png

1: Return to the chat interface

2: The sent information is placed here, and will be retained after re-entering or restarting

3: Used to send content, clear the text box after sending

Activity code:
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()
        }
    }
}

The user enters this page twice and it will be cleared)

d4357a2686afc4270a095a8e05db7d68.png

⑤The chat page returns to the message list page to carry back the content of the last message, and update the database and message list page RecyclerView or listview

Still use the SharedPreferences database to retain the content of the last message to carry and return

we try to send a message

4a6630a73ddf4997b27e6fd7e5f5e110.png

Will carry the last output information and put it in the text box of the friend page

013759381693b495a656cbfb92bd9311.png

⑥ Forced offline

In the "box 3" of the friend interface, a button is registered to realize the forced offline function. After clicking, a text box will pop up and cannot be closed. After clicking, it will jump to the loading page.

 

Click "Force Offline"

70f52aa4c44386c57b6e7deec0d7c9b6.png

Click "OK" and we'll go to the landing page after loading

At the same time, for the safety of the user, after re-entering through this method, the "remember me" will be unchecked, and the saved password will be cleared, requiring the user to re-enter the password

38c53460bdabc46b32cea7977f518950.png

⑦ Add a button on a certain page, click to query the weather.

At this point, the basic functions are realized

Implementation method of forced offline:

1. Create a new singleton class ActivityCollector as a collection of Activities

/* 单例类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. Create a new Class named BaseActivity, add code to let it inherit AppCompatActivity, and rewrite the onCreat() method and onDestroy() method

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

3. Let all activities inherit from BaseActivity. Since BaseActivity inherits from AppCompatActivity, all existing functions of Activity will not be affected

class MainActivity : BaseActivity()

4. To set the click event of the button, just call the finishAll method of ActivityCollector

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

Guess you like

Origin blog.csdn.net/lok_p/article/details/125020781