feat:完成公聊厅-首页入口

This commit is contained in:
max
2024-05-09 16:06:15 +08:00
parent 376fbdaeb2
commit c986a2dce6
15 changed files with 323 additions and 19 deletions

View File

@@ -222,7 +222,7 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
publicChatMessageWidget = PublicChatRoomMessageWidget(requireContext()) publicChatMessageWidget = PublicChatRoomMessageWidget(requireContext())
val tabList: MutableList<String> = java.util.ArrayList(2) val tabList: MutableList<String> = java.util.ArrayList(2)
tabList.add(getString(R.string.room)) tabList.add(getString(R.string.room))
tabList.add(getString(R.string.public_chat)) tabList.add(getString(R.string.public_chat_room))
val messagePager = mView.findViewById<ViewPager2>(R.id.message_pager) val messagePager = mView.findViewById<ViewPager2>(R.id.message_pager)
val messageIndicator = mView.findViewById<MagicIndicator>(R.id.message_indicator) val messageIndicator = mView.findViewById<MagicIndicator>(R.id.message_indicator)
messagePager.offscreenPageLimit = tabList.size messagePager.offscreenPageLimit = tabList.size

View File

@@ -0,0 +1,20 @@
package com.chwl.app.home
import androidx.lifecycle.MutableLiveData
import com.chwl.app.base.BaseViewModel
import com.chwl.core.bean.response.BeanResult
import com.chwl.core.public_chat_hall.bean.PublicChatMessageBean
import com.chwl.core.public_chat_hall.model.PublicChatModel
class HomeMessageViewModel : BaseViewModel() {
val topPublicChatMessageLiveData = MutableLiveData<BeanResult<List<PublicChatMessageBean>>>()
fun getTopPublicChatMessage() {
safeLaunch(needLoading = false, onError = {
topPublicChatMessageLiveData.postValue(BeanResult.failed(it))
}) {
val value = PublicChatModel.getTopMessage()
topPublicChatMessageLiveData.postValue(BeanResult.success(value ?: emptyList()))
}
}
}

View File

@@ -0,0 +1,48 @@
package com.chwl.app.home.adapter
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseViewHolder
import com.chwl.app.R
import com.chwl.app.ui.utils.loadAvatar
import com.chwl.core.public_chat_hall.bean.PublicChatMessageBean
class PublicChatLaneAdapter(private val data: MutableList<PublicChatMessageBean>) :
RecyclerView.Adapter<BaseViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
return BaseViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.public_chat_lane_item, null)
)
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val item = getItem(position)
holder.setText(R.id.tv_message, item?.content ?: "")
val avatarView = holder.getView<ImageView>(R.id.iv_avatar)
avatarView.loadAvatar(item?.fromAvatar ?: "")
}
override fun getItemCount(): Int {
return Int.MAX_VALUE
}
fun getRealItemCount(): Int {
return data.size
}
fun setNewData(list: List<PublicChatMessageBean>) {
data.clear()
data.addAll(list)
notifyDataSetChanged()
}
private fun getItem(position: Int): PublicChatMessageBean? {
if (data.isEmpty()) {
return null
}
return data[position % data.size]
}
}

View File

@@ -1,35 +1,44 @@
package com.chwl.app.home.fragment package com.chwl.app.home.fragment
import android.view.GestureDetector
import android.view.MotionEvent
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager.OnPageChangeListener import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import androidx.viewpager2.widget.ViewPager2 import androidx.viewpager2.widget.ViewPager2
import com.netease.nimlib.sdk.NIMClient import com.chwl.app.MainTabContentView
import com.netease.nimlib.sdk.msg.MsgService
import com.chwl.app.R import com.chwl.app.R
import com.chwl.app.avroom.adapter.CommonVPAdapter import com.chwl.app.avroom.adapter.CommonVPAdapter
import com.chwl.app.base.BaseViewBindingFragment import com.chwl.app.base.BaseViewBindingFragment
import com.chwl.app.common.widget.dialog.DialogManager.AbsOkDialogListener
import com.chwl.app.databinding.FragmentContactListBinding import com.chwl.app.databinding.FragmentContactListBinding
import com.chwl.app.home.event.ContactTrashEvent import com.chwl.app.home.HomeMessageViewModel
import com.chwl.app.home.adapter.PublicChatLaneAdapter
import com.chwl.app.home.helper.AutoScrollTask
import com.chwl.app.public_chat.ui.message.PublicChatRoomMessageActivity
import com.chwl.app.ui.im.friend.FriendListFragment import com.chwl.app.ui.im.friend.FriendListFragment
import com.chwl.app.ui.im.recent.RecentListFragment import com.chwl.app.ui.im.recent.RecentListFragment
import com.chwl.app.ui.relation.FansListFragment import com.chwl.app.ui.relation.FansListFragment
import com.chwl.app.ui.user.adapter.UserInfoIndicatorAdapter import com.chwl.app.ui.user.adapter.UserInfoIndicatorAdapter
import com.chwl.app.ui.user.adapter.UserInfoPagerAdapter
import com.chwl.app.ui.widget.magicindicator.ViewPagerHelper
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.CommonNavigator import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.CommonNavigator
import com.chwl.core.Constants import com.chwl.core.Constants
import com.chwl.library.utils.ResUtil import com.example.lib_utils.UiUtils
import org.greenrobot.eventbus.EventBus import com.example.lib_utils.ktx.singleClick
/** /**
* @author jack * @author jack
* @Description * @Description
* @Date 2018/11/1 * @Date 2018/11/1
*/ */
class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>() { class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>(),
MainTabContentView {
private val viewModel: HomeMessageViewModel by activityViewModels()
private val publicChatAdapter = PublicChatLaneAdapter(ArrayList())
companion object { companion object {
const val TAG = "ContactsListFragment" const val TAG = "ContactsListFragment"
@@ -40,8 +49,21 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
} }
} }
private var isRTL = false
private val autoScrollTask = AutoScrollTask(15) {
val x = if (isRTL) {
-2
} else {
2
}
binding.recyclerViewPublicChat.scrollBy(x, 0)
}
override fun init() { override fun init() {
isRTL = UiUtils.isRtl(requireContext())
initViewPager() initViewPager()
initPublicChatView()
} }
private fun initViewPager() { private fun initViewPager() {
@@ -93,4 +115,85 @@ class ContactsListFragment : BaseViewBindingFragment<FragmentContactListBinding>
}) })
} }
private fun initPublicChatView() {
val gestureDetectorCompat = GestureDetectorCompat(requireContext(), object :
GestureDetector.OnGestureListener {
override fun onDown(e: MotionEvent): Boolean {
return true
}
override fun onShowPress(e: MotionEvent) {
}
override fun onSingleTapUp(e: MotionEvent): Boolean {
PublicChatRoomMessageActivity.start(requireContext())
return true
}
override fun onScroll(
e1: MotionEvent,
e2: MotionEvent,
distanceX: Float,
distanceY: Float
): Boolean {
return true
}
override fun onLongPress(e: MotionEvent) {
}
override fun onFling(
e1: MotionEvent,
e2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
return true
}
})
binding.layoutPublicChat.singleClick {
PublicChatRoomMessageActivity.start(requireContext())
}
binding.recyclerViewPublicChat.setOnTouchListener { v, event ->
gestureDetectorCompat.onTouchEvent(event)
}
binding.recyclerViewPublicChat.layoutManager =
StaggeredGridLayoutManager(2, RecyclerView.HORIZONTAL)
binding.recyclerViewPublicChat.adapter = publicChatAdapter
viewModel.topPublicChatMessageLiveData.observe(this) {
val newList = it.data
if (it.isSuccess && !newList.isNullOrEmpty()) {
publicChatAdapter.setNewData(newList)
switchPublicChatMessageScrollState(true)
}
binding.layoutPublicChat.isVisible = (publicChatAdapter.getRealItemCount() > 0)
}
}
private fun refreshPublicChatMessage() {
viewModel.getTopPublicChatMessage()
}
override fun onStart() {
super.onStart()
onVisibleStateChanged(true)
refreshPublicChatMessage()
}
override fun onStop() {
super.onStop()
onVisibleStateChanged(false)
}
override fun onVisibleStateChanged(showOrHide: Boolean) {
switchPublicChatMessageScrollState(showOrHide)
}
private fun switchPublicChatMessageScrollState(showOrHide: Boolean) {
if (showOrHide && publicChatAdapter.getRealItemCount() > 0) {
autoScrollTask.start()
} else {
autoScrollTask.stop()
}
}
} }

View File

@@ -0,0 +1,23 @@
package com.chwl.app.home.helper
import android.os.Handler
import android.os.Looper
class AutoScrollTask(val timeInterval: Long, call: () -> Unit) {
private val handler = Handler(Looper.getMainLooper())
private val autoRunnable = object : Runnable {
override fun run() {
call.invoke()
handler.postDelayed(this, timeInterval)
}
}
fun start() {
handler.removeCallbacks(autoRunnable)
handler.postDelayed(autoRunnable, 0)
}
fun stop() {
handler.removeCallbacks(autoRunnable)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -3,7 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/color_F7F7F7"> android:background="@color/color_F7F7F7"
xmlns:tools="http://schemas.android.com/tools">
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -12,17 +13,68 @@
app:layout_constraintDimensionRatio="375:91" app:layout_constraintDimensionRatio="375:91"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:visibility="gone"
tools:visibility="visible"
android:id="@+id/layout_public_chat"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="@dimen/dp_44"
android:background="@drawable/public_chat_bg_lane"
app:layout_constraintDimensionRatio="375:112"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_public_chat_title_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.22" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_public_chat_list_top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.46" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_public_chat_list_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.94" />
<TextView
android:id="@+id/tv_public_chat_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/public_chat_room"
android:textColor="#FFDDA2"
android:textSize="@dimen/dp_17"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/line_public_chat_title_top" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_public_chat"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="@id/line_public_chat_list_bottom"
app:layout_constraintTop_toTopOf="@id/line_public_chat_list_top" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout <LinearLayout
android:id="@+id/ll_title" android:id="@+id/ll_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/dp_44" android:layout_height="@dimen/dp_44"
android:layout_marginTop="@dimen/dp_44"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingStart="@dimen/dp_15" android:paddingStart="@dimen/dp_15"
android:paddingEnd="@dimen/dp_15" android:paddingEnd="@dimen/dp_15"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toBottomOf="@id/layout_public_chat"
app:layout_goneMarginTop="@dimen/dp_44">
<com.chwl.app.ui.widget.magicindicator.MagicIndicator <com.chwl.app.ui.widget.magicindicator.MagicIndicator
android:id="@+id/magic_indicator" android:id="@+id/magic_indicator"

View File

@@ -0,0 +1,35 @@
<?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="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingEnd="@dimen/dp_18"
tools:layout_height="@dimen/dp_80">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/iv_avatar"
android:layout_width="0dp"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="w,1:1"
app:layout_constraintStart_toStartOf="parent"
app:shapeAppearance="@style/shape_circle"
tools:src="@drawable/default_cover" />
<TextView
android:id="@+id/tv_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_5"
android:maxLines="1"
android:textColor="#FFFCED"
android:textSize="@dimen/dp_12"
app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/iv_avatar"
app:layout_constraintTop_toTopOf="@id/iv_avatar"
tools:text="Message" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -50,7 +50,7 @@ class PublicChatRoomMessageActivity : BaseBindingActivity<PublicChatMessageActiv
} }
private fun initView(sessionId: String) { private fun initView(sessionId: String) {
initWhiteTitleBar(ResUtil.getString(R.string.public_chat)) initWhiteTitleBar(ResUtil.getString(R.string.public_chat_room))
val fragment = PublicChatRoomMessageFragment.newInstance(sessionId) val fragment = PublicChatRoomMessageFragment.newInstance(sessionId)
supportFragmentManager.beginTransaction().add(R.id.fragment_message, fragment) supportFragmentManager.beginTransaction().add(R.id.fragment_message, fragment)
.commitAllowingStateLoss() .commitAllowingStateLoss()

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="public_chat">公聊廳</string> <string name="public_chat_room">公聊廳</string>
<string name="want_headline">我要上頭條~</string> <string name="want_headline">我要上頭條~</string>
<string name="public_chat_not_found">獲取公聊廳信息失敗</string> <string name="public_chat_not_found">獲取公聊廳信息失敗</string>
<string name="headline_buy_format">%s 上頭條</string> <string name="headline_buy_format">%s 上頭條</string>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="public_chat">公聊廳</string> <string name="public_chat_room">公聊廳</string>
<string name="want_headline">我要上頭條~</string> <string name="want_headline">我要上頭條~</string>
<string name="public_chat_not_found">獲取公聊廳信息失敗</string> <string name="public_chat_not_found">獲取公聊廳信息失敗</string>
<string name="headline_buy_format">%s 上頭條</string> <string name="headline_buy_format">%s 上頭條</string>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="public_chat">公聊廳</string> <string name="public_chat_room">公聊廳</string>
<string name="want_headline">我要上頭條~</string> <string name="want_headline">我要上頭條~</string>
<string name="public_chat_not_found">獲取公聊廳信息失敗</string> <string name="public_chat_not_found">獲取公聊廳信息失敗</string>
<string name="headline_buy_format">%s 上頭條</string> <string name="headline_buy_format">%s 上頭條</string>

View File

@@ -1,9 +1,10 @@
package com.chwl.core.public_chat_hall.bean package com.chwl.core.public_chat_hall.bean
import androidx.annotation.Keep import androidx.annotation.Keep
import java.io.Serializable
@Keep @Keep
class HeadlineBean { class HeadlineBean : Serializable {
val content: String? = null val content: String? = null
val id: Long? = null val id: Long? = null
val uid: Long? = null val uid: Long? = null

View File

@@ -0,0 +1,10 @@
package com.chwl.core.public_chat_hall.bean
import androidx.annotation.Keep
@Keep
class PublicChatMessageBean {
val content: String? = null
val fromAvatar: String? = null
val fromNick: String? = null
}

View File

@@ -3,6 +3,7 @@ package com.chwl.core.public_chat_hall.model
import com.chwl.core.base.BaseModel import com.chwl.core.base.BaseModel
import com.chwl.core.bean.response.ServiceResult import com.chwl.core.bean.response.ServiceResult
import com.chwl.core.public_chat_hall.bean.HeadlineBean import com.chwl.core.public_chat_hall.bean.HeadlineBean
import com.chwl.core.public_chat_hall.bean.PublicChatMessageBean
import com.chwl.core.utils.net.launchRequest import com.chwl.core.utils.net.launchRequest
import com.chwl.core.vip.bean.VipPageInfo import com.chwl.core.vip.bean.VipPageInfo
import com.chwl.library.net.rxnet.RxNet import com.chwl.library.net.rxnet.RxNet
@@ -14,6 +15,11 @@ import retrofit2.http.POST
object PublicChatModel : BaseModel() { object PublicChatModel : BaseModel() {
private val api = RxNet.create(PublicChatModel.Api::class.java) private val api = RxNet.create(PublicChatModel.Api::class.java)
suspend fun getTopMessage(): List<PublicChatMessageBean>? =
launchRequest {
api.getTopMessage()
}
suspend fun getCurrentHeadline(): HeadlineBean? = suspend fun getCurrentHeadline(): HeadlineBean? =
launchRequest { launchRequest {
api.getCurrentHeadline() api.getCurrentHeadline()
@@ -31,6 +37,12 @@ object PublicChatModel : BaseModel() {
interface Api { interface Api {
/**
* 获取前几条数据
*/
@GET("publicChatTopRecord/getChatForTop50")
suspend fun getTopMessage(): ServiceResult<List<PublicChatMessageBean>>
/** /**
* 获取头条 * 获取头条
*/ */