refactor: 修改database层
修改database层语言为kotlin
This commit is contained in:
parent
8919957c37
commit
023fdbb324
@ -1,42 +1,25 @@
|
|||||||
package com.kaixed.kchat;
|
package com.kaixed.kchat
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application
|
||||||
import android.content.Context;
|
import android.util.Log
|
||||||
import android.util.Log;
|
import com.kaixed.kchat.database.ObjectBox
|
||||||
|
import com.kaixed.kchat.database.ObjectBox.get
|
||||||
import com.kaixed.kchat.database.ObjectBox;
|
import com.kaixed.kchat.database.ObjectBox.init
|
||||||
import com.tencent.mmkv.MMKV;
|
import com.tencent.mmkv.MMKV
|
||||||
|
import io.objectbox.android.Admin
|
||||||
import io.objectbox.android.Admin;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: kaixed
|
* @Author: kaixed
|
||||||
* @Date: 2024/5/4 10:37
|
* @Date: 2024/10/24 17:04
|
||||||
*/
|
*/
|
||||||
public class KchatApplication extends Application {
|
class KchatApplication : Application() {
|
||||||
private static KchatApplication instance;
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
val rootDir = MMKV.initialize(this)
|
||||||
|
Log.d("mmkv root: ", rootDir)
|
||||||
|
|
||||||
@Override
|
init(this)
|
||||||
public void onCreate() {
|
val started = Admin(get()).start(this)
|
||||||
super.onCreate();
|
Log.i("ObjectBoxAdmin", "Started: $started")
|
||||||
instance = this;
|
|
||||||
String rootDir = MMKV.initialize(this);
|
|
||||||
Log.d("mmkv root: ", rootDir);
|
|
||||||
|
|
||||||
ObjectBox.init(this);
|
|
||||||
|
|
||||||
|
|
||||||
boolean started = new Admin(ObjectBox.get()).start(this);
|
|
||||||
Log.i("ObjectBoxAdmin", "Started: " + started);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void attachBaseContext(Context base) {
|
|
||||||
super.attachBaseContext(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static KchatApplication getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,24 +1,21 @@
|
|||||||
package com.kaixed.kchat.database;
|
package com.kaixed.kchat.database
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context
|
||||||
|
import com.kaixed.kchat.database.entity.MyObjectBox
|
||||||
import com.kaixed.kchat.database.entity.MyObjectBox;
|
import io.objectbox.BoxStore
|
||||||
|
|
||||||
import io.objectbox.BoxStore;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author hui
|
* @Author: kaixed
|
||||||
|
* @Date: 2024/10/24 16:57
|
||||||
*/
|
*/
|
||||||
public class ObjectBox {
|
object ObjectBox {
|
||||||
private static BoxStore store;
|
private var store: BoxStore? = null
|
||||||
|
|
||||||
public static void init(Context context) {
|
fun init(context: Context) {
|
||||||
store = MyObjectBox.builder()
|
store = MyObjectBox.builder()
|
||||||
.androidContext(context)
|
.androidContext(context)
|
||||||
.build();
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BoxStore get() {
|
fun get(): BoxStore = store ?: throw IllegalStateException("ObjectBox is not initialized.")
|
||||||
return store;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,28 +1,22 @@
|
|||||||
package com.kaixed.kchat.database;
|
package com.kaixed.kchat.database
|
||||||
|
|
||||||
import static com.kaixed.kchat.utils.Constants.MMKV_USER_SESSION;
|
import com.kaixed.kchat.utils.Constants.MMKV_USER_SESSION
|
||||||
|
import com.tencent.mmkv.MMKV
|
||||||
|
|
||||||
import com.tencent.mmkv.MMKV;
|
/**
|
||||||
|
* @Author: kaixed
|
||||||
|
* @Date: 2024/10/24 16:44
|
||||||
|
*/
|
||||||
|
object UserManager {
|
||||||
|
private const val USERNAME_KEY = "username"
|
||||||
|
private var username: String
|
||||||
|
|
||||||
public class UserManager {
|
init {
|
||||||
|
val mmkv = MMKV.mmkvWithID(MMKV_USER_SESSION)
|
||||||
private static final String USERNAME_KEY = "username";
|
username = mmkv.getString(USERNAME_KEY, "").toString()
|
||||||
private static UserManager instance;
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
private UserManager() {
|
|
||||||
MMKV mmkv = MMKV.mmkvWithID(MMKV_USER_SESSION);
|
|
||||||
username = mmkv.getString(USERNAME_KEY, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized UserManager getInstance() {
|
fun getUsername(): String {
|
||||||
if (instance == null) {
|
return username
|
||||||
instance = new UserManager();
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,92 +1,21 @@
|
|||||||
package com.kaixed.kchat.database.entity;
|
package com.kaixed.kchat.database.entity
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import io.objectbox.annotation.Entity
|
||||||
|
import io.objectbox.annotation.Id
|
||||||
import io.objectbox.annotation.Entity;
|
|
||||||
import io.objectbox.annotation.Id;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: kaixed
|
* @Author: kaixed
|
||||||
* @Date: 2024/5/23 13:51
|
* @Date: 2024/10/24 17:07
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class ChatLists {
|
data class ChatLists(
|
||||||
@Id
|
@Id
|
||||||
public long id;
|
var id: Long = 0L,
|
||||||
private String talkerId;
|
var talkerId: String,
|
||||||
private String nickname;
|
var nickname: String,
|
||||||
private String avatarUrl;
|
var avatarUrl: String,
|
||||||
private String lastContent;
|
var lastContent: String,
|
||||||
private Long timestamp;
|
var timestamp: Long,
|
||||||
private int unread;
|
var unread: Int,
|
||||||
|
)
|
||||||
public long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setId(long id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTalkerId() {
|
|
||||||
return talkerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTalkerId(String talkerId) {
|
|
||||||
this.talkerId = talkerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNickname() {
|
|
||||||
return nickname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNickname(String nickname) {
|
|
||||||
this.nickname = nickname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAvatarUrl() {
|
|
||||||
return avatarUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAvatarUrl(String avatarUrl) {
|
|
||||||
this.avatarUrl = avatarUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLastContent() {
|
|
||||||
return lastContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastContent(String lastContent) {
|
|
||||||
this.lastContent = lastContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimestamp(Long timestamp) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getUnread() {
|
|
||||||
return unread;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUnread(int unread) {
|
|
||||||
this.unread = unread;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "ChatLists{" +
|
|
||||||
"id=" + id +
|
|
||||||
", talkerId='" + talkerId + '\'' +
|
|
||||||
", nickname='" + nickname + '\'' +
|
|
||||||
", avatarUrl='" + avatarUrl + '\'' +
|
|
||||||
", lastContent='" + lastContent + '\'' +
|
|
||||||
", timestamp=" + timestamp +
|
|
||||||
", unread=" + unread +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,109 +1,23 @@
|
|||||||
package com.kaixed.kchat.database.entity;
|
package com.kaixed.kchat.database.entity
|
||||||
|
|
||||||
import io.objectbox.annotation.Entity;
|
import io.objectbox.annotation.Entity
|
||||||
import io.objectbox.annotation.Id;
|
import io.objectbox.annotation.Id
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: kaixed
|
* @Author: kaixed
|
||||||
* @Date: 2024/5/23 13:38
|
* @Date: 2024/10/24 17:08
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Messages {
|
data class Messages(
|
||||||
@Id
|
@Id
|
||||||
public long msgLocalId;
|
var msgLocalId: Long = 0L,
|
||||||
private Long msgSvrId;
|
var msgSvrId: Long,
|
||||||
private String content;
|
var content: String,
|
||||||
private Long timestamp;
|
var timestamp: Long,
|
||||||
private String status;
|
var status: String,
|
||||||
private String senderId;
|
var senderId: String,
|
||||||
private String takerId;
|
var takerId: String,
|
||||||
private String type;
|
var type: String,
|
||||||
private boolean show;
|
var show: Boolean = true,
|
||||||
|
)
|
||||||
public long getMsgLocalId() {
|
|
||||||
return msgLocalId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMsgLocalId(long msgLocalId) {
|
|
||||||
this.msgLocalId = msgLocalId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getMsgSvrId() {
|
|
||||||
return msgSvrId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMsgSvrId(Long msgSvrId) {
|
|
||||||
this.msgSvrId = msgSvrId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContent() {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContent(String content) {
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimestamp(Long timestamp) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(String status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSenderId() {
|
|
||||||
return senderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSenderId(String senderId) {
|
|
||||||
this.senderId = senderId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTakerId() {
|
|
||||||
return takerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTakerId(String takerId) {
|
|
||||||
this.takerId = takerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(String type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isShow() {
|
|
||||||
return show;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShow(boolean show) {
|
|
||||||
this.show = show;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Messages{" +
|
|
||||||
"msgLocalId=" + msgLocalId +
|
|
||||||
", msgSvrId=" + msgSvrId +
|
|
||||||
", content='" + content + '\'' +
|
|
||||||
", timestamp=" + timestamp +
|
|
||||||
", status='" + status + '\'' +
|
|
||||||
", senderId='" + senderId + '\'' +
|
|
||||||
", takerId='" + takerId + '\'' +
|
|
||||||
", type='" + type + '\'' +
|
|
||||||
", show=" + show +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -96,7 +96,7 @@ class ContactRepo {
|
|||||||
fun addContact(contactId: String, message: String): MutableLiveData<ApplyFriend?> {
|
fun addContact(contactId: String, message: String): MutableLiveData<ApplyFriend?> {
|
||||||
val mutableLiveData = MutableLiveData<ApplyFriend?>()
|
val mutableLiveData = MutableLiveData<ApplyFriend?>()
|
||||||
val requestBody = FormBody.Builder()
|
val requestBody = FormBody.Builder()
|
||||||
.add("senderId", UserManager.getInstance().username)
|
.add("senderId", UserManager.getUsername())
|
||||||
.add("receiverId", contactId)
|
.add("receiverId", contactId)
|
||||||
.add("message", message)
|
.add("message", message)
|
||||||
.build()
|
.build()
|
||||||
|
@ -96,8 +96,8 @@ public class WebSocketService extends Service {
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
// 初始化本地存储及其他配置
|
// 初始化本地存储及其他配置
|
||||||
messagesBox = ObjectBox.get().boxFor(Messages.class);
|
messagesBox = ObjectBox.INSTANCE.get().boxFor(Messages.class);
|
||||||
username = UserManager.getInstance().getUsername();
|
username = UserManager.INSTANCE.getUsername();
|
||||||
|
|
||||||
// 创建并配置心跳执行器
|
// 创建并配置心跳执行器
|
||||||
initializeHeartbeatExecutor();
|
initializeHeartbeatExecutor();
|
||||||
|
@ -39,7 +39,7 @@ class ApproveContactRequestActivity : BaseActivity() {
|
|||||||
private fun setOnClickListener() {
|
private fun setOnClickListener() {
|
||||||
binding.tvFinish.setOnClickListener {
|
binding.tvFinish.setOnClickListener {
|
||||||
val contactId = intent.getStringExtra("contactId")
|
val contactId = intent.getStringExtra("contactId")
|
||||||
contactViewModel.acceptContactRequest(UserManager.getInstance().username, contactId!!)
|
contactViewModel.acceptContactRequest(UserManager.getUsername(), contactId!!)
|
||||||
.observe(this) { value ->
|
.observe(this) { value ->
|
||||||
value?.let {
|
value?.let {
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
|
@ -390,8 +390,8 @@ public class ChatActivity extends AppCompatActivity implements OnItemClickListen
|
|||||||
|
|
||||||
|
|
||||||
private void initData() {
|
private void initData() {
|
||||||
messagesBox = ObjectBox.get().boxFor(Messages.class);
|
messagesBox = ObjectBox.INSTANCE.get().boxFor(Messages.class);
|
||||||
username = UserManager.getInstance().getUsername();
|
username = UserManager.INSTANCE.getUsername();
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
friendId = intent.getStringExtra("friendId");
|
friendId = intent.getStringExtra("friendId");
|
||||||
softKeyboardHeight = ConstantsUtil.getKeyboardHeight();
|
softKeyboardHeight = ConstantsUtil.getKeyboardHeight();
|
||||||
@ -480,13 +480,17 @@ public class ChatActivity extends AppCompatActivity implements OnItemClickListen
|
|||||||
private void sendMessage() {
|
private void sendMessage() {
|
||||||
String message = binding.etInput.getText().toString().trim();
|
String message = binding.etInput.getText().toString().trim();
|
||||||
|
|
||||||
Messages messages = new Messages();
|
Messages messages = new Messages(
|
||||||
messages.setTakerId(friendId);
|
0,
|
||||||
messages.setSenderId(username);
|
0,
|
||||||
messages.setContent(message);
|
message,
|
||||||
messages.setStatus("normal");
|
System.currentTimeMillis(),
|
||||||
messages.setType("normal");
|
"normal",
|
||||||
messages.setTimestamp(System.currentTimeMillis());
|
username,
|
||||||
|
friendId,
|
||||||
|
"normal",
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
addData(messages);
|
addData(messages);
|
||||||
|
|
||||||
@ -503,7 +507,7 @@ public class ChatActivity extends AppCompatActivity implements OnItemClickListen
|
|||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
webSocketService.sendMessage(jsonObject.toString(),id);
|
webSocketService.sendMessage(jsonObject.toString(), id);
|
||||||
|
|
||||||
|
|
||||||
binding.etInput.setText("");
|
binding.etInput.setText("");
|
||||||
|
@ -24,7 +24,7 @@ class FriendListActivity : AppCompatActivity() {
|
|||||||
binding = ActivityFriendListBinding.inflate(layoutInflater)
|
binding = ActivityFriendListBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
getFriendList(UserManager.getInstance().username)
|
getFriendList(UserManager.getUsername())
|
||||||
|
|
||||||
if (friendList.isEmpty()) {
|
if (friendList.isEmpty()) {
|
||||||
binding.tvNothing.visibility = View.VISIBLE
|
binding.tvNothing.visibility = View.VISIBLE
|
||||||
|
@ -62,8 +62,8 @@ public class MainActivity extends AppCompatActivity implements OnChatListItemCli
|
|||||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
chatListsBox = ObjectBox.get().boxFor(ChatLists.class);
|
chatListsBox = ObjectBox.INSTANCE.get().boxFor(ChatLists.class);
|
||||||
messagesBox = ObjectBox.get().boxFor(Messages.class);
|
messagesBox = ObjectBox.INSTANCE.get().boxFor(Messages.class);
|
||||||
|
|
||||||
initView();
|
initView();
|
||||||
|
|
||||||
@ -143,14 +143,15 @@ public class MainActivity extends AppCompatActivity implements OnChatListItemCli
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ChatLists createChatList(String talkerId, String content, Long timestamp) {
|
private ChatLists createChatList(String talkerId, String content, Long timestamp) {
|
||||||
ChatLists chatList = new ChatLists();
|
return new ChatLists(
|
||||||
chatList.setAvatarUrl("1");
|
0L,
|
||||||
chatList.setTalkerId(talkerId);
|
talkerId,
|
||||||
chatList.setNickname(talkerId);
|
talkerId,
|
||||||
chatList.setTimestamp(timestamp);
|
"1",
|
||||||
chatList.setLastContent(content);
|
content,
|
||||||
chatList.setUnread(1);
|
timestamp,
|
||||||
return chatList;
|
1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int findChatListIndex(String talkerId) {
|
private int findChatListIndex(String talkerId) {
|
||||||
|
@ -35,7 +35,7 @@ class MessageActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getItems() {
|
private fun getItems() {
|
||||||
contactViewModel.getContactRequestList(UserManager.getInstance().username)
|
contactViewModel.getContactRequestList(UserManager.getUsername())
|
||||||
.observe(this) { value ->
|
.observe(this) { value ->
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
items.addAll(value.data.toMutableList())
|
items.addAll(value.data.toMutableList())
|
||||||
|
@ -1,222 +1,222 @@
|
|||||||
package com.kaixed.kchat.view.adapter;
|
//package com.kaixed.kchat.view.adapter;
|
||||||
|
//
|
||||||
import static com.kaixed.kchat.utils.Constants.TYPE_ITEM_MINE;
|
//import static com.kaixed.kchat.utils.Constants.TYPE_ITEM_MINE;
|
||||||
import static com.kaixed.kchat.utils.Constants.TYPE_ITEM_OTHER;
|
//import static com.kaixed.kchat.utils.Constants.TYPE_ITEM_OTHER;
|
||||||
import static com.kaixed.kchat.utils.Constants.TYPE_MESSAGE_WITHDRAW;
|
//import static com.kaixed.kchat.utils.Constants.TYPE_MESSAGE_WITHDRAW;
|
||||||
|
//
|
||||||
import android.annotation.SuppressLint;
|
//import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
//import android.content.Context;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
//import android.graphics.drawable.ColorDrawable;
|
||||||
import android.text.SpannableString;
|
//import android.text.SpannableString;
|
||||||
import android.view.LayoutInflater;
|
//import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
//import android.view.View;
|
||||||
import android.view.ViewGroup;
|
//import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
//import android.widget.ImageView;
|
||||||
import android.widget.PopupWindow;
|
//import android.widget.PopupWindow;
|
||||||
import android.widget.TextView;
|
//import android.widget.TextView;
|
||||||
|
//
|
||||||
import androidx.annotation.NonNull;
|
//import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
//import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.window.layout.WindowMetrics;
|
//import androidx.window.layout.WindowMetrics;
|
||||||
import androidx.window.layout.WindowMetricsCalculator;
|
//import androidx.window.layout.WindowMetricsCalculator;
|
||||||
|
//
|
||||||
import com.kaixed.kchat.R;
|
//import com.kaixed.kchat.R;
|
||||||
import com.kaixed.kchat.database.entity.Messages;
|
//import com.kaixed.kchat.database.entity.Messages;
|
||||||
import com.kaixed.kchat.database.ObjectBox;
|
//import com.kaixed.kchat.database.ObjectBox;
|
||||||
import com.kaixed.kchat.database.UserManager;
|
//import com.kaixed.kchat.database.UserManager;
|
||||||
import com.kaixed.kchat.utils.ImageSpanUtil;
|
//import com.kaixed.kchat.utils.ImageSpanUtil;
|
||||||
|
//
|
||||||
import java.util.LinkedList;
|
//import java.util.LinkedList;
|
||||||
|
//
|
||||||
import io.objectbox.Box;
|
//import io.objectbox.Box;
|
||||||
|
//
|
||||||
/**
|
///**
|
||||||
* @Author: kaixed
|
// * @Author: kaixed
|
||||||
* @Date: 2024/5/4 22:48
|
// * @Date: 2024/5/4 22:48
|
||||||
*/
|
// */
|
||||||
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
//public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
private final LinkedList<Messages> messages;
|
// private final LinkedList<Messages> messages;
|
||||||
private final Context mContext;
|
// private final Context mContext;
|
||||||
|
//
|
||||||
public ChatAdapter(Context mContext, LinkedList<Messages> messages) {
|
// public ChatAdapter(Context mContext, LinkedList<Messages> messages) {
|
||||||
this.messages = messages;
|
// this.messages = messages;
|
||||||
this.mContext = mContext;
|
// this.mContext = mContext;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@NonNull
|
// @NonNull
|
||||||
@Override
|
// @Override
|
||||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
// public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
RecyclerView.ViewHolder viewHolder;
|
// RecyclerView.ViewHolder viewHolder;
|
||||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
// LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||||
if (viewType == TYPE_ITEM_MINE) {
|
// if (viewType == TYPE_ITEM_MINE) {
|
||||||
View view = inflater.inflate(R.layout.chat_recycle_item_mine, parent, false);
|
// View view = inflater.inflate(R.layout.chat_recycle_item_mine, parent, false);
|
||||||
viewHolder = new MineViewHolder(view);
|
// viewHolder = new MineViewHolder(view);
|
||||||
} else if (viewType == TYPE_ITEM_OTHER) {
|
// } else if (viewType == TYPE_ITEM_OTHER) {
|
||||||
View view = inflater.inflate(R.layout.chat_recycle_item_other, parent, false);
|
// View view = inflater.inflate(R.layout.chat_recycle_item_other, parent, false);
|
||||||
viewHolder = new OtherViewHolder(view);
|
// viewHolder = new OtherViewHolder(view);
|
||||||
} else {
|
// } else {
|
||||||
View view = inflater.inflate(R.layout.chat_recycle_item_withdraw, parent, false);
|
// View view = inflater.inflate(R.layout.chat_recycle_item_withdraw, parent, false);
|
||||||
viewHolder = new WithdrawViewHolder(view);
|
// viewHolder = new WithdrawViewHolder(view);
|
||||||
}
|
// }
|
||||||
return viewHolder;
|
// return viewHolder;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
// public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||||
|
//
|
||||||
Messages singleMessage = messages.get(position);
|
// Messages singleMessage = messages.get(position);
|
||||||
if (singleMessage == null) {
|
// if (singleMessage == null) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
if (holder.getItemViewType() == TYPE_ITEM_MINE) {
|
// if (holder.getItemViewType() == TYPE_ITEM_MINE) {
|
||||||
MineViewHolder mineViewHolder = (MineViewHolder) holder;
|
// MineViewHolder mineViewHolder = (MineViewHolder) holder;
|
||||||
SpannableString spannableString = ImageSpanUtil.setEmojiSpan(mContext, singleMessage.getContent(), (int) mineViewHolder.mTvContent.getTextSize());
|
// SpannableString spannableString = ImageSpanUtil.setEmojiSpan(mContext, singleMessage.getContent(), (int) mineViewHolder.mTvContent.getTextSize());
|
||||||
|
//
|
||||||
mineViewHolder.mTvContent.setText(spannableString);
|
// mineViewHolder.mTvContent.setText(spannableString);
|
||||||
|
//
|
||||||
mineViewHolder.mTvContent.setOnLongClickListener(v -> {
|
// mineViewHolder.mTvContent.setOnLongClickListener(v -> {
|
||||||
showPopupWindow(v, position);
|
// showPopupWindow(v, position);
|
||||||
return true;
|
// return true;
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
} else if (holder.getItemViewType() == TYPE_ITEM_OTHER) {
|
// } else if (holder.getItemViewType() == TYPE_ITEM_OTHER) {
|
||||||
OtherViewHolder otherViewHolder = (OtherViewHolder) holder;
|
// OtherViewHolder otherViewHolder = (OtherViewHolder) holder;
|
||||||
|
//
|
||||||
SpannableString spannableString = ImageSpanUtil.setEmojiSpan(mContext, singleMessage.getContent(), (int) otherViewHolder.mTvContent.getTextSize());
|
// SpannableString spannableString = ImageSpanUtil.setEmojiSpan(mContext, singleMessage.getContent(), (int) otherViewHolder.mTvContent.getTextSize());
|
||||||
|
//
|
||||||
otherViewHolder.mTvContent.setText(spannableString);
|
// otherViewHolder.mTvContent.setText(spannableString);
|
||||||
otherViewHolder.mTvContent.setOnLongClickListener(v -> {
|
// otherViewHolder.mTvContent.setOnLongClickListener(v -> {
|
||||||
showPopupWindow(v, position);
|
// showPopupWindow(v, position);
|
||||||
return true;
|
// return true;
|
||||||
});
|
// });
|
||||||
} else {
|
// } else {
|
||||||
WithdrawViewHolder mineViewHolder = (WithdrawViewHolder) holder;
|
// WithdrawViewHolder mineViewHolder = (WithdrawViewHolder) holder;
|
||||||
mineViewHolder.bindData(singleMessage.getSenderId());
|
// mineViewHolder.bindData(singleMessage.getSenderId());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* 用来显示消息长按弹窗
|
// * 用来显示消息长按弹窗
|
||||||
*/
|
// */
|
||||||
private void showPopupWindow(@NonNull View textView, int position) {
|
// private void showPopupWindow(@NonNull View textView, int position) {
|
||||||
@SuppressLint("InflateParams") View popupView = LayoutInflater.from(mContext).inflate(R.layout.popwindows, null);
|
// @SuppressLint("InflateParams") View popupView = LayoutInflater.from(mContext).inflate(R.layout.popwindows, null);
|
||||||
|
//
|
||||||
PopupWindow popupWindow = new PopupWindow(popupView,
|
// PopupWindow popupWindow = new PopupWindow(popupView,
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
// ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
//
|
||||||
popupWindow.setFocusable(true);
|
// popupWindow.setFocusable(true);
|
||||||
popupWindow.setBackgroundDrawable(new ColorDrawable());
|
// popupWindow.setBackgroundDrawable(new ColorDrawable());
|
||||||
|
//
|
||||||
|
//
|
||||||
popupView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
// popupView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||||
int popupWidth = popupView.getMeasuredWidth();
|
// int popupWidth = popupView.getMeasuredWidth();
|
||||||
int popupHeight = popupView.getMeasuredHeight();
|
// int popupHeight = popupView.getMeasuredHeight();
|
||||||
|
//
|
||||||
int anchorWidth = textView.getWidth();
|
// int anchorWidth = textView.getWidth();
|
||||||
int anchorHeight = textView.getHeight();
|
// int anchorHeight = textView.getHeight();
|
||||||
int offsetX = (anchorWidth - popupWidth) / 2;
|
// int offsetX = (anchorWidth - popupWidth) / 2;
|
||||||
|
//
|
||||||
int offset = 15;
|
// int offset = 15;
|
||||||
|
//
|
||||||
ImageView mIvArrowUp = popupView.findViewById(R.id.iv_arrow_up);
|
// ImageView mIvArrowUp = popupView.findViewById(R.id.iv_arrow_up);
|
||||||
ImageView mIvArrowDown = popupView.findViewById(R.id.iv_arrow_down);
|
// ImageView mIvArrowDown = popupView.findViewById(R.id.iv_arrow_down);
|
||||||
|
//
|
||||||
if (getDistanceFromTop(textView) > anchorHeight) {
|
// if (getDistanceFromTop(textView) > anchorHeight) {
|
||||||
popupWindow.showAsDropDown(textView, offsetX, -offset - anchorHeight - popupHeight);
|
// popupWindow.showAsDropDown(textView, offsetX, -offset - anchorHeight - popupHeight);
|
||||||
mIvArrowUp.setVisibility(View.GONE);
|
// mIvArrowUp.setVisibility(View.GONE);
|
||||||
mIvArrowDown.setVisibility(View.VISIBLE);
|
// mIvArrowDown.setVisibility(View.VISIBLE);
|
||||||
} else {
|
// } else {
|
||||||
popupWindow.showAsDropDown(textView, offsetX, 10);
|
// popupWindow.showAsDropDown(textView, offsetX, 10);
|
||||||
mIvArrowUp.setVisibility(View.VISIBLE);
|
// mIvArrowUp.setVisibility(View.VISIBLE);
|
||||||
mIvArrowDown.setVisibility(View.GONE);
|
// mIvArrowDown.setVisibility(View.GONE);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
ImageView mIvWithdraw = popupView.findViewById(R.id.iv_withdraw);
|
// ImageView mIvWithdraw = popupView.findViewById(R.id.iv_withdraw);
|
||||||
|
//
|
||||||
mIvWithdraw.setOnClickListener(v -> {
|
// mIvWithdraw.setOnClickListener(v -> {
|
||||||
messages.get(position).setStatus("withdraw");
|
// messages.get(position).setStatus("withdraw");
|
||||||
updateDb(messages.get(position));
|
// updateDb(messages.get(position));
|
||||||
notifyItemChanged(position);
|
// notifyItemChanged(position);
|
||||||
|
//
|
||||||
popupWindow.dismiss();
|
// popupWindow.dismiss();
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void updateDb(Messages messages) {
|
// private void updateDb(Messages messages) {
|
||||||
Box<Messages> messagesBox = ObjectBox.get().boxFor(Messages.class);
|
// Box<Messages> messagesBox = ObjectBox.get().boxFor(Messages.class);
|
||||||
messagesBox.put(messages);
|
// messagesBox.put(messages);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private int getDistanceFromTop(View view) {
|
// private int getDistanceFromTop(View view) {
|
||||||
int[] location = new int[2];
|
// int[] location = new int[2];
|
||||||
view.getLocationOnScreen(location);
|
// view.getLocationOnScreen(location);
|
||||||
//location[0]指的是横向距离
|
// //location[0]指的是横向距离
|
||||||
return location[1];
|
// return location[1];
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private int getDistanceFromBottom(@NonNull View view) {
|
// private int getDistanceFromBottom(@NonNull View view) {
|
||||||
// 获取控件在屏幕上的位置
|
// // 获取控件在屏幕上的位置
|
||||||
int[] location = new int[2];
|
// int[] location = new int[2];
|
||||||
view.getLocationOnScreen(location);
|
// view.getLocationOnScreen(location);
|
||||||
// 获取屏幕高度
|
// // 获取屏幕高度
|
||||||
WindowMetrics windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(mContext);
|
// WindowMetrics windowMetrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(mContext);
|
||||||
int screenHeight = windowMetrics.getBounds().height();
|
// int screenHeight = windowMetrics.getBounds().height();
|
||||||
// 计算控件底部到屏幕底部的距离
|
// // 计算控件底部到屏幕底部的距离
|
||||||
int viewBottom = location[1] + view.getHeight();
|
// int viewBottom = location[1] + view.getHeight();
|
||||||
return screenHeight - viewBottom;
|
// return screenHeight - viewBottom;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public int getItemViewType(int position) {
|
// public int getItemViewType(int position) {
|
||||||
String curUser = UserManager.getInstance().getUsername();
|
// String curUser = UserManager.getInstance().getUsername();
|
||||||
if ("withdraw".equals(messages.get(position).getStatus())) {
|
// if ("withdraw".equals(messages.get(position).getStatus())) {
|
||||||
return TYPE_MESSAGE_WITHDRAW;
|
// return TYPE_MESSAGE_WITHDRAW;
|
||||||
}
|
// }
|
||||||
return curUser.equals(messages.get(position).getSenderId()) ? TYPE_ITEM_MINE : TYPE_ITEM_OTHER;
|
// return curUser.equals(messages.get(position).getSenderId()) ? TYPE_ITEM_MINE : TYPE_ITEM_OTHER;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public int getItemCount() {
|
// public int getItemCount() {
|
||||||
return messages.isEmpty() ? 0 : messages.size();
|
// return messages.isEmpty() ? 0 : messages.size();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static class MineViewHolder extends RecyclerView.ViewHolder {
|
// static class MineViewHolder extends RecyclerView.ViewHolder {
|
||||||
private final TextView mTvContent;
|
// private final TextView mTvContent;
|
||||||
|
//
|
||||||
public MineViewHolder(@NonNull View itemView) {
|
// public MineViewHolder(@NonNull View itemView) {
|
||||||
super(itemView);
|
// super(itemView);
|
||||||
mTvContent = itemView.findViewById(R.id.tv_mine_content);
|
// mTvContent = itemView.findViewById(R.id.tv_mine_content);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void bindData(Messages singleMessage) {
|
// private void bindData(Messages singleMessage) {
|
||||||
mTvContent.setText(singleMessage.getContent());
|
// mTvContent.setText(singleMessage.getContent());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static class OtherViewHolder extends RecyclerView.ViewHolder {
|
// static class OtherViewHolder extends RecyclerView.ViewHolder {
|
||||||
private final TextView mTvContent;
|
// private final TextView mTvContent;
|
||||||
|
//
|
||||||
public OtherViewHolder(@NonNull View itemView) {
|
// public OtherViewHolder(@NonNull View itemView) {
|
||||||
super(itemView);
|
// super(itemView);
|
||||||
mTvContent = itemView.findViewById(R.id.tv_other_content);
|
// mTvContent = itemView.findViewById(R.id.tv_other_content);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void bindData(Messages singleMessage) {
|
// private void bindData(Messages singleMessage) {
|
||||||
mTvContent.setText(singleMessage.getContent());
|
// mTvContent.setText(singleMessage.getContent());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static class WithdrawViewHolder extends RecyclerView.ViewHolder {
|
// static class WithdrawViewHolder extends RecyclerView.ViewHolder {
|
||||||
private final TextView mTvNickname;
|
// private final TextView mTvNickname;
|
||||||
|
//
|
||||||
public WithdrawViewHolder(@NonNull View itemView) {
|
// public WithdrawViewHolder(@NonNull View itemView) {
|
||||||
super(itemView);
|
// super(itemView);
|
||||||
mTvNickname = itemView.findViewById(R.id.tv_user_nickname);
|
// mTvNickname = itemView.findViewById(R.id.tv_user_nickname);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void bindData(String nickname) {
|
// private void bindData(String nickname) {
|
||||||
mTvNickname.setText(nickname);
|
// mTvNickname.setText(nickname);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
191
app/src/main/java/com/kaixed/kchat/view/adapter/ChatAdapter.kt
Normal file
191
app/src/main/java/com/kaixed/kchat/view/adapter/ChatAdapter.kt
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
package com.kaixed.kchat.view.adapter
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.ColorDrawable
|
||||||
|
import android.text.SpannableString
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.PopupWindow
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.window.layout.WindowMetrics
|
||||||
|
import androidx.window.layout.WindowMetricsCalculator
|
||||||
|
import com.kaixed.kchat.R
|
||||||
|
import com.kaixed.kchat.database.entity.Messages
|
||||||
|
import com.kaixed.kchat.database.ObjectBox
|
||||||
|
import com.kaixed.kchat.database.UserManager
|
||||||
|
import com.kaixed.kchat.utils.Constants.TYPE_ITEM_MINE
|
||||||
|
import com.kaixed.kchat.utils.Constants.TYPE_ITEM_OTHER
|
||||||
|
import com.kaixed.kchat.utils.Constants.TYPE_MESSAGE_WITHDRAW
|
||||||
|
import com.kaixed.kchat.utils.ImageSpanUtil
|
||||||
|
import com.kaixed.kchat.databinding.ChatRecycleItemMineBinding
|
||||||
|
import com.kaixed.kchat.databinding.ChatRecycleItemOtherBinding
|
||||||
|
import com.kaixed.kchat.databinding.ChatRecycleItemWithdrawBinding
|
||||||
|
import com.kaixed.kchat.databinding.PopwindowsBinding
|
||||||
|
import java.util.LinkedList
|
||||||
|
import io.objectbox.Box
|
||||||
|
|
||||||
|
class ChatAdapter(
|
||||||
|
private val context: Context,
|
||||||
|
private val messages: LinkedList<Messages>
|
||||||
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
return when (viewType) {
|
||||||
|
TYPE_ITEM_MINE -> {
|
||||||
|
val binding = ChatRecycleItemMineBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
MineViewHolder(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE_ITEM_OTHER -> {
|
||||||
|
val binding = ChatRecycleItemOtherBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
OtherViewHolder(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
val binding = ChatRecycleItemWithdrawBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
WithdrawViewHolder(binding)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
val singleMessage = messages[position]
|
||||||
|
|
||||||
|
when (holder) {
|
||||||
|
is MineViewHolder -> {
|
||||||
|
val spannableString = ImageSpanUtil.setEmojiSpan(
|
||||||
|
context,
|
||||||
|
singleMessage.content,
|
||||||
|
holder.binding.tvMineContent.textSize.toInt()
|
||||||
|
)
|
||||||
|
holder.binding.tvMineContent.text = spannableString
|
||||||
|
holder.binding.tvMineContent.setOnLongClickListener {
|
||||||
|
showPopupWindow(it, position)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is OtherViewHolder -> {
|
||||||
|
val spannableString = ImageSpanUtil.setEmojiSpan(
|
||||||
|
context,
|
||||||
|
singleMessage.content,
|
||||||
|
holder.binding.tvOtherContent.textSize.toInt()
|
||||||
|
)
|
||||||
|
holder.binding.tvOtherContent.text = spannableString
|
||||||
|
holder.binding.tvOtherContent.setOnLongClickListener {
|
||||||
|
showPopupWindow(it, position)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is WithdrawViewHolder -> {
|
||||||
|
holder.bindData(singleMessage.senderId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun showPopupWindow(view: View, position: Int) {
|
||||||
|
val binding: PopwindowsBinding = PopwindowsBinding.inflate(LayoutInflater.from(context))
|
||||||
|
val popupWindow: PopupWindow = PopupWindow(
|
||||||
|
binding.root,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
|
).apply {
|
||||||
|
isFocusable = true
|
||||||
|
isOutsideTouchable = true
|
||||||
|
setBackgroundDrawable(ColorDrawable())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动态计算 PopupWindow 的显示位置
|
||||||
|
val location = IntArray(2)
|
||||||
|
view.getLocationOnScreen(location)
|
||||||
|
|
||||||
|
// 测量 PopupWindow 的宽度和高度
|
||||||
|
binding.root.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
|
||||||
|
val popupWidth = binding.root.measuredWidth
|
||||||
|
val popupHeight = binding.root.measuredHeight
|
||||||
|
|
||||||
|
// 计算水平居中的偏移量
|
||||||
|
val offsetX = (view.width - popupWidth) / 2
|
||||||
|
|
||||||
|
// 上下方显示的 padding
|
||||||
|
val somePadding = (context.resources.displayMetrics.density * 10).toInt()
|
||||||
|
|
||||||
|
// 获取 view 顶部和底部在屏幕中的绝对位置
|
||||||
|
val viewTop = location[1]
|
||||||
|
val viewBottom = location[1] + view.height
|
||||||
|
|
||||||
|
// 判断 PopupWindow 显示在上方是否有足够空间
|
||||||
|
val isEnoughSpaceAbove = viewTop >= popupHeight + somePadding
|
||||||
|
val isEnoughSpaceBelow =
|
||||||
|
(context.resources.displayMetrics.heightPixels - viewBottom) >= popupHeight + somePadding
|
||||||
|
|
||||||
|
// 计算 Y 轴的偏移量,根据空间选择上方或下方显示
|
||||||
|
val offsetY = if (isEnoughSpaceAbove) {
|
||||||
|
-view.height - popupHeight - somePadding
|
||||||
|
} else if (isEnoughSpaceBelow) {
|
||||||
|
view.height + somePadding
|
||||||
|
} else {
|
||||||
|
// 如果上下空间都不足,选择最小偏移量的显示(可以根据需求调整)
|
||||||
|
view.height / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示 PopupWindow,锚点是 view
|
||||||
|
popupWindow.showAsDropDown(view, offsetX, offsetY)
|
||||||
|
|
||||||
|
// 设置点击事件
|
||||||
|
binding.ivWithdraw.setOnClickListener {
|
||||||
|
messages[position].status = "withdraw"
|
||||||
|
updateDb(messages[position])
|
||||||
|
notifyItemChanged(position)
|
||||||
|
popupWindow.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun updateDb(message: Messages) {
|
||||||
|
val messagesBox: Box<Messages> = ObjectBox.get().boxFor(Messages::class.java)
|
||||||
|
messagesBox.put(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
val curUser = UserManager.getUsername()
|
||||||
|
return if (messages[position].status == "withdraw") {
|
||||||
|
TYPE_MESSAGE_WITHDRAW
|
||||||
|
} else {
|
||||||
|
if (curUser == messages[position].senderId) TYPE_ITEM_MINE else TYPE_ITEM_OTHER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = messages.size
|
||||||
|
|
||||||
|
class MineViewHolder(val binding: ChatRecycleItemMineBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root)
|
||||||
|
|
||||||
|
class OtherViewHolder(val binding: ChatRecycleItemOtherBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root)
|
||||||
|
|
||||||
|
class WithdrawViewHolder(val binding: ChatRecycleItemWithdrawBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bindData(nickname: String) {
|
||||||
|
binding.tvUserNickname.text = nickname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,6 @@ package com.kaixed.kchat.view.adapter;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
Loading…
Reference in New Issue
Block a user