作者 zhangji

聊天详情写完

正在显示 24 个修改的文件 包含 412 行增加12 行删除
... ... @@ -10,8 +10,8 @@ import java.io.File
*/
object Constant {
// const val BASE_URL = "https://security.brofirst.cn/"
// const val BASE_URL = "http://security.brofirst.cn/"
const val BASE_URL = "https://test.mobile.anqixing.com/"
const val BASE_URL = "http://security.brofirst.cn/"
// const val BASE_URL = "https://test.mobile.anqixing.com/"
// const val BASE_URL = "http://admin.anqixing.com"
const val USERNAME_KEY = "username"
const val USERID_KEY = "userid"
... ...
... ... @@ -3,6 +3,7 @@ package com.br_technology.securitytrain_master.base.network.api
import com.br_technology.securitytrain_master.base.network.response.*
import com.br_technology.securitytrain_master.ui.bean.*
import com.br_technology.securitytrain_master.ui.view.login.bean.LoginBean
import com.br_technology.securitytrain_master.ui.view.mine.bean.ChatDetailBean
import com.br_technology.securitytrain_master.ui.view.mine.bean.ChatRecordBean
import io.reactivex.rxjava3.core.Observable
import retrofit2.http.*
... ... @@ -267,6 +268,33 @@ interface UserApi : ApiService {
@Field("page_num") page_num: Int
): Observable<BaseResponse<CommonDataList<CommonPage<ChatRecordBean>>>>
/**
* 教师消息列表
* @param page 页数
* @param page_num 每页显示数量
*/
@FormUrlEncoded
@POST("/api/teachermessage/msg_detail")
fun msgDetail(
@Field("page") page: Int,
@Field("page_num") page_num: Int,
@Field("teacher_id") teacherId: Int,
): Observable<BaseResponse<CommonDetail<CommonPage<ChatDetailBean>>>>
/**
* 教师消息列表
* @param page 页数
* @param page_num 每页显示数量
*/
@FormUrlEncoded
@POST("/api/teachermessage/return_msg")
fun sendMsg(
@Field("teacher_id") teacherId: Int,
@Field("content") content: String,
): Observable<BaseResponse<Any>>
/**
* 删除证件
* @param id 证件id
... ...
... ... @@ -10,6 +10,7 @@ import android.text.style.AbsoluteSizeSpan
import android.util.Log
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
... ... @@ -104,3 +105,8 @@ fun TextView.percentage() {
span.setSpan(AbsoluteSizeSpan(20.dp2px()),0,text.length-1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
this.text=span
}
fun View.hideSoftInputFromWindow() {
val inputMethodManager=this.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(this.windowToken,0)
}
... ...
... ... @@ -76,7 +76,7 @@ class OnLiveCourseFragment
if (status == "1") {
url = adapter.data.get(position).playerUrl
}
val title = adapter.data.get(position).name
val title = adapter.data[position].name
val intent = Intent(requireActivity(), LiveWebActivity::class.java)
intent.putExtra("url", url)
intent.putExtra("title", title)
... ...
... ... @@ -16,6 +16,7 @@ import com.br_technology.securitytrain_master.ui.view.home.adapter.SearchAdapter
import com.br_technology.securitytrain_master.ui.view.home.bean.RecommendBean
import com.br_technology.securitytrain_master.ui.view.home.bean.VideoLessonBean
import com.br_technology.securitytrain_master.ui.view.home.viewmodel.ResultViewModel
import com.br_technology.securitytrain_master.ui.view.mine.activity.LiveWebActivity
import com.br_technology.securitytrain_master.util.TranslateUnit
import com.br_technology.securitytrain_master.view.VerticalDecoration
import com.wjx.android.wanandroidmvvm.base.view.BaseLifeCycleFragment
... ... @@ -186,6 +187,13 @@ class ResultFragment(val type: Int) :
)
}
ResultViewModel.ResultType.TYPE_ONE -> {
//todo 直播未写
// val title = item.videoData
val intent = Intent(requireActivity(), LiveWebActivity::class.java)
// intent.putExtra("url", url)
// intent.putExtra("title", title)
startActivity(intent)
}
ResultViewModel.ResultType.TYPE_TWO -> {
val course = CourseParam()
... ...
... ... @@ -7,6 +7,7 @@ import com.br_technology.securitytrain_master.databinding.ActivityMobileLoginBin
import com.br_technology.securitytrain_master.isPhone
import com.br_technology.securitytrain_master.ui.view.login.viewmode.MobileLoginViewModel
import com.br_technology.securitytrain_master.ui.view.main.MainActivity
import com.br_technology.securitytrain_master.util.userId
import com.wjx.android.wanandroidmvvm.base.view.BaseLifeCycleActivity
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Flowable
... ...
package com.br_technology.securitytrain_master.ui.view.mine.activity
import com.br_technology.securitytrain_master.databinding.ActivityChatRecordBinding
import android.os.Handler
import android.os.Looper
import androidx.recyclerview.widget.LinearLayoutManager
import com.br_technology.securitytrain_master.databinding.ActivityChatBinding
import com.br_technology.securitytrain_master.expand.hideSoftInputFromWindow
import com.br_technology.securitytrain_master.ui.view.mine.adapter.ChatAdapter
import com.br_technology.securitytrain_master.ui.view.mine.bean.ChatDetailBean
import com.br_technology.securitytrain_master.ui.view.mine.viewmodel.ChatRecordViewModel
import com.gyf.immersionbar.ImmersionBar
import com.scwang.smart.refresh.header.ClassicsHeader
import com.wjx.android.wanandroidmvvm.base.view.BaseLifeCycleActivity
/**
... ... @@ -11,15 +19,80 @@ import com.wjx.android.wanandroidmvvm.base.view.BaseLifeCycleActivity
* updateInfo:
*/
class ChatActivity :
BaseLifeCycleActivity<ChatRecordViewModel, ActivityChatRecordBinding>(ActivityChatRecordBinding::inflate) {
BaseLifeCycleActivity<ChatRecordViewModel, ActivityChatBinding>(ActivityChatBinding::inflate) {
companion object {
init {
ClassicsHeader.REFRESH_HEADER_PULLING = "下拉可以加载...";
ClassicsHeader.REFRESH_HEADER_REFRESHING = "正在加载...";
ClassicsHeader.REFRESH_HEADER_RELEASE = "释放立即加载";
ClassicsHeader.REFRESH_HEADER_FINISH = "加载完成";
ClassicsHeader.REFRESH_HEADER_FAILED = "加载失败";
}
}
val adapter: ChatAdapter by lazy {
ChatAdapter()
}
private var page = 1
private var teacherId = -1
override fun initDataObserver() {
mViewModel.detailLiveData.observe(this) {
it.data.detail.data.forEach { bean ->
bean.itemType = if (bean.from_id_type == "1") 0 else 1
}
if (it.data.detail.data.size < 10) {
binding.smartRefresh.finishRefreshWithNoMoreData()
}
if (page == 1) {
binding.chatRv.scrollToPosition(0)
adapter.setNewInstance(it.data.detail.data as MutableList<ChatDetailBean>)
} else {
adapter.addData(it.data.detail.data)
}
}
mViewModel.sendLiveData.observe(this) {
showTip("发送成功")
binding.root.hideSoftInputFromWindow()
binding.chatSend.isClickable = true
binding.chatContent.setText("")
page = 1
// 请求网络
mViewModel.msgDetail(page, teacherId)
}
}
override fun initData() {
super.initData()
ImmersionBar.with(this).transparentStatusBar().keyboardEnable(true).statusBarDarkFont(true)
.init()
// 教师id
teacherId = intent.getIntExtra("id", -1)
// 请求网络
mViewModel.msgDetail(page, teacherId)
binding.apply {
// chatRv.adapter=
smartRefresh.setOnRefreshListener {
++page
mViewModel.msgDetail(page, teacherId)
smartRefresh.finishRefresh()
}
// 倒叙显示
val manager = LinearLayoutManager(baseContext, LinearLayoutManager.VERTICAL, true)
manager.stackFromEnd = true
chatRv.layoutManager = manager
// 设置适配器
chatRv.adapter = adapter
// 发送评论
chatSend.setOnClickListener {
chatSend.isClickable = false
val content = chatContent.text.toString()
mViewModel.sendMsg(content, teacherId)
}
}
}
}
\ No newline at end of file
... ...
package com.br_technology.securitytrain_master.ui.view.mine.activity
import android.content.Intent
import com.br_technology.securitytrain_master.databinding.ActivityChatRecordBinding
import com.br_technology.securitytrain_master.ui.view.mine.adapter.ChatRecordAdapter
import com.br_technology.securitytrain_master.ui.view.mine.bean.ChatRecordBean
... ... @@ -36,7 +37,6 @@ class ChatRecordActivity :
super.initData()
binding.apply {
smartRefresh.autoRefresh()
// 刷新
smartRefresh.setOnRefreshListener {
smartRefresh.setNoMoreData(false)
... ... @@ -53,9 +53,16 @@ class ChatRecordActivity :
chatRv.adapter = chatRecordAdapter
}
chatRecordAdapter.setOnItemClickListener { adapter, view, position ->
startActivity(ChatActivity::class.java)
chatRecordAdapter.setOnItemClickListener { _, _, position ->
val id = chatRecordAdapter.data[position].id
val intent = Intent(baseContext,ChatActivity::class.java)
intent.putExtra("id",id)
startActivity(intent)
}
}
override fun onResume() {
super.onResume()
binding.smartRefresh.autoRefresh()
}
}
\ No newline at end of file
... ...
package com.br_technology.securitytrain_master.ui.view.mine.adapter
import android.view.View
import android.widget.TextView
import com.br_technology.securitytrain_master.R
import com.br_technology.securitytrain_master.ui.view.mine.bean.ChatDetailBean
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.bumptech.glide.request.RequestOptions
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
/**
* auth: 张继
* date: 2022/2/7 10:41
* dsc:
* updateInfo:
*/
class ChatAdapter : BaseMultiItemQuickAdapter<ChatDetailBean, BaseViewHolder>() {
override fun convert(baseViewHolder: BaseViewHolder, chatBean: ChatDetailBean) {
when (chatBean.itemType) {
0 -> {
baseViewHolder.setText(R.id.chat_content, chatBean.content)
.setText(R.id.chat_time, chatBean.create_time)
val chatTime = baseViewHolder.getView<TextView>(R.id.chat_time)
if (chatBean.is_show_time == 0) {
chatTime.visibility = View.GONE
} else {
chatTime.visibility = View.VISIBLE
}
Glide.with(baseViewHolder.itemView.context)
.load(chatBean.avatar)
.apply(RequestOptions().transform(CircleCrop()))
.into(baseViewHolder.getView(R.id.chat_avatar))
}
1 -> {
baseViewHolder.setText(R.id.chat_content, chatBean.content)
.setText(R.id.chat_time, chatBean.create_time)
val chatTime = baseViewHolder.getView<TextView>(R.id.chat_time)
if (chatBean.is_show_time == 0) {
chatTime.visibility = View.GONE
} else {
chatTime.visibility = View.VISIBLE
}
Glide.with(baseViewHolder.itemView.context)
.load(chatBean.avatar)
.apply(RequestOptions().transform(CircleCrop()))
.into(baseViewHolder.getView(R.id.chat_avatar))
}
}
}
init {
addItemType(0, R.layout.chat_life_adapter)
addItemType(1, R.layout.chat_right_adapter)
}
}
\ No newline at end of file
... ...
package com.br_technology.securitytrain_master.ui.view.mine.bean
import com.chad.library.adapter.base.entity.MultiItemEntity
/**
* auth: 张继
* date: 2022/1/27 13:58
... ... @@ -22,3 +24,20 @@ data class Teacher(
val name: String,
val update_time_text: String
)
data class ChatDetailBean(
val avatar: String,
val content: String,
val create_time: String,
val delete_time: String,
val from_id: Int,
val from_id_type: String,
val from_id_type_text: String,
val id: Int,
val is_read: String,
val is_read_text: String,
val is_show_time: Int,
val msg_id: Int,
val to_id: Int,
val update_time: String, override var itemType: Int
):MultiItemEntity
\ No newline at end of file
... ...
... ... @@ -4,8 +4,10 @@ import androidx.lifecycle.MutableLiveData
import com.br_technology.securitytrain_master.base.common.State
import com.br_technology.securitytrain_master.base.network.response.BaseResponse
import com.br_technology.securitytrain_master.base.network.response.CommonDataList
import com.br_technology.securitytrain_master.base.network.response.CommonDetail
import com.br_technology.securitytrain_master.base.network.response.CommonPage
import com.br_technology.securitytrain_master.base.repository.ApiRepository
import com.br_technology.securitytrain_master.ui.view.mine.bean.ChatDetailBean
import com.br_technology.securitytrain_master.ui.view.mine.bean.ChatRecordBean
/**
... ... @@ -24,5 +26,21 @@ class ChatRepository(val loadState: MutableLiveData<State>) : ApiRepository(load
addRequest(userService.msgList(page, 20), liveData)
}
fun msgDetail(
page: Int,
teacherId: Int,
liveData: MutableLiveData<BaseResponse<CommonDetail<CommonPage<ChatDetailBean>>>>
) {
addRequest(userService.msgDetail(page, 10, teacherId), liveData)
}
fun sendMsg(
content: String,
teacherId: Int,
liveData: MutableLiveData<BaseResponse<Any>>
) {
addRequest(userService.sendMsg(teacherId, content), liveData)
}
}
\ No newline at end of file
... ...
... ... @@ -3,8 +3,10 @@ package com.br_technology.securitytrain_master.ui.view.mine.viewmodel
import androidx.lifecycle.MutableLiveData
import com.br_technology.securitytrain_master.base.network.response.BaseResponse
import com.br_technology.securitytrain_master.base.network.response.CommonDataList
import com.br_technology.securitytrain_master.base.network.response.CommonDetail
import com.br_technology.securitytrain_master.base.network.response.CommonPage
import com.br_technology.securitytrain_master.base.view.BaseViewModel
import com.br_technology.securitytrain_master.ui.view.mine.bean.ChatDetailBean
import com.br_technology.securitytrain_master.ui.view.mine.bean.ChatRecordBean
import com.br_technology.securitytrain_master.ui.view.mine.repository.ChatRepository
... ... @@ -18,7 +20,20 @@ class ChatRecordViewModel : BaseViewModel<ChatRepository>() {
val liveData: MutableLiveData<BaseResponse<CommonDataList<CommonPage<ChatRecordBean>>>> =
MutableLiveData()
val detailLiveData: MutableLiveData<BaseResponse<CommonDetail<CommonPage<ChatDetailBean>>>> =
MutableLiveData()
val sendLiveData: MutableLiveData<BaseResponse<Any>> = MutableLiveData()
fun msgList(page: Int) {
mRepository.msgList(page, liveData)
}
fun msgDetail(page: Int, teacherId: Int) {
mRepository.msgDetail(page, teacherId, detailLiveData)
}
fun sendMsg(content: String, teacherId: Int) {
mRepository.sendMsg(content, teacherId, sendLiveData)
}
}
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="1dp"
android:color="@color/color_96" />
<corners android:radius="4dp" />
</shape>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/layout_tool_bar" />
<com.br_technology.securitytrain_master.view.ViewToolBar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:toolTitle="聊天记录" />
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/smart_refresh"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:srlEnableLoadMore="false">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chat_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="1dp"
android:layout_marginBottom="15dp"
android:overScrollMode="never" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/white"
android:orientation="horizontal"
android:paddingHorizontal="16dp">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/chat_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginVertical="10dp"
android:layout_weight="1"
android:background="@drawable/stroke_ed_4"
android:hint="输入新消息"
android:textSize="14sp"
android:singleLine="true"
android:paddingHorizontal="10dp" />
<TextView
android:id="@+id/chat_send"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="15dp"
android:background="@drawable/solid_25_4"
android:gravity="center"
android:text="发送"
android:textColor="@color/white"
android:textSize="16sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
\ No newline at end of file
... ...
... ... @@ -23,8 +23,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="16dp"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
android:layout_marginTop="1dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:overScrollMode="never" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
\ No newline at end of file
... ...
... ... @@ -2,6 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_marginTop="15dp"
android:layout_height="wrap_content">
... ... @@ -54,4 +55,5 @@
android:layout_marginVertical="15dp"
android:background="@color/color_eb"
app:layout_constraintTop_toBottomOf="@id/chat_content" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/chat_time"
android:layout_marginTop="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/color_96"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/chat_avatar"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginTop="15dp"
android:contentDescription="@string/logo"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/chat_time"
app:srcCompat="@mipmap/placeholder_head" />
<TextView
android:id="@+id/chat_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:padding="12dp"
android:layout_marginTop="15dp"
android:textColor="@color/color_32"
android:background="@drawable/solid_ff_4"
android:textSize="15sp"
app:layout_constraintStart_toEndOf="@+id/chat_avatar"
app:layout_constraintTop_toBottomOf="@+id/chat_time" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/chat_time"
android:layout_marginTop="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="@color/color_96"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/chat_avatar"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginTop="15dp"
android:contentDescription="@string/logo"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/chat_time"
app:srcCompat="@mipmap/placeholder_head" />
<TextView
android:id="@+id/chat_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:background="@drawable/solid_ff_4"
android:padding="12dp"
android:textColor="@color/color_32"
android:textSize="15sp"
app:layout_constraintEnd_toStartOf="@+id/chat_avatar"
app:layout_constraintTop_toBottomOf="@+id/chat_time" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
... ...

5.2 KB | 宽: | 高:

3.7 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖

3.3 KB | 宽: | 高:

2.5 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖

7.3 KB | 宽: | 高:

5.1 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖

4.2 KB | 宽: | 高:

27.3 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖

11.6 KB | 宽: | 高:

7.7 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖

16.2 KB | 宽: | 高:

10.5 KB | 宽: | 高:

  • 两方对比
  • 交换覆盖
  • 透明覆盖