Merge branch 'yinyou_develop' into yinyou_develop_4.3.0_merge

# Conflicts:
#	app/src/main/java/com/yizhuan/erban/MainActivity.java
#	app/src/main/java/com/yizhuan/erban/skill/SKillDataParser.kt
#	app/src/main/java/com/yizhuan/erban/skill/activity/AddSkillActivity.kt
#	app/src/main/java/com/yizhuan/erban/skill/activity/EditSkillActivity.kt
#	app/src/main/java/com/yizhuan/erban/skill/activity/SkillEditableDelegate.kt
#	app/src/main/java/com/yizhuan/erban/skill/adapter/MineSkillCardAdapter.kt
#	app/src/main/java/com/yizhuan/erban/skill/adapter/SkillSelectionAdapter.kt
#	app/src/main/java/com/yizhuan/erban/skill/dialog/SkillSelectionDialog.kt
#	app/src/main/java/com/yizhuan/erban/skill/widget/ItemAttribute.kt
#	app/src/main/java/com/yizhuan/erban/skill/widget/RecordIResourceItem.kt
#	app/src/main/java/com/yizhuan/erban/skill/widget/SkillAttribute.kt
#	app/src/main/java/com/yizhuan/erban/skill/widget/SkillCardView.kt
#	app/src/main/java/com/yizhuan/erban/skill/widget/SkillItemHelper.kt
#	app/src/main/java/com/yizhuan/erban/skill/widget/TimerRecorderView.kt
#	app/src/main/res/layout/dialog_add_skill_item.xml
#	app/src/main/res/layout/layout_ok_cancel_dialog.xml
#	app/src/main/res/layout/layout_skill_audio.xml
#	app/src/main/res/values/attrs.xml
#	app/src/main/res/values/strings.xml
#	core/src/main/java/com/yizhuan/xchat_android_core/im/custom/bean/CustomAttachParser.java
#	core/src/main/java/com/yizhuan/xchat_android_core/im/custom/bean/CustomAttachment.java
#	core/src/main/java/com/yizhuan/xchat_android_core/skill/entity/SkillRecordEntity.kt
This commit is contained in:
yitao_hello
2022-02-27 19:12:02 +08:00
100 changed files with 1210 additions and 524 deletions

View File

@@ -249,10 +249,7 @@ dependencies {
implementation 'it.sephiroth.android.library.imagezoom:library:1.0.4' implementation 'it.sephiroth.android.library.imagezoom:library:1.0.4'
// 易盾一键登录 // 易盾一键登录
implementation(name: 'quicklogin_libary-external-release', ext: 'aar') implementation 'io.github.yidun:quicklogin:3.1.5'
implementation(name: 'CMCCSSOSDK-wy-release', ext: 'aar')
implementation(name: 'Ui-factory_oauth_mobile_3.9.1.7_external', ext: 'aar')
implementation(name: 'CTAccount_sdk_api_v3.8.3_all', ext: 'aar')
implementation 'com.github.fodroid:XRadioGroup:v1.5' implementation 'com.github.fodroid:XRadioGroup:v1.5'
implementation files('libs/msa_mdid_1.0.13.aar') implementation files('libs/msa_mdid_1.0.13.aar')
@@ -278,7 +275,7 @@ String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.goog
repositories { repositories {
flatDir { flatDir {
dirs 'aliyun-libs', 'quick-pass-libs', 'com.huawei.agconnect' dirs 'aliyun-libs','com.huawei.agconnect'
} }
mavenCentral() mavenCentral()

View File

@@ -329,8 +329,11 @@
#一键登录 #一键登录
-dontwarn com.cmic.sso.sdk.** -dontwarn com.cmic.sso.sdk.**
-keep public class com.cmic.sso.sdk.**{*;} -keep class com.cmic.sso.**{*;}
-keep class cn.com.chinatelecom.account.api.**{*;} -dontwarn com.sdk.**
-keep class com.sdk.** { *;}
-keep class cn.com.chinatelecom.account.**{*;}
-keep public class * extends android.view.View
-keep class com.netease.nis.quicklogin.entity.**{*;} -keep class com.netease.nis.quicklogin.entity.**{*;}
-keep class com.netease.nis.quicklogin.listener.**{*;} -keep class com.netease.nis.quicklogin.listener.**{*;}
-keep class com.netease.nis.quicklogin.QuickLogin{ -keep class com.netease.nis.quicklogin.QuickLogin{
@@ -346,6 +349,11 @@
public <methods>; public <methods>;
public <fields>; public <fields>;
} }
-keep class com.netease.nis.basesdk.**{
public *;
protected *;
}
-keep class com.bun.miitmdid.core.** {*;} -keep class com.bun.miitmdid.core.** {*;}
-keep class com.bun.** {*;} -keep class com.bun.** {*;}
-keep class com.asus.msa.** {*;} -keep class com.asus.msa.** {*;}

View File

@@ -93,6 +93,7 @@ import com.yizhuan.erban.ui.im.chat.MsgViewHolderMatch;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderOnline; import com.yizhuan.erban.ui.im.chat.MsgViewHolderOnline;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderRedPackage; import com.yizhuan.erban.ui.im.chat.MsgViewHolderRedPackage;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderRedPacket; import com.yizhuan.erban.ui.im.chat.MsgViewHolderRedPacket;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderSkill;
import com.yizhuan.erban.ui.im.chat.MsgViewHolderText; import com.yizhuan.erban.ui.im.chat.MsgViewHolderText;
import com.yizhuan.erban.ui.im.chat.SignInNoticeMsgViewHolder; import com.yizhuan.erban.ui.im.chat.SignInNoticeMsgViewHolder;
import com.yizhuan.erban.ui.im.chat.SysMsgV2ViewHolder; import com.yizhuan.erban.ui.im.chat.SysMsgV2ViewHolder;
@@ -148,6 +149,7 @@ import com.yizhuan.xchat_android_core.im.custom.bean.OpenRoomNotiAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.OpenSignInAttachment; import com.yizhuan.xchat_android_core.im.custom.bean.OpenSignInAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RedPackageAttachment; import com.yizhuan.xchat_android_core.im.custom.bean.RedPackageAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.RedPacketAttachment; import com.yizhuan.xchat_android_core.im.custom.bean.RedPacketAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.SkillMsgAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.SysMsgAttachment; import com.yizhuan.xchat_android_core.im.custom.bean.SysMsgAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.SysMsgV2Attachment; import com.yizhuan.xchat_android_core.im.custom.bean.SysMsgV2Attachment;
import com.yizhuan.xchat_android_core.initial.InitialModel; import com.yizhuan.xchat_android_core.initial.InitialModel;
@@ -415,6 +417,9 @@ public class MainActivity extends BaseMvpActivity<IMainView, MainPresenter>
NimUIKit.registerMsgItemViewHolder(ChatHintAttachment.class, MsgViewHolderChatHint.class); NimUIKit.registerMsgItemViewHolder(ChatHintAttachment.class, MsgViewHolderChatHint.class);
NimUIKit.registerMsgItemViewHolder(MatchAttachment.class, MsgViewHolderMatch.class); NimUIKit.registerMsgItemViewHolder(MatchAttachment.class, MsgViewHolderMatch.class);
//技能卡
NimUIKit.registerMsgItemViewHolder(SkillMsgAttachment.class, MsgViewHolderSkill.class);
//CP //CP
NimUIKit.registerMsgItemViewHolder(CpInviteAttachment.class, MsgViewHolderText.class); NimUIKit.registerMsgItemViewHolder(CpInviteAttachment.class, MsgViewHolderText.class);
NimUIKit.setSessionListener(listener); NimUIKit.setSessionListener(listener);

View File

@@ -5,6 +5,8 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
@@ -15,6 +17,7 @@ import com.yizhuan.erban.R;
import com.yizhuan.erban.avroom.adapter.RoomNormalListAdapter; import com.yizhuan.erban.avroom.adapter.RoomNormalListAdapter;
import com.yizhuan.erban.avroom.presenter.RoomBlackPresenter; import com.yizhuan.erban.avroom.presenter.RoomBlackPresenter;
import com.yizhuan.erban.avroom.view.IRoomBlackView; import com.yizhuan.erban.avroom.view.IRoomBlackView;
import com.yizhuan.erban.ui.utils.RVDelegate;
import com.yizhuan.xchat_android_core.auth.AuthModel; import com.yizhuan.xchat_android_core.auth.AuthModel;
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager; import com.yizhuan.xchat_android_core.manager.AvRoomDataManager;
import com.yizhuan.erban.base.BaseMvpActivity; import com.yizhuan.erban.base.BaseMvpActivity;
@@ -22,6 +25,7 @@ import com.yizhuan.erban.common.widget.dialog.DialogManager;
import com.yizhuan.xchat_android_core.room.model.AvRoomModel; import com.yizhuan.xchat_android_core.room.model.AvRoomModel;
import com.yizhuan.xchat_android_core.super_admin.model.SuperAdminModel; import com.yizhuan.xchat_android_core.super_admin.model.SuperAdminModel;
import com.yizhuan.xchat_android_core.super_admin.util.SuperAdminUtil; import com.yizhuan.xchat_android_core.super_admin.util.SuperAdminUtil;
import com.yizhuan.xchat_android_core.user.bean.UserInfo;
import com.yizhuan.xchat_android_core.utils.net.DontWarnObserver; import com.yizhuan.xchat_android_core.utils.net.DontWarnObserver;
import com.yizhuan.xchat_android_library.base.factory.CreatePresenter; import com.yizhuan.xchat_android_library.base.factory.CreatePresenter;
import com.yizhuan.xchat_android_library.utils.JavaUtil; import com.yizhuan.xchat_android_library.utils.JavaUtil;
@@ -43,7 +47,6 @@ import java.util.Objects;
@CreatePresenter(RoomBlackPresenter.class) @CreatePresenter(RoomBlackPresenter.class)
public class RoomBlackListActivity extends BaseMvpActivity<IRoomBlackView, RoomBlackPresenter> public class RoomBlackListActivity extends BaseMvpActivity<IRoomBlackView, RoomBlackPresenter>
implements RoomNormalListAdapter.OnRoomNormalListOperationClickListener, IRoomBlackView { implements RoomNormalListAdapter.OnRoomNormalListOperationClickListener, IRoomBlackView {
private TextView count;
private RecyclerView recyclerView; private RecyclerView recyclerView;
private RoomNormalListAdapter normalListAdapter; private RoomNormalListAdapter normalListAdapter;
@@ -58,22 +61,18 @@ public class RoomBlackListActivity extends BaseMvpActivity<IRoomBlackView, RoomB
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_room_black_list); setContentView(R.layout.activity_room_black_list);
initWhiteTitleBar("黑名单"); initWhiteTitleBar("黑名单(0)人");
initView(); initView();
showLoading();
loadData();
mSuperAdminModel = new SuperAdminModel(); mSuperAdminModel = new SuperAdminModel();
loadData();
} }
private void loadData() { private void loadData() {
getMvpPresenter().queryBlackList(500); queryBlackListSuccess(AvRoomDataManager.get().mRoomLimitMemberList);
} }
private void initView() { private void initView() {
count = (TextView) findViewById(R.id.count); recyclerView = findViewById(R.id.recycler_view);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
normalListAdapter = new RoomNormalListAdapter(this); normalListAdapter = new RoomNormalListAdapter(this);
normalListAdapter.setListOperationClickListener(this); normalListAdapter.setListOperationClickListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setLayoutManager(new LinearLayoutManager(this));
@@ -149,10 +148,10 @@ public class RoomBlackListActivity extends BaseMvpActivity<IRoomBlackView, RoomB
if (chatRoomMemberList != null && chatRoomMemberList.size() > 0) { if (chatRoomMemberList != null && chatRoomMemberList.size() > 0) {
normalListAdapter.setNormalList(chatRoomMemberList); normalListAdapter.setNormalList(chatRoomMemberList);
normalListAdapter.notifyDataSetChanged(); normalListAdapter.notifyDataSetChanged();
count.setText("黑名单" + chatRoomMemberList.size() + ""); mTitleBar.setTitle("黑名单(" + chatRoomMemberList.size() + ")");
} else { } else {
showNoData("暂没有设置黑名单"); showNoData("暂没有设置黑名单");
count.setText("黑名单0"); mTitleBar.setTitle("黑名单(0)");
} }
} }
@@ -168,20 +167,20 @@ public class RoomBlackListActivity extends BaseMvpActivity<IRoomBlackView, RoomB
if (!ListUtils.isListEmpty(normalList)) { if (!ListUtils.isListEmpty(normalList)) {
hideStatus(); hideStatus();
ListIterator<ChatRoomMember> iterator = normalList.listIterator(); ListIterator<ChatRoomMember> iterator = normalList.listIterator();
for (; iterator.hasNext(); ) { while (iterator.hasNext()) {
if (Objects.equals(iterator.next().getAccount(), chatRoomMember.getAccount())) { if (Objects.equals(iterator.next().getAccount(), chatRoomMember.getAccount())) {
iterator.remove(); iterator.remove();
} }
} }
normalListAdapter.notifyDataSetChanged(); mTitleBar.setTitle("黑名单(" + normalList.size() + ")人");
count.setText("黑名单" + normalList.size() + "");
if (normalList.size() == 0) { if (normalList.size() == 0) {
showNoData("暂没有设置黑名单"); showNoData("暂没有设置黑名单");
} }
} else { } else {
showNoData("暂没有设置黑名单"); showNoData("暂没有设置黑名单");
count.setText("黑名单0"); mTitleBar.setTitle("黑名单(0)");
} }
normalListAdapter.notifyDataSetChanged();
toast("操作成功"); toast("操作成功");
} }

View File

@@ -3,10 +3,10 @@ package com.yizhuan.erban.avroom.activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.netease.nim.uikit.StatusBarUtil; import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember; import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
@@ -34,7 +34,6 @@ import java.util.Objects;
@CreatePresenter(RoomManagerPresenter.class) @CreatePresenter(RoomManagerPresenter.class)
public class RoomManagerListActivity extends BaseMvpActivity<IRoomManagerView, RoomManagerPresenter> public class RoomManagerListActivity extends BaseMvpActivity<IRoomManagerView, RoomManagerPresenter>
implements RoomNormalListAdapter.OnRoomNormalListOperationClickListener, IRoomManagerView { implements RoomNormalListAdapter.OnRoomNormalListOperationClickListener, IRoomManagerView {
private TextView count;
private RecyclerView recyclerView; private RecyclerView recyclerView;
private RoomNormalListAdapter normalListAdapter; private RoomNormalListAdapter normalListAdapter;
@@ -47,7 +46,7 @@ public class RoomManagerListActivity extends BaseMvpActivity<IRoomManagerView, R
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_room_manager_list); setContentView(R.layout.activity_room_manager_list);
initWhiteTitleBar("管理员"); initWhiteTitleBar("管理员(0)人");
initView(); initView();
showLoading(); showLoading();
loadData(); loadData();
@@ -58,8 +57,7 @@ public class RoomManagerListActivity extends BaseMvpActivity<IRoomManagerView, R
} }
private void initView() { private void initView() {
count = (TextView) findViewById(R.id.count); recyclerView = findViewById(R.id.recycler_view);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
normalListAdapter = new RoomNormalListAdapter(this); normalListAdapter = new RoomNormalListAdapter(this);
normalListAdapter.setListOperationClickListener(this); normalListAdapter.setListOperationClickListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setLayoutManager(new LinearLayoutManager(this));
@@ -103,10 +101,10 @@ public class RoomManagerListActivity extends BaseMvpActivity<IRoomManagerView, R
if (chatRoomMemberList != null && chatRoomMemberList.size() > 0) { if (chatRoomMemberList != null && chatRoomMemberList.size() > 0) {
normalListAdapter.setNormalList(chatRoomMemberList); normalListAdapter.setNormalList(chatRoomMemberList);
normalListAdapter.notifyDataSetChanged(); normalListAdapter.notifyDataSetChanged();
count.setText("管理员" + chatRoomMemberList.size() + ""); mTitleBar.setTitle("管理员(" + chatRoomMemberList.size() + ")");
} else { } else {
showNoData("暂没有设置管理员"); showNoData("暂没有设置管理员");
count.setText("管理员0"); mTitleBar.setTitle("管理员(0)");
} }
} }
@@ -122,27 +120,26 @@ public class RoomManagerListActivity extends BaseMvpActivity<IRoomManagerView, R
if (!ListUtils.isListEmpty(list)) { if (!ListUtils.isListEmpty(list)) {
hideStatus(); hideStatus();
ListIterator<ChatRoomMember> iterator = list.listIterator(); ListIterator<ChatRoomMember> iterator = list.listIterator();
for (; iterator.hasNext(); ) { while (iterator.hasNext()) {
if (Objects.equals(iterator.next().getAccount(), chatRoomMember.getAccount())) { if (Objects.equals(iterator.next().getAccount(), chatRoomMember.getAccount())) {
iterator.remove(); iterator.remove();
} }
} }
normalListAdapter.notifyDataSetChanged(); mTitleBar.setTitle("管理员(" + list.size() + ")人");
count.setText("管理员" + list.size() + "");
if (list.size() == 0) { if (list.size() == 0) {
showNoData("暂没有设置管理员"); showNoData("暂没有设置管理员");
} }
} else { } else {
showNoData("暂没有设置管理员"); showNoData("暂没有设置管理员");
count.setText("管理员0"); mTitleBar.setTitle("管理员(0)");
} }
normalListAdapter.notifyDataSetChanged();
toast("操作成功"); toast("操作成功");
// loadData();
} }
@Override @Override
public void markManagerListFail(int code, String error) { public void markManagerListFail(int code, String error) {
// toast("操作失败,请重试");
} }
@Override @Override

View File

@@ -3,6 +3,7 @@ package com.yizhuan.erban.avroom.presenter;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember; import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import com.yizhuan.erban.avroom.view.IRoomBlackView; import com.yizhuan.erban.avroom.view.IRoomBlackView;
import com.yizhuan.erban.base.BaseMvpPresenter; import com.yizhuan.erban.base.BaseMvpPresenter;
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager;
import com.yizhuan.xchat_android_core.room.model.RoomBaseModel; import com.yizhuan.xchat_android_core.room.model.RoomBaseModel;
import com.yizhuan.xchat_android_library.net.rxnet.callback.CallBack; import com.yizhuan.xchat_android_library.net.rxnet.callback.CallBack;
@@ -24,24 +25,6 @@ public class RoomBlackPresenter extends BaseMvpPresenter<IRoomBlackView> {
mRoomBaseModel = new RoomBaseModel(); mRoomBaseModel = new RoomBaseModel();
} }
public void queryBlackList(int limit) {
mRoomBaseModel.queryBlackList(limit)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<ChatRoomMember>>() {
@Override
public void accept(List<ChatRoomMember> chatRoomMemberList) throws Exception {
if (getMvpView() != null)
getMvpView().queryBlackListSuccess(chatRoomMemberList);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
if (getMvpView() != null)
getMvpView().queryBlackListFail();
}
});
}
/** /**
* 拉黑操作 * 拉黑操作
* *

View File

@@ -45,7 +45,7 @@ public class RoomManagerPresenter extends BaseMvpPresenter<IRoomManagerView> {
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
public void queryManagerList(int limit) { public void queryManagerList(int limit) {
mRoomBaseModel.queryManagerList(limit) Single.just(AvRoomDataManager.get().mRoomManagerList)
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.flatMap((Function<List<ChatRoomMember>, SingleSource<List<ChatRoomMember>>>) chatRoomMembers -> { .flatMap((Function<List<ChatRoomMember>, SingleSource<List<ChatRoomMember>>>) chatRoomMembers -> {
List<String> uids = new ArrayList<>(); List<String> uids = new ArrayList<>();

View File

@@ -12,7 +12,8 @@ object SKillDataParser {
isSelf: Boolean, isSelf: Boolean,
isEdit: Boolean, isEdit: Boolean,
itemEventListener: ItemEventListener? = null, itemEventListener: ItemEventListener? = null,
item: PropRecordVoEntity item: PropRecordVoEntity,
audioStatus: Int = 0
): ItemAttribute { ): ItemAttribute {
return ItemAttribute( return ItemAttribute(
cardId, cardId,
@@ -20,8 +21,10 @@ object SKillDataParser {
item.state, item.isMust, item.state, item.isMust,
item.parentId, item.parentVal, item.parentId, item.parentVal,
itemEventListener, itemEventListener,
item.refPropVos.toMutableList() item.refPropVos.toMutableList(),
) ).apply {
this.audioStatus = audioStatus
}
} }
@@ -37,11 +40,13 @@ object SKillDataParser {
item.isEdit, item.isEdit,
itemEventListener, itemEventListener,
it it
) ).apply {
audioStatus = item.audioStatus
}
list.add(element) list.add(element)
} }
return SkillAttribute( return SkillAttribute(
item.id, item.cardId, item.id, item.type, item.cardId,
item.icon, item.name, item.icon, item.name,
item.isSelf, item.isEdit, item.isSelf, item.isEdit,
item.pic, list item.pic, list
@@ -64,7 +69,7 @@ object SKillDataParser {
list.add(element) list.add(element)
} }
return SkillAttribute( return SkillAttribute(
-1, item.cardId, -1, item.type, item.cardId,
item.icon, item.name, item.icon, item.name,
item.isSelf, item.isEdit, item.isSelf, item.isEdit,
item.pic, list item.pic, list

View File

@@ -0,0 +1,201 @@
package com.yizhuan.erban.skill
import android.annotation.SuppressLint
import com.yizhuan.erban.base.BaseActivity
import com.yizhuan.erban.skill.dialog.SkillSelectionDialog
import com.yizhuan.erban.skill.repository.SkillDataManager
import com.yizhuan.erban.skill.repository.SkillModel
import com.yizhuan.erban.skill.widget.*
import com.yizhuan.xchat_android_core.file.FileModel
import com.yizhuan.xchat_android_core.skill.entity.PropRefEntity
import com.yizhuan.xchat_android_core.skill.entity.PropsEntity
import com.yizhuan.xchat_android_core.skill.entity.SkillPostServerEntity
import com.yizhuan.xchat_android_core.skill.entity.SkillPropertyEntity
import com.yizhuan.xchat_android_core.skill.event.SkillEvent
import com.yizhuan.xchat_android_core.utils.toast
import org.greenrobot.eventbus.EventBus
import java.io.File
class SkillDataDelegate(private val skillView: SkillCardView, private val activity: BaseActivity) :
ItemEventListener {
@SuppressLint("CheckResult")
override fun onItemClick(item: SkillItem) {
onItemSelection(item)
}
override fun onRecordSuccess(audioFile: File?, duration: Int) {
onRecordAudioSuccess(audioFile, duration)
}
override fun onDeleteRecordClick() {
deleteSkill(false)
}
/**
* 上传音频文件
*/
private fun onRecordAudioSuccess(audioFile: File?, duration: Int) {
val sourceItem =
skillView.getItems().find { it.getContentEntity().state == ItemAttribute.STATE_AUDIO }!!
val durationItem =
skillView.getItems()
.find { it.getContentEntity().state == ItemAttribute.STATE_DURATION }!!
with(durationItem.getContentEntity()) {
if (selectedProperties.isEmpty()) {
val entity = PropRefEntity(parentId, duration.toString())
selectedProperties.add(entity)
} else {
selectedProperties[0].propVal = duration.toString()
}
}
audioFile?.absolutePath?.let {
activity.dialogManager.showProgressDialog(activity)
FileModel.get()
.uploadFile(audioFile.absolutePath)
.flatMap {
with(sourceItem.getContentEntity()) {
if (selectedProperties.isEmpty()) {
val entity = PropRefEntity(parentId, it)
selectedProperties.add(entity)
} else {
selectedProperties[0].propVal = it
}
}
SkillModel.instance.saveSkillInfo(
SKillDataParser.parseSkillSelectedValue(
skillView.getAttributes().id,
skillView.getAttributes().cardId,
skillView.getItems()
)
)
}.compose(activity.bindToLifecycle())
.subscribe({
activity.dialogManager.dismissDialog()
EventBus.getDefault().post(SkillEvent())
if (skillView.getAttributes().id == -1) {
activity.finish()
}
}, {
activity.dialogManager.dismissDialog()
"上传失败,请重新录制".toast()
(sourceItem as RecordIResourceItem).setItemByState(RecordIResourceItem.RECORD_STATE_READY)
})
}
}
/**
* 选项
*/
@SuppressLint("CheckResult")
private fun onItemSelection(item: SkillItem) {
val propertyEntity =
SkillDataManager.get().getPropertyEntity(item.getContentEntity().cardId)
if (propertyEntity == null) {
SkillModel.instance.getCardInfoById(item.getContentEntity().cardId)
.compose(activity.bindToLifecycle())
.doOnSubscribe { activity.dialogManager.showProgressDialog(activity) }
.subscribe({
SkillDataManager.get()
.setSkillPropertyEntity(item.getContentEntity().cardId, it)
showSelectionDialog(item, it)
activity.dialogManager.dismissDialog()
}, { th ->
th.printStackTrace()
activity.toast(th.message)
showSelectionDialog(item, null)
activity.dialogManager.dismissDialog()
})
} else {
showSelectionDialog(item, propertyEntity)
}
}
private fun showSelectionValueDialog(item: SkillItem, propertyEntity: PropsEntity?) {
val selectionDialog = SkillSelectionDialog(activity, propertyEntity) {
item.getContentEntity().selectedProperties.clear()
it.forEach { element -> item.getContentEntity().selectedProperties.add(element.parseToRecord()) }
item.invalidate()
}
selectionDialog.openDialog()
}
/**
* 显示选择对话框
*/
private fun showSelectionDialog(item: SkillItem, propertyEntity: SkillPropertyEntity?) {
val props = propertyEntity?.props
val propDictVos = props?.find { it.id == item.getContentEntity().parentId }?.apply {
propDictVos?.forEach { prop ->
//清空已选项
prop.isSelected = false
//设置之前保存的选项,从服务器拉下来的数据
val hasSelectBefore =
item.getContentEntity().selectedProperties.find { record -> record.propId == prop.id }
if (hasSelectBefore != null) {
//表示这个是上次存在服务器的值 设置为true
prop.isSelected = true
}
}
}
showSelectionValueDialog(item, propDictVos)
}
@SuppressLint("CheckResult")
internal fun saveSkill() {
if (!skillView.isValid()) {
activity.toast("请填写或选择带*条目的内容")
return
}
val item = parseSelectedValues()
SkillModel.instance.saveSkillInfo(item).compose(activity.bindToLifecycle())
.doOnSubscribe { activity.dialogManager.showProgressDialog(activity) }
.subscribe(
{
activity.dialogManager.dismissDialog()
val event = SkillEvent()
event.event = SkillEvent.ADD
EventBus.getDefault().post(event)
activity.finish()
},
{ th ->
th.printStackTrace()
activity.toast(th.message)
activity.dialogManager.dismissDialog()
})
}
/**
* 获取SkillView数据转换成提交服务器数据
*/
private fun parseSelectedValues(): SkillPostServerEntity {
val itemList = skillView.getItems()
val skillAttr = skillView.getAttributes()
return SKillDataParser.parseSkillSelectedValue(skillAttr.id, skillAttr.cardId, itemList)
}
/**
* 删除技能卡
*/
@SuppressLint("CheckResult")
fun deleteSkill(needFinishCurrent: Boolean) {
activity.dialogManager.showProgressDialog(activity)
SkillModel.instance.deleteSkill(skillView.getAttributes().id)
.compose(activity.bindToLifecycle())
.subscribe({
activity.toast("删除成功")
val event = SkillEvent()
event.event = SkillEvent.REMOVE
EventBus.getDefault().post(event)
activity.dialogManager.dismissDialog()
if (needFinishCurrent)
activity.finish()
}, { th ->
th.printStackTrace()
activity.toast(th.message)
})
}
}

View File

@@ -8,11 +8,9 @@ import com.netease.nim.uikit.StatusBarUtil
import com.yizhuan.erban.R import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseBindingActivity import com.yizhuan.erban.base.BaseBindingActivity
import com.yizhuan.erban.databinding.ActivitySkillEditBinding import com.yizhuan.erban.databinding.ActivitySkillEditBinding
import com.yizhuan.xchat_android_core.skill.event.SkillEvent
import com.yizhuan.erban.skill.repository.SkillModel import com.yizhuan.erban.skill.repository.SkillModel
import com.yizhuan.erban.ui.widget.dialog.CommonTipDialog import com.yizhuan.erban.ui.widget.dialog.CommonTipDialog
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes import com.yizhuan.xchat_android_library.annatation.ActLayoutRes
import org.greenrobot.eventbus.EventBus
@ActLayoutRes(R.layout.activity_skill_edit) @ActLayoutRes(R.layout.activity_skill_edit)
class EditSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() { class EditSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
@@ -33,7 +31,7 @@ class EditSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
when (v.id) { when (v.id) {
R.id.btn_delete -> showDeleteDialog() R.id.btn_delete -> showDeleteDialog()
R.id.btn_save -> { R.id.btn_save -> {
mDelegate.saveSkill(mBinding) mDelegate.saveSkill()
} }
} }
} }
@@ -48,7 +46,7 @@ class EditSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
deleteTipDialog?.setTipMsg(resources.getString(R.string.tip_delete_skill)) deleteTipDialog?.setTipMsg(resources.getString(R.string.tip_delete_skill))
deleteTipDialog?.setOnActionListener(object : CommonTipDialog.OnActionListener { deleteTipDialog?.setOnActionListener(object : CommonTipDialog.OnActionListener {
override fun onOk() { override fun onOk() {
deleteSkill(mBinding.skillView.getAttributes().id) mDelegate.deleteSkill()
deleteTipDialog?.dismiss() deleteTipDialog?.dismiss()
} }
@@ -63,22 +61,6 @@ class EditSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
deleteTipDialog?.show() deleteTipDialog?.show()
} }
@SuppressLint("CheckResult")
private fun deleteSkill(id: Int) {
SkillModel.instance.deleteSkill(id)
.compose(bindToLifecycle())
.subscribe({
toast("删除成功")
val event = SkillEvent()
event.event = SkillEvent.REMOVE
EventBus.getDefault().post(event)
finish()
}, { th ->
th.printStackTrace()
toast(th.message)
})
}
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
private fun loadData() { private fun loadData() {

View File

@@ -1,21 +1,12 @@
package com.yizhuan.erban.skill.activity package com.yizhuan.erban.skill.activity
import android.annotation.SuppressLint
import com.yizhuan.erban.R import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseBindingActivity import com.yizhuan.erban.base.BaseBindingActivity
import com.yizhuan.erban.databinding.ActivitySkillEditBinding import com.yizhuan.erban.databinding.ActivitySkillEditBinding
import com.yizhuan.erban.skill.SKillDataParser import com.yizhuan.erban.skill.SKillDataParser
import com.yizhuan.erban.skill.dialog.SkillSelectionDialog import com.yizhuan.erban.skill.SkillDataDelegate
import com.yizhuan.xchat_android_core.skill.event.SkillEvent
import com.yizhuan.erban.skill.repository.SkillDataManager
import com.yizhuan.erban.skill.repository.SkillModel
import com.yizhuan.erban.skill.widget.*
import com.yizhuan.erban.ui.widget.dialog.CommonTipDialog import com.yizhuan.erban.ui.widget.dialog.CommonTipDialog
import com.yizhuan.xchat_android_core.file.FileModel
import com.yizhuan.xchat_android_core.skill.entity.* import com.yizhuan.xchat_android_core.skill.entity.*
import com.yizhuan.xchat_android_core.utils.toast
import org.greenrobot.eventbus.EventBus
import java.io.File
/** /**
* 编辑-添加 界面 * 编辑-添加 界面
@@ -53,45 +44,28 @@ class SkillEditableDelegate(
saveTipDialog.show() saveTipDialog.show()
} }
private fun showSelectionValueDialog(item: SkillItem, propertyEntity: PropsEntity?) { /**
val selectionDialog = SkillSelectionDialog(activity, propertyEntity) { * 保存 添加
item.getContentEntity().selectedProperties.clear() */
it.forEach { element -> item.getContentEntity().selectedProperties.add(element.parseToRecord()) } internal fun saveSkill() {
item.invalidate() SkillDataDelegate(activity.mBinding.skillView, activity).saveSkill()
}
selectionDialog.openDialog()
} }
@SuppressLint("CheckResult") /**
internal fun saveSkill(binding: ActivitySkillEditBinding) { * 删除
if (!binding.skillView.isValid()) { */
activity.toast("请填写或选择带*条目的内容") internal fun deleteSkill() {
return SkillDataDelegate(activity.mBinding.skillView, activity).deleteSkill(true)
}
val item = parseSelectedValues()
SkillModel.instance.saveSkillInfo(item).compose(activity.bindToLifecycle())
.doOnSubscribe { activity.dialogManager.showProgressDialog(activity) }
.subscribe(
{
activity.dialogManager.dismissDialog()
val event = SkillEvent()
event.event = SkillEvent.ADD
EventBus.getDefault().post(event)
activity.finish()
},
{ th ->
th.printStackTrace()
activity.toast(th.message)
activity.dialogManager.dismissDialog()
})
} }
/** /**
* 记录 * 记录
*/ */
internal fun setSkillViewData(entity: SkillRecordEntity) { internal fun setSkillViewData(entity: SkillRecordEntity) {
val onItemCall = if (entity.isEdit && entity.isSelf) itemEventListener else null val onItemCall =
if (entity.isEdit && entity.isSelf)
SkillDataDelegate(activity.mBinding.skillView, activity)
else null
val attr = SKillDataParser.parseSkillRecordToAttribute(entity, onItemCall) val attr = SKillDataParser.parseSkillRecordToAttribute(entity, onItemCall)
activity.mBinding.skillView.initView(attr) activity.mBinding.skillView.initView(attr)
} }
@@ -100,119 +74,15 @@ class SkillEditableDelegate(
* 初值属性 * 初值属性
*/ */
internal fun setSkillViewData(entity: SkillPropertyEntity) { internal fun setSkillViewData(entity: SkillPropertyEntity) {
val onItemCall = if (entity.isEdit && entity.isSelf) itemEventListener else null val onItemCall = if (entity.isEdit && entity.isSelf) SkillDataDelegate(
activity.mBinding.skillView,
activity
) else null
val attr = SKillDataParser.parseSkillPropertyToAttribute(entity, onItemCall) val attr = SKillDataParser.parseSkillPropertyToAttribute(entity, onItemCall)
activity.mBinding.skillView.initView(attr) activity.mBinding.skillView.initView(attr)
} }
/**
* 显示选择对话框
*/
private fun showSelectionDialog(item: SkillItem, propertyEntity: SkillPropertyEntity?) {
val props = propertyEntity?.props
val propDictVos = props?.find {
it.id == item.getContentEntity().parentId
}
showSelectionValueDialog(item, propDictVos)
}
/**
* 获取SkillView数据转换成提交服务器数据
*/
private fun parseSelectedValues(): SkillPostServerEntity {
val itemList = activity.mBinding.skillView.getItems()
val skillAttr = activity.mBinding.skillView.getAttributes()
return SKillDataParser.parseSkillSelectedValue(skillAttr.id, skillAttr.cardId, itemList)
}
private val itemEventListener = object : ItemEventListener {
@SuppressLint("CheckResult")
override fun onItemClick(item: SkillItem) {
onItemSelection(item)
}
override fun onRecordSuccess(audioFile: File?, duration: Int) {
onRecordAudioSuccess(audioFile, duration)
}
}
companion object { companion object {
const val RECORD_ID = "record_id" const val RECORD_ID = "record_id"
} }
/**
* 上传音频文件
*/
private fun onRecordAudioSuccess(audioFile: File?, duration: Int) {
val sourceItem =
activity.mBinding.skillView.getItems().find { it.getContentEntity().state == 3 }!!
val durationItem =
activity.mBinding.skillView.getItems().find { it.getContentEntity().state == 4 }!!
with(durationItem.getContentEntity()) {
if (selectedProperties.isEmpty()) {
val entity = PropRefEntity(parentId, duration.toString())
selectedProperties.add(entity)
} else {
selectedProperties[0].propVal = duration.toString()
}
}
audioFile?.absolutePath?.let {
activity.dialogManager.showProgressDialog(activity)
FileModel.get()
.uploadFile(audioFile.absolutePath)
.flatMap {
with(sourceItem.getContentEntity()) {
if (selectedProperties.isEmpty()) {
val entity = PropRefEntity(parentId, it)
selectedProperties.add(entity)
} else {
selectedProperties[0].propVal = it
}
}
SkillModel.instance.saveSkillInfo(
SKillDataParser.parseSkillSelectedValue(
activity.mBinding.skillView.getAttributes().id,
activity.mBinding.skillView.getAttributes().cardId,
activity.mBinding.skillView.getItems()
)
)
}.compose(activity.bindToLifecycle())
.subscribe({
activity.dialogManager.dismissDialog()
(sourceItem as RecordIResourceItem).setItemByState(RECORD_STATE_JUDGE)
}, {
activity.dialogManager.dismissDialog()
"上传失败,请重新录制".toast()
(sourceItem as RecordIResourceItem).setItemByState(RECORD_STATE_READY)
})
}
}
/**
* 选项
*/
private fun onItemSelection(item: SkillItem) {
val propertyEntity =
SkillDataManager.get().getPropertyEntity(item.getContentEntity().cardId)
if (propertyEntity == null) {
SkillModel.instance.getCardInfoById(item.getContentEntity().cardId)
.compose(activity.bindToLifecycle())
.doOnSubscribe { activity.dialogManager.showProgressDialog(activity) }
.subscribe({
SkillDataManager.get()
.setSkillPropertyEntity(item.getContentEntity().cardId, it)
showSelectionDialog(item, it)
activity.dialogManager.dismissDialog()
}, { th ->
th.printStackTrace()
activity.toast(th.message)
showSelectionDialog(item, null)
activity.dialogManager.dismissDialog()
})
} else {
showSelectionDialog(item, propertyEntity)
}
}
} }

View File

@@ -14,12 +14,15 @@ import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseBindingActivity import com.yizhuan.erban.base.BaseBindingActivity
import com.yizhuan.erban.common.EmptyViewHelper import com.yizhuan.erban.common.EmptyViewHelper
import com.yizhuan.erban.databinding.ActivitySkillHomeBinding import com.yizhuan.erban.databinding.ActivitySkillHomeBinding
import com.yizhuan.erban.skill.SKillDataParser
import com.yizhuan.erban.skill.adapter.MineSkillCardAdapter import com.yizhuan.erban.skill.adapter.MineSkillCardAdapter
import com.yizhuan.erban.skill.decoration.SkillLinearVerticalDecoration import com.yizhuan.erban.skill.decoration.SkillLinearVerticalDecoration
import com.yizhuan.erban.skill.dialog.AddSkillCardDialog import com.yizhuan.erban.skill.dialog.AddSkillCardDialog
import com.yizhuan.xchat_android_core.skill.event.SkillEvent import com.yizhuan.xchat_android_core.skill.event.SkillEvent
import com.yizhuan.erban.skill.repository.SkillDataManager import com.yizhuan.erban.skill.repository.SkillDataManager
import com.yizhuan.erban.skill.repository.SkillModel import com.yizhuan.erban.skill.repository.SkillModel
import com.yizhuan.erban.skill.widget.CARD_TYPE_AUDIO
import com.yizhuan.erban.skill.widget.SkillAttribute
import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes import com.yizhuan.xchat_android_library.annatation.ActLayoutRes
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
@@ -39,11 +42,13 @@ class SkillHomeActivity : BaseBindingActivity<ActivitySkillHomeBinding>() {
userId = intent.getLongExtra(USER_ID, 0) userId = intent.getLongExtra(USER_ID, 0)
EventBus.getDefault().register(this) EventBus.getDefault().register(this)
mBinding.recyclerView.layoutManager = LinearLayoutManager(this) mBinding.recyclerView.layoutManager = LinearLayoutManager(this)
adapter = MineSkillCardAdapter(pageType ==PAGE_TYPE_SELF) adapter = MineSkillCardAdapter(pageType == PAGE_TYPE_SELF, this)
mBinding.recyclerView.adapter = adapter mBinding.recyclerView.adapter = adapter
mBinding.recyclerView.addItemDecoration(SkillLinearVerticalDecoration(this, 6, 16)) mBinding.recyclerView.addItemDecoration(SkillLinearVerticalDecoration(this, 6, 16))
adapter.setOnItemClickListener { _, _, position -> adapter.setOnItemClickListener { _, _, position ->
if (pageType != PAGE_TYPE_SELF) return@setOnItemClickListener if (pageType != PAGE_TYPE_SELF) return@setOnItemClickListener
val item = adapter.getItem(position) ?: return@setOnItemClickListener
if (item == null || item.type == CARD_TYPE_AUDIO) return@setOnItemClickListener
adapter.getItem(position)?.let { adapter.getItem(position)?.let {
EditSkillActivity.start(this, it.id) EditSkillActivity.start(this, it.id)
} }
@@ -54,6 +59,7 @@ class SkillHomeActivity : BaseBindingActivity<ActivitySkillHomeBinding>() {
mBinding.refreshLayout.setOnRefreshListener { mBinding.refreshLayout.setOnRefreshListener {
loadUserSkillList(userId) loadUserSkillList(userId)
} }
mBinding.refreshLayout.isEnabled=false//禁用下拉刷新
loadUserSkillList(userId) loadUserSkillList(userId)
} }
@@ -163,7 +169,8 @@ class SkillHomeActivity : BaseBindingActivity<ActivitySkillHomeBinding>() {
fun onDataChangedEvent(event: SkillEvent) { fun onDataChangedEvent(event: SkillEvent) {
loadUserSkillList(userId) loadUserSkillList(userId)
} }
override fun needSteepStateBar()=true
override fun needSteepStateBar() = true
override fun setStatusBar() { override fun setStatusBar() {
super.setStatusBar() super.setStatusBar()
StatusBarUtil.transparencyBar(this) StatusBarUtil.transparencyBar(this)

View File

@@ -3,19 +3,36 @@ package com.yizhuan.erban.skill.adapter
import com.chad.library.adapter.base.BaseQuickAdapter import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder import com.chad.library.adapter.base.BaseViewHolder
import com.yizhuan.erban.R import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseActivity
import com.yizhuan.erban.skill.SKillDataParser import com.yizhuan.erban.skill.SKillDataParser
import com.yizhuan.erban.skill.SkillDataDelegate
import com.yizhuan.erban.skill.widget.CARD_TYPE_AUDIO
import com.yizhuan.xchat_android_core.skill.entity.SkillRecordEntity import com.yizhuan.xchat_android_core.skill.entity.SkillRecordEntity
import com.yizhuan.erban.skill.widget.SkillCardView import com.yizhuan.erban.skill.widget.SkillCardView
/** /**
* 用户所有技能卡 显示 * 用户所有技能卡 显示
*/ */
class MineSkillCardAdapter(private val isSelf: Boolean) : class MineSkillCardAdapter(private val isSelf: Boolean, private val activity: BaseActivity) :
BaseQuickAdapter<SkillRecordEntity, BaseViewHolder>(R.layout.item_mine_skill_card) { BaseQuickAdapter<SkillRecordEntity, BaseViewHolder>(R.layout.item_mine_skill_card) {
override fun convert(helper: BaseViewHolder, item: SkillRecordEntity) { override fun convert(helper: BaseViewHolder, item: SkillRecordEntity) {
val itemView = helper.itemView as SkillCardView val itemView = helper.itemView as SkillCardView
item.isSelf = isSelf
item.isEdit = false item.isEdit = false
itemView.initView(SKillDataParser.parseSkillRecordToAttribute(item)) when (item.type) {
CARD_TYPE_AUDIO -> {
//声音秀没有编辑选项
item.isSelf = false
itemView.initView(
SKillDataParser.parseSkillRecordToAttribute(
item,
SkillDataDelegate(itemView, activity)
)
)
}
else -> {
item.isSelf = isSelf
itemView.initView(SKillDataParser.parseSkillRecordToAttribute(item))
}
}
} }
} }

View File

@@ -6,10 +6,24 @@ import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder import com.chad.library.adapter.base.BaseViewHolder
import com.yizhuan.erban.R import com.yizhuan.erban.R
import com.yizhuan.xchat_android_core.skill.entity.PropDictVo import com.yizhuan.xchat_android_core.skill.entity.PropDictVo
import com.yizhuan.xchat_android_core.utils.toast
class SkillSelectionAdapter(private val context: Context, private val itemState: Int) : class SkillSelectionAdapter(
private val context: Context,
private val itemState: Int,
private var maxSelectNumber: Int
) :
BaseQuickAdapter<PropDictVo, BaseViewHolder>(R.layout.item_skill_selection) { BaseQuickAdapter<PropDictVo, BaseViewHolder>(R.layout.item_skill_selection) {
init {
//-1 不限制
maxSelectNumber =
if (maxSelectNumber == 0 || maxSelectNumber == -1) Int.MAX_VALUE
else maxSelectNumber
}
private var refreshByUser = false//标志是否是用户选择后刷新Adapter在用户选择后设置为true
private var selectedCount = 0
override fun convert(helper: BaseViewHolder, item: PropDictVo) { override fun convert(helper: BaseViewHolder, item: PropDictVo) {
helper.setText(R.id.tv_item, item.propVal) helper.setText(R.id.tv_item, item.propVal)
helper.setBackgroundRes( helper.setBackgroundRes(
@@ -19,15 +33,17 @@ class SkillSelectionAdapter(private val context: Context, private val itemState:
) )
helper.setTextColor( helper.setTextColor(
R.id.tv_item, R.id.tv_item,
if (item.isSelected) context.resources.getColor(R.color.color_333333) if (item.isSelected) Color.parseColor("#FFBC51")
else Color.parseColor("#FFBC51") else context.resources.getColor(R.color.color_333333)
) )
if (item.isSelected && !refreshByUser) {
selectedCount++
}
} }
fun select(position: Int) { fun select(position: Int) {
refreshByUser = true
getItem(position)?.let { getItem(position)?.let {
it.isSelected = !it.isSelected
if (!it.isSelected) return@let
when (itemState) { when (itemState) {
//0 单选 1 输入 2多选 3 音频 4 音频时长 //0 单选 1 输入 2多选 3 音频 4 音频时长
0 -> singleSelect(it) 0 -> singleSelect(it)
@@ -43,15 +59,44 @@ class SkillSelectionAdapter(private val context: Context, private val itemState:
private fun singleSelect(item: PropDictVo) { private fun singleSelect(item: PropDictVo) {
data.forEach { it.isSelected = false } data.forEach { it.isSelected = false }
selectedCount = 1
item.isSelected = true item.isSelected = true
} }
private fun multiSelect(item: PropDictVo) { private fun multiSelect(item: PropDictVo) {
item.isSelected = !item.isSelected
when (item.refIsOnlyCheck) { when (item.refIsOnlyCheck) {
0 -> data.find { e -> e.refIsOnlyCheck == 1 }?.isSelected = false 0 -> {
when (item.isSelected) {
false -> {
selectedCount--
}
true -> {
selectedCount++
if (selectedCount > maxSelectNumber) {
"最多只能选择${maxSelectNumber}".toast()
selectedCount--
item.isSelected = false
return
} else {
data.find { e -> e.refIsOnlyCheck == 1 }?.let {
if (it.isSelected) {
it.isSelected = false
selectedCount--
}
}
}
}
}
}
1 -> { 1 -> {
data.forEach { that -> that.isSelected = false } if (item.isSelected) {
item.isSelected = true data.forEach { that -> that.isSelected = false }
item.isSelected = true
selectedCount = 1
} else {
selectedCount = 0
}
} }
} }
} }

View File

@@ -27,7 +27,7 @@ class SkillSelectionDialog(
gravity = Gravity.BOTTOM gravity = Gravity.BOTTOM
binding.tvTitle.visibility = View.VISIBLE binding.tvTitle.visibility = View.VISIBLE
binding.tvTitle.text = item?.propVal ?: "" binding.tvTitle.text = item?.propVal ?: ""
adapter = SkillSelectionAdapter(context, item?.state ?: 0) adapter = SkillSelectionAdapter(context, item?.state ?: 0,item?.checkLimitNum?:-1)
adapter.setOnItemClickListener { _, _, position -> adapter.setOnItemClickListener { _, _, position ->
adapter.select(position) adapter.select(position)
} }

View File

@@ -7,17 +7,30 @@ data class ItemAttribute(
val cardId: Int, val cardId: Int,
val isSelf: Boolean = false, val isSelf: Boolean = false,
val editable: Boolean = false, val editable: Boolean = false,
val state: Int = 0,//0 单选 1 编辑 2 多选 3 音频 val state: Int = STATE_SINGLE_CHOICE,//0 单选 1 编辑 2 多选 3 音频
val isMust: Int = 0, val isMust: Int = 0,
val parentId: Int, val parentId: Int,
val parentVol: String, val parentVol: String,
val itemEventListener: ItemEventListener? = null, val itemEventListener: ItemEventListener? = null,
var selectedProperties: MutableList<PropRefEntity> var selectedProperties: MutableList<PropRefEntity>
)
) {
companion object {
const val STATE_SINGLE_CHOICE = 0
const val STATE_EDIT = 1
const val STATE_MULTIPLE_CHOICE = 2
const val STATE_AUDIO = 3
const val STATE_DURATION = 4
}
var audioDuration: String? = null
var audioStatus: Int = 0//声音秀审核状态
}
interface ItemEventListener { interface ItemEventListener {
fun onItemClick(item: SkillItem) {} fun onItemClick(item: SkillItem) {}
fun onRecordSuccess( audioFile: File?, duration: Int) {} fun onRecordSuccess(audioFile: File?, duration: Int) {}
fun onDeleteRecordClick() {}
} }

View File

@@ -3,7 +3,9 @@ package com.yizhuan.erban.skill.widget
import android.content.Context import android.content.Context
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import com.netease.nim.uikit.common.util.sys.ScreenUtil
import com.netease.nimlib.sdk.media.record.RecordType import com.netease.nimlib.sdk.media.record.RecordType
import com.yizhuan.erban.R
import com.yizhuan.erban.audio.helper.AudioPlayerHelper import com.yizhuan.erban.audio.helper.AudioPlayerHelper
import com.yizhuan.erban.audio.helper.OnPlayListener import com.yizhuan.erban.audio.helper.OnPlayListener
import com.yizhuan.erban.databinding.LayoutSkillAudioBinding import com.yizhuan.erban.databinding.LayoutSkillAudioBinding
@@ -12,38 +14,60 @@ import com.yizhuan.xchat_android_core.utils.TextUtils
import com.yizhuan.xchat_android_core.utils.toast import com.yizhuan.xchat_android_core.utils.toast
import java.io.File import java.io.File
//录制
const val MAX_RECORD_DURATION = 15//最大录音时长
const val RECORD_STATE_READY = 1//初态 即将录制
const val RECORD_STATE_COMPLETE = 2//录制完成
const val RECORD_STATE_JUDGE = 3//上传成功 正在审核
const val RECORD_STATE_REFUSE = 5//上传成功 审核不通过
const val RECORD_STATE_AGREE = 6//上传成功 审核通过
//播放
private const val PLAY_STATE_PLAYING = 10
private const val PLAY_STATE_READY = 11//播放出错失败按完成处理,设置为初态
class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem, class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
TimerRecorderView.RecordListener { TimerRecorderView.RecordListener, View.OnClickListener {
private lateinit var binding: LayoutSkillAudioBinding private lateinit var binding: LayoutSkillAudioBinding
private lateinit var context: Context private lateinit var context: Context
private var audioLength = 0 private var audioLength = 0
private var playState = PLAY_STATE_READY private var playState = PLAY_STATE_READY
private val cancelTipDialog by lazy {
//重新录制
private val reStartTipDialog by lazy {
CommonTipDialog(context).apply { CommonTipDialog(context).apply {
setTipMsg("确定要取消录制吗?") itemAttribute
setCancelText("取消") setTipMsg(
setOkText("确定") if (itemAttribute.audioStatus == RECORD_STATE_JUDGE)
"您录制的声音正在审核中,确定要重新录制吗?"
else "确定要重新录制吗?"
)
setCancelText("")
setOkText("")
setBold(true)
setTextSize(ScreenUtil.dip2px(16f))
setOnActionListener(object : CommonTipDialog.OnActionListener { setOnActionListener(object : CommonTipDialog.OnActionListener {
override fun onCancel() {} override fun onCancel() {}
override fun onOk() { override fun onOk() {
binding.recordView.endAudioRecord(true) if (AudioPlayerHelper.get().isPlaying) {
stopAudio()
}
binding.recordState = RECORD_STATE_READY
} }
}) })
} }
} }
//删除录制
private val deleteTipDialog by lazy {
CommonTipDialog(context).apply {
setTipMsg("确定要删除该声音吗?")
setCancelText("确定")
setBold(true)
setTextSize(ScreenUtil.dip2px(16f))
setOkText("取消")
setOnActionListener(object : CommonTipDialog.OnActionListener {
override fun onCancel() {
if (AudioPlayerHelper.get().isPlaying) {
stopAudio()
}
itemAttribute.itemEventListener?.onDeleteRecordClick()
}
override fun onOk() {}
})
}
}
override fun createItem(context: Context): View { override fun createItem(context: Context): View {
this.context = context this.context = context
val inflater = LayoutInflater.from(context) val inflater = LayoutInflater.from(context)
@@ -55,19 +79,11 @@ class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
private fun initItem() { private fun initItem() {
binding.recordView.recordListener = this binding.recordView.recordListener = this
binding.recordView.recordDuration = MAX_RECORD_DURATION binding.recordView.recordDuration = MAX_RECORD_DURATION
binding.btnCancel.setOnClickListener { binding.recordState = itemAttribute.audioStatus
if (cancelTipDialog.isShowing) { itemAttribute.audioDuration?.let { binding.duration = it }
cancelTipDialog.dismiss() binding.btnCancel.text = if (itemAttribute.isSelf) "取消录制" else "取消重新录制"
}
cancelTipDialog.show() binding.click = this
}
binding.tvSound.setOnClickListener {
if (playState == PLAY_STATE_READY) {
playAudio(itemAttribute.selectedProperties.getOrNull(0)?.propVal)
} else {
stopAudio()
}
}
} }
override fun invalidate() {} override fun invalidate() {}
@@ -81,16 +97,19 @@ class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
} }
override fun onRecordStart(file: File?, recordType: RecordType?) { override fun onRecordStart(file: File?, recordType: RecordType?) {
binding.tvRecordTip.text="录音开始不少于3s喔" binding.recordState = RECORD_STATE_RECORDING
} }
override fun onRecordCancel() { override fun onRecordCancel() {
setItemByState(RECORD_STATE_READY) //审核通过后 重新录制取消 要设置为之前审核通过的状态
binding.recordState = itemAttribute.audioStatus
} }
override fun onRecordSuccess(file: File?) { override fun onRecordSuccess(file: File?) {
if (cancelTipDialog.isShowing) { if (audioLength < 3) {
cancelTipDialog.dismiss() "录制时间不能少于3s哦".toast()
binding.recordState = RECORD_STATE_READY
return
} }
itemAttribute.itemEventListener?.onRecordSuccess(file, audioLength) itemAttribute.itemEventListener?.onRecordSuccess(file, audioLength)
} }
@@ -105,40 +124,18 @@ class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
* 根据状态设置View * 根据状态设置View
*/ */
fun setItemByState(state: Int) { fun setItemByState(state: Int) {
when (state) { binding.recordState = state
RECORD_STATE_READY -> {
binding.groupJudge.visibility = View.GONE
binding.groupReady.visibility = View.VISIBLE
binding.btnCancel.visibility = View.VISIBLE
}
RECORD_STATE_COMPLETE -> {
binding.groupJudge.visibility = View.GONE
binding.groupReady.visibility = View.VISIBLE
binding.btnCancel.visibility = View.GONE
}
RECORD_STATE_JUDGE -> {
binding.groupReady.visibility = View.GONE
binding.groupJudge.visibility = View.VISIBLE
}
PLAY_STATE_PLAYING -> {
//更改状态,动画
}
PLAY_STATE_READY -> {
}
}
} }
private fun playAudio(url: String?) { private fun playAudio(url: String?) {
if (playState == PLAY_STATE_PLAYING || TextUtils.isEmptyText(url)) return if (playState == PLAY_STATE_PLAYING || TextUtils.isEmptyText(url)) return
playState = PLAY_STATE_PLAYING playState = PLAY_STATE_PLAYING
setItemByState(PLAY_STATE_PLAYING) binding.palyState = playState
AudioPlayerHelper.get().playInThread(url, object : OnPlayListener { AudioPlayerHelper.get().playInThread(url, object : OnPlayListener {
override fun onError(error: String?) { override fun onError(error: String?) {
"播放出错,请重试".toast() "播放出错,请重试".toast()
playState = PLAY_STATE_READY playState = PLAY_STATE_READY
setItemByState(PLAY_STATE_READY) binding.palyState = playState
} }
override fun onPrepared() {} override fun onPrepared() {}
@@ -147,7 +144,7 @@ class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
override fun onCompletion() { override fun onCompletion() {
playState = PLAY_STATE_READY playState = PLAY_STATE_READY
setItemByState(PLAY_STATE_READY) binding.palyState = playState
} }
}) })
} }
@@ -156,7 +153,49 @@ class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
if (playState == PLAY_STATE_READY) return if (playState == PLAY_STATE_READY) return
AudioPlayerHelper.get().endPlay() AudioPlayerHelper.get().endPlay()
playState = PLAY_STATE_READY playState = PLAY_STATE_READY
//更改状态 binding.palyState = playState
setItemByState(PLAY_STATE_READY) }
companion object {
//录制
const val MAX_RECORD_DURATION = 15//最大录音时长
const val RECORD_STATE_READY = 0//初态 即将录制
const val RECORD_STATE_RECORDING = 5//正在录制
const val RECORD_STATE_AGREE = 1//上传成功 审核通过
const val RECORD_STATE_JUDGE = 2//上传成功 正在审核
const val RECORD_STATE_REFUSE = 3//上传成功 审核不通过
//播放
const val PLAY_STATE_PLAYING = 10
const val PLAY_STATE_READY = 11//播放出错失败按完成处理,设置为初态
}
override fun onClick(v: View) {
when (v.id) {
R.id.btn_cancel -> {
binding.recordView.endAudioRecord(true)
}
R.id.tv_sound, R.id.iv_play -> {
if (playState == PLAY_STATE_READY) {
playAudio(itemAttribute.selectedProperties.getOrNull(0)?.propVal)
} else {
stopAudio()
}
}
R.id.btn_delete -> {
if (deleteTipDialog.isShowing) {
deleteTipDialog.dismiss()
}
deleteTipDialog.show()
}
R.id.btn_restart -> {
if (reStartTipDialog.isShowing) {
reStartTipDialog.dismiss()
}
reStartTipDialog.show()
}
}
} }
} }

View File

@@ -1,7 +1,12 @@
package com.yizhuan.erban.skill.widget package com.yizhuan.erban.skill.widget
const val CARD_TYPE_GAME = 1
const val CARD_TYPE_ART = 2
const val CARD_TYPE_AUDIO = 3
data class SkillAttribute( data class SkillAttribute(
val id: Int, val id: Int,
val type: Int,
val cardId: Int, val cardId: Int,
val skillRes: String?, val skillRes: String?,
val skillName: String, val skillName: String,

View File

@@ -96,6 +96,8 @@ class SkillCardView(
attr.itemAttributes.forEach { attr.itemAttributes.forEach {
this.itemList.add(createItemView(it)) this.itemList.add(createItemView(it))
} }
//暂时处理
SkillItemHelper.wrapAudio(attr)
setBackgroundImg(attr.background) setBackgroundImg(attr.background)
removeAllViews() removeAllViews()
setSkillTitle(attr.skillRes, attr.skillName, attr.isSelf, attr.isEdit) setSkillTitle(attr.skillRes, attr.skillName, attr.isSelf, attr.isEdit)

View File

@@ -5,6 +5,8 @@ import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan import android.text.style.ForegroundColorSpan
import android.widget.EditText import android.widget.EditText
import android.widget.TextView import android.widget.TextView
import com.yizhuan.erban.skill.widget.ItemAttribute.Companion.STATE_AUDIO
import com.yizhuan.erban.skill.widget.ItemAttribute.Companion.STATE_DURATION
object SkillItemHelper { object SkillItemHelper {
/** /**
@@ -45,4 +47,12 @@ object SkillItemHelper {
contentView.isFocusable = true contentView.isFocusable = true
contentView.isCursorVisible = true contentView.isCursorVisible = true
} }
fun wrapAudio(attr: SkillAttribute) {
if (attr.type == CARD_TYPE_AUDIO) {
val sourceItem = attr.itemAttributes.find { it.state == STATE_AUDIO }
val durationItem = attr.itemAttributes.find { it.state == STATE_DURATION }
sourceItem?.audioDuration = durationItem?.selectedProperties?.getOrNull(0)?.propVal
}
}
} }

View File

@@ -24,6 +24,8 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
AppCompatImageView(context, attrs, defStyleAttr), IAudioRecordCallback { AppCompatImageView(context, attrs, defStyleAttr), IAudioRecordCallback {
private var progressWidth = 0 private var progressWidth = 0
private var outerWidth = 0
private var progressColor = 0
private val progressPaint by lazy { private val progressPaint by lazy {
Paint(Paint.ANTI_ALIAS_FLAG) Paint(Paint.ANTI_ALIAS_FLAG)
} }
@@ -40,8 +42,11 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) { constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) {
val array = context.obtainStyledAttributes(attrs, R.styleable.TimerRecorderView) val array = context.obtainStyledAttributes(attrs, R.styleable.TimerRecorderView)
progressWidth = array.getDimension(R.styleable.TimerRecorderView_progressWidth, 0f).toInt() progressWidth = array.getDimension(R.styleable.TimerRecorderView_progressWidth, 0f).toInt()
outerWidth = array.getDimension(R.styleable.TimerRecorderView_outerWidth, 0f).toInt()
progressColor = array.getColor(R.styleable.TimerRecorderView_progressColor, 0).toInt()
progressPaint.style = Paint.Style.STROKE progressPaint.style = Paint.Style.STROKE
progressPaint.strokeWidth = progressWidth.toFloat() progressPaint.strokeWidth = progressWidth.toFloat()
progressPaint.color = progressColor
array.recycle() array.recycle()
setOnClickListener { setOnClickListener {
when (state) { when (state) {
@@ -59,29 +64,19 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
super.onMeasure(widthMeasureSpec, heightMeasureSpec) super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = MeasureSpec.getSize(widthMeasureSpec) val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec) val height = MeasureSpec.getSize(heightMeasureSpec)
val dimens = width.coerceAtLeast(height) + progressWidth * 2 setMeasuredDimension(width, height)
setMeasuredDimension(dimens, dimens)
} }
override fun onDraw(canvas: Canvas) { override fun onDraw(canvas: Canvas) {
super.onDraw(canvas) super.onDraw(canvas)
progressPaint.color = Color.GRAY
val r = (measuredWidth - progressWidth * 2) / 2
canvas.drawCircle(
(measuredWidth / 2).toFloat(),
(measuredHeight / 2).toFloat(),
r.toFloat(),
progressPaint
)
if (state == STATE_PLAYED) { if (state == STATE_PLAYED) {
progressPaint.color = Color.BLUE
val rectF = RectF() val rectF = RectF()
val swipe = animatedPercent * 360 val swipe = animatedPercent * 360
rectF.left = progressWidth.toFloat() rectF.left = outerWidth.toFloat()
rectF.top = progressWidth.toFloat() rectF.top = outerWidth.toFloat()
rectF.right = measuredWidth.toFloat() - progressWidth rectF.right = measuredWidth.toFloat() - outerWidth
rectF.bottom = measuredHeight.toFloat() - progressWidth rectF.bottom = measuredHeight.toFloat() - outerWidth
canvas.drawArc(rectF, -90f, swipe, false, progressPaint) canvas.drawArc(rectF, -90f, swipe, false, progressPaint)
} }
} }
@@ -97,6 +92,7 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
options.audioRecordMaxTime, this options.audioRecordMaxTime, this
) )
} }
setImageResource(R.drawable.ic_skill_audio_recording)
audioMessageHelper!!.startRecord() audioMessageHelper!!.startRecord()
} }
@@ -108,6 +104,7 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
fun endAudioRecord(cancel: Boolean) { fun endAudioRecord(cancel: Boolean) {
state = STATE_PAUSED state = STATE_PAUSED
audioMessageHelper?.completeRecord(cancel) audioMessageHelper?.completeRecord(cancel)
setImageResource(R.drawable.ic_skill_audio_ready)
clearRecordAnim() clearRecordAnim()
} }

View File

@@ -0,0 +1,53 @@
package com.yizhuan.erban.ui.im.chat;
import android.widget.TextView;
import com.netease.nim.uikit.business.session.viewholder.MsgViewHolderBase;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseMultiItemFetchLoadAdapter;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.yizhuan.erban.R;
import com.yizhuan.xchat_android_core.im.custom.bean.SkillMsgAttachment;
import com.yizhuan.xchat_android_core.skill.entity.SkillNotifyEntity;
/**
* <p> 文字消息holder </p>
*
* @author jiahui
* @date 2018/1/10
*/
public class MsgViewHolderSkill extends MsgViewHolderBase {
private TextView mTvTitle;
private TextView mTvContent;
private SkillMsgAttachment matchAttachment;
public MsgViewHolderSkill(BaseMultiItemFetchLoadAdapter adapter) {
super(adapter);
}
@Override
protected int getContentResId() {
return R.layout.layout_msg_view_holder_skill;
}
@Override
protected void inflateContentView() {
mTvTitle = findViewById(R.id.tv_title);
mTvContent = findViewById(R.id.tv_content);
}
@Override
protected void bindContentView() {
CharSequence title = "";
CharSequence content = "";
MsgAttachment attachment = message.getAttachment();
if (attachment instanceof SkillMsgAttachment) {
matchAttachment = (SkillMsgAttachment) attachment;
SkillNotifyEntity entity = matchAttachment.getEntity();
title = entity.getLayout().getTitle().getContent();
if (!entity.getLayout().getContents().isEmpty()) {
content = entity.getLayout().getContents().get(0).getContent();
}
}
mTvTitle.setText(title);
mTvContent.setText(content);
}
}

View File

@@ -17,6 +17,8 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ItemDecoration import androidx.recyclerview.widget.RecyclerView.ItemDecoration
import com.netease.nim.uikit.support.glide.GlideApp import com.netease.nim.uikit.support.glide.GlideApp
import com.yizhuan.erban.R import com.yizhuan.erban.R
import com.yizhuan.erban.audio.helper.AudioPlayerHelper
import com.yizhuan.erban.audio.helper.OnPlayListener
import com.yizhuan.erban.base.BaseViewBindingFragment import com.yizhuan.erban.base.BaseViewBindingFragment
import com.yizhuan.erban.databinding.FragmentUserinfoUserinfoBinding import com.yizhuan.erban.databinding.FragmentUserinfoUserinfoBinding
import com.yizhuan.erban.module_hall.HallDataManager import com.yizhuan.erban.module_hall.HallDataManager
@@ -30,6 +32,7 @@ import com.yizhuan.erban.ui.user.adapter.GiftAdapter
import com.yizhuan.erban.ui.user.adapter.SkillCardAdapter import com.yizhuan.erban.ui.user.adapter.SkillCardAdapter
import com.yizhuan.erban.ui.user.decorationsend.UserInfoSkillDecoration import com.yizhuan.erban.ui.user.decorationsend.UserInfoSkillDecoration
import com.yizhuan.erban.ui.user.viewmodel.UserInfoViewModel import com.yizhuan.erban.ui.user.viewmodel.UserInfoViewModel
import com.yizhuan.erban.ui.utils.ImageLoadUtilsV2
import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil
import com.yizhuan.xchat_android_core.auth.AuthModel import com.yizhuan.xchat_android_core.auth.AuthModel
import com.yizhuan.xchat_android_core.module_hall.hall.HallModel import com.yizhuan.xchat_android_core.module_hall.hall.HallModel
@@ -40,6 +43,7 @@ import com.yizhuan.xchat_android_core.user.bean.UserDetailInfo.DataBean.UserGift
import com.yizhuan.xchat_android_core.user.bean.UserInfoSkillEntity import com.yizhuan.xchat_android_core.user.bean.UserInfoSkillEntity
import com.yizhuan.xchat_android_core.utils.net.BeanObserver import com.yizhuan.xchat_android_core.utils.net.BeanObserver
import com.yizhuan.xchat_android_core.utils.net.RxHelper import com.yizhuan.xchat_android_core.utils.net.RxHelper
import com.yizhuan.xchat_android_core.utils.toast
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes import com.yizhuan.xchat_android_library.annatation.ActLayoutRes
@@ -50,6 +54,7 @@ class UserInfoInfoFragment : BaseViewBindingFragment<FragmentUserinfoUserinfoBin
private var giftAdapter: GiftAdapter? = null private var giftAdapter: GiftAdapter? = null
private var skillAdapter: SkillCardAdapter? = null private var skillAdapter: SkillCardAdapter? = null
private val vm: UserInfoViewModel by activityViewModels() private val vm: UserInfoViewModel by activityViewModels()
private var audioPlaying = false
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun initClanAndHall(clanAndHallInfo: ClanAndHallInfo) { private fun initClanAndHall(clanAndHallInfo: ClanAndHallInfo) {
@@ -140,6 +145,22 @@ class UserInfoInfoFragment : BaseViewBindingFragment<FragmentUserinfoUserinfoBin
* 技能卡 * 技能卡
*/ */
private fun initSkillCardList(list: List<UserInfoSkillEntity>) { private fun initSkillCardList(list: List<UserInfoSkillEntity>) {
val audio = list.find { it.cardId == 8 }
var newList: MutableList<UserInfoSkillEntity> = list.toMutableList()
if (audio != null) {
binding.llAudio.visibility = View.VISIBLE
ImageLoadUtilsV2.loadImage(binding.ivAudioIcon, audio?.icon)
audio?.name?.let { binding.tvAudioName.text = it }
binding.livUser.stop()
binding.llAudio.setOnClickListener { toggleAudio(audio.propVals) }
newList.remove(audio)
if (newList.isEmpty()) {//只有声音秀
binding.recyclerSkill.visibility = View.GONE
return
}
} else {
binding.llAudio.visibility = View.GONE
}
if (skillAdapter == null) { if (skillAdapter == null) {
skillAdapter = SkillCardAdapter(mContext) skillAdapter = SkillCardAdapter(mContext)
skillAdapter?.setHeaderAndEmpty(true) skillAdapter?.setHeaderAndEmpty(true)
@@ -153,12 +174,10 @@ class UserInfoInfoFragment : BaseViewBindingFragment<FragmentUserinfoUserinfoBin
LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false) LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false)
binding.recyclerSkill.adapter = skillAdapter binding.recyclerSkill.adapter = skillAdapter
} }
if (list.isEmpty()) { if (newList.isEmpty()) {
skillAdapter?.setNewData(ArrayList(0))
skillAdapter?.emptyView = createSkillEmptyView() skillAdapter?.emptyView = createSkillEmptyView()
} else {
skillAdapter?.setNewData(list)
} }
skillAdapter?.setNewData(newList)
} }
override fun onClick(v: View) { override fun onClick(v: View) {
@@ -216,4 +235,42 @@ class UserInfoInfoFragment : BaseViewBindingFragment<FragmentUserinfoUserinfoBin
} }
binding.tvGiftDetail.setOnClickListener(this) binding.tvGiftDetail.setOnClickListener(this)
} }
private fun toggleAudio(list: List<String>) {
val url = list.find { it.contains("http") } ?: return
if (!audioPlaying) {
playAudio(url)
} else {
stopAudio()
}
}
private fun playAudio(url: String) {
if (audioPlaying) return
audioPlaying = true
binding.livUser.start()
binding.ivAudioControl.setImageResource(R.drawable.ic_skill_play)
AudioPlayerHelper.get().playInThread(url, object : OnPlayListener {
override fun onError(error: String?) {
"播放出错,请重试".toast()
stopAudio()
}
override fun onPrepared() {}
override fun onPlaying(currDuration: Long) {}
override fun onCompletion() {
stopAudio()
}
})
}
private fun stopAudio() {
if (!audioPlaying) return
audioPlaying = false
binding.livUser.stop()
binding.ivAudioControl.setImageResource(R.drawable.ic_skill_pause)
AudioPlayerHelper.get().endPlay()
}
} }

View File

@@ -26,22 +26,26 @@ public class LivingIconView extends AppCompatImageView {
private AnimationDrawable drawable; private AnimationDrawable drawable;
private int drawableId; private int drawableId;
private int dpWidth = 0;
private int dpHeight = 0;
public LivingIconView(Context context, @Nullable AttributeSet attrs) { public LivingIconView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs); super(context, attrs);
int dp_9 = UIUtil.dip2px(context, 9);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LivingIconView); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LivingIconView);
drawableId = a.getResourceId(R.styleable.LivingIconView_cus_drawable, R.drawable.living_icon_animation); drawableId = a.getResourceId(R.styleable.LivingIconView_cus_drawable, R.drawable.living_icon_animation);
dpWidth = (int) a.getDimension(R.styleable.LivingIconView_cus_dp_width, dp_9);
dpHeight = (int) a.getDimension(R.styleable.LivingIconView_cus_dp_height, dp_9);
a.recycle(); a.recycle();
init(context); init(context);
} }
private void init(Context context){ private void init(Context context) {
drawable = (AnimationDrawable) context.getResources().getDrawable(drawableId); drawable = (AnimationDrawable) context.getResources().getDrawable(drawableId);
drawable.setOneShot(false); drawable.setOneShot(false);
setScaleType(ScaleType.FIT_CENTER); setScaleType(ScaleType.FIT_CENTER);
setImageDrawable(drawable); setImageDrawable(drawable);
int dp_9 = UIUtil.dip2px(context, 9); setLayoutParams(new ViewGroup.LayoutParams(dpWidth, dpHeight));
setLayoutParams(new ViewGroup.LayoutParams(dp_9, dp_9));
} }
public void setColor(int color) { public void setColor(int color) {

View File

@@ -1,10 +1,17 @@
package com.yizhuan.erban.ui.widget.dialog; package com.yizhuan.erban.ui.widget.dialog;
import static android.graphics.Typeface.BOLD;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.view.Window; import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.StyleSpan;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorRes;
import com.yizhuan.erban.R; import com.yizhuan.erban.R;
import com.yizhuan.xchat_android_core.utils.TextUtils; import com.yizhuan.xchat_android_core.utils.TextUtils;
@@ -18,6 +25,10 @@ public class CommonTipDialog extends BaseDialog {
private String okText = "确定"; private String okText = "确定";
private String cancelText = "取消"; private String cancelText = "取消";
private boolean isBold;
private @ColorRes
int color = -1;
private int textSize = -1;
public CommonTipDialog(Context context) { public CommonTipDialog(Context context) {
super(context, R.style.dialog); super(context, R.style.dialog);
@@ -36,7 +47,19 @@ public class CommonTipDialog extends BaseDialog {
TextView tip = findViewById(R.id.message); TextView tip = findViewById(R.id.message);
tip.setText(tipMsg); tip.setText(tipMsg);
if (color != -1) {
tip.setTextColor(getContext().getResources().getColor(color));
}
SpannableStringBuilder builder = new SpannableStringBuilder(tipMsg);
if (textSize != -1) {
AbsoluteSizeSpan sizeSpan = new AbsoluteSizeSpan(textSize);
builder.setSpan(sizeSpan, 0, builder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
if (isBold) {
StyleSpan boldSpan = new StyleSpan(BOLD);
builder.setSpan(boldSpan, 0, builder.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
}
tip.setText(builder);
TextView ok = findViewById(R.id.btn_ok); TextView ok = findViewById(R.id.btn_ok);
ok.setText(okText); ok.setText(okText);
ok.setOnClickListener(v -> { ok.setOnClickListener(v -> {
@@ -59,6 +82,18 @@ public class CommonTipDialog extends BaseDialog {
this.tipMsg = tipMsg; this.tipMsg = tipMsg;
} }
public void setBold(boolean isBold) {
this.isBold = isBold;
}
public void setTextColor(@ColorRes int color) {
this.color = color;
}
public void setTextSize(int textSize) {
this.textSize = textSize;
}
private OnActionListener l; private OnActionListener l;
public void setOkText(String okText) { public void setOkText(String okText) {

View File

@@ -2,20 +2,12 @@ package com.yizhuan.erban.vip
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.sdk.mobile.manager.login.views.Loading
import com.yizhuan.erban.base.BaseViewModel import com.yizhuan.erban.base.BaseViewModel
import com.yizhuan.xchat_android_core.bean.response.ListResult
import com.yizhuan.xchat_android_core.home.bean.*
import com.yizhuan.xchat_android_core.home.model.HomeModel
import com.yizhuan.xchat_android_core.user.UserModel import com.yizhuan.xchat_android_core.user.UserModel
import com.yizhuan.xchat_android_core.utils.net.ServerException
import com.yizhuan.xchat_android_core.utils.toast import com.yizhuan.xchat_android_core.utils.toast
import com.yizhuan.xchat_android_core.vip.VipAuthInfo import com.yizhuan.xchat_android_core.vip.VipAuthInfo
import com.yizhuan.xchat_android_core.vip.VipInfo import com.yizhuan.xchat_android_core.vip.VipInfo
import com.yizhuan.xchat_android_core.vip.VipModel import com.yizhuan.xchat_android_core.vip.VipModel
import com.yizhuan.xchat_android_core.vip.VipPageInfo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
class VipViewModel : BaseViewModel() { class VipViewModel : BaseViewModel() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_20" />
<solid android:color="@color/color_30_ffce4e" />
</shape>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> android:shape="rectangle">
<solid android:color="#FFBC51" /> <solid android:color="#1AFFBC51" />
<corners android:radius="@dimen/dp_8" /> <corners android:radius="@dimen/dp_8" />
</shape> </shape>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_15" />
<stroke android:color="#8CA1FF" android:width="1dp"/>
</shape>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:bottomLeftRadius="@dimen/dp_4"
android:bottomRightRadius="@dimen/dp_19"
android:topLeftRadius="@dimen/dp_19"
android:topRightRadius="@dimen/dp_4" />
<gradient
android:endColor="#B3daf8fc"
android:startColor="#B3f4f5ef"
android:angle="180"
android:type="linear"/>
</shape>

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item
android:drawable="@drawable/ic_skill_audio_anim_01"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_02"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_03"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_04"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_05"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_06"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_07"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_08"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_09"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_10"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_11"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_12"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_13"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_14"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_15"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_16"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_17"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_18"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_19"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_20"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_21"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_22"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_23"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_24"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_25"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_26"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_27"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_28"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_29"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_30"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_31"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_32"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_33"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_34"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_35"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_36"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_37"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_38"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_39"
android:duration="@integer/skill_icon_anim_duration" />
<item
android:drawable="@drawable/ic_skill_audio_anim_40"
android:duration="@integer/skill_icon_anim_duration" />
</animation-list>

View File

@@ -11,19 +11,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_25" /> android:layout_marginTop="@dimen/dp_25" />
<TextView
android:id="@+id/count"
android:layout_width="match_parent"
android:layout_height="44dp"
android:layout_centerVertical="true"
android:background="@color/bg_secondary_2a2a39"
android:gravity="center_vertical"
android:paddingLeft="15dp"
android:textColor="@color/text_secondary_4f516a"
android:textSize="14dp"
android:visibility="gone" />
<com.yizhuan.erban.common.widget.StatusLayout <com.yizhuan.erban.common.widget.StatusLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View File

@@ -11,19 +11,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<TextView
android:id="@+id/count"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="44dp"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:background="@color/bg_secondary_2a2a39"
android:paddingLeft="15dp"
android:textColor="@color/text_secondary_4f516a"
android:textSize="14dp" />
<com.yizhuan.erban.common.widget.StatusLayout <com.yizhuan.erban.common.widget.StatusLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">

View File

@@ -22,14 +22,15 @@
<androidx.appcompat.widget.AppCompatButton <androidx.appcompat.widget.AppCompatButton
android:layout_width="@dimen/dp_100" android:layout_width="175dp"
android:layout_height="wrap_content" android:layout_height="@dimen/dp_40"
android:id="@+id/btn_ensure" android:id="@+id/btn_ensure"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="@dimen/dp_20" android:layout_marginBottom="@dimen/dp_20"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
android:textColor="@color/white" android:textColor="@color/white"
android:background="@drawable/common_btn_bg"
android:text="@string/text_ok" android:text="@string/text_ok"
/> />

View File

@@ -281,6 +281,52 @@
android:textColor="@color/color_333333" android:textColor="@color/color_333333"
android:textSize="@dimen/sp_14" /> android:textSize="@dimen/sp_14" />
<LinearLayout
android:id="@+id/ll_audio"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_40"
android:layout_marginTop="@dimen/dp_8"
android:background="@drawable/bg_userinfo_skill_audio"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="gone">
<ImageView
android:id="@+id/iv_audio_icon"
android:layout_width="@dimen/dp_32"
android:layout_height="@dimen/dp_32"
android:layout_marginLeft="@dimen/dp_13"
tools:src="@mipmap/app_logo" />
<TextView
android:id="@+id/tv_audio_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_8"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_16"
tools:text="声音秀" />
<ImageView
android:id="@+id/iv_audio_control"
android:layout_width="@dimen/dp_18"
android:layout_height="@dimen/dp_18"
android:layout_marginLeft="@dimen/dp_8"
android:src="@drawable/ic_skill_pause" />
<com.yizhuan.erban.ui.widget.LivingIconView
android:id="@+id/liv_user"
android:layout_width="@dimen/dp_40"
android:layout_height="15dp"
android:layout_marginLeft="@dimen/dp_8"
android:background="@color/transparent"
app:cus_drawable="@drawable/skill_audio_animation"
app:cus_dp_height="15dp"
app:cus_dp_width="@dimen/dp_40" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_skill" android:id="@+id/recycler_skill"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -297,8 +343,8 @@
android:background="@drawable/bg_secondary_radius_10" android:background="@drawable/bg_secondary_radius_10"
android:orientation="vertical" android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0" app:layout_constraintTop_toBottomOf="@id/ll_skill"
app:layout_constraintTop_toBottomOf="@id/ll_skill"> app:layout_constraintVertical_bias="0">
<TextView <TextView
android:id="@+id/tv_gift_detail" android:id="@+id/tv_gift_detail"
@@ -314,8 +360,8 @@
android:id="@+id/rv_gift" android:id="@+id/rv_gift"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="@dimen/dp_14"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/dp_14"
android:layout_marginBottom="@dimen/dp_15" android:layout_marginBottom="@dimen/dp_15"
android:clipToPadding="false" android:clipToPadding="false"
android:paddingStart="2dp" android:paddingStart="2dp"

View File

@@ -3,11 +3,11 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="142dp" android:layout_width="142dp"
android:paddingTop="@dimen/dp_8" android:layout_height="wrap_content"
android:paddingBottom="@dimen/dp_8"
android:paddingLeft="@dimen/dp_5" android:paddingLeft="@dimen/dp_5"
android:paddingTop="@dimen/dp_8"
android:paddingRight="@dimen/dp_5" android:paddingRight="@dimen/dp_5"
android:layout_height="wrap_content"> android:paddingBottom="@dimen/dp_8">
<ImageView <ImageView
android:id="@+id/iv_icon" android:id="@+id/iv_icon"
@@ -30,15 +30,19 @@
<TextView <TextView
android:id="@+id/tv_desc" android:id="@+id/tv_desc"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_5"
android:ellipsize="end"
app:layout_constrainedWidth="true"
android:fontFamily="sans-serif"
android:singleLine="true"
android:textColor="@color/color_333333" android:textColor="@color/color_333333"
android:textSize="@dimen/sp_12" android:textSize="@dimen/sp_12"
android:fontFamily="sans-serif" app:layout_constraintLeft_toLeftOf="@id/tv_title"
app:layout_constraintStart_toStartOf="@id/tv_title"
app:layout_constraintTop_toBottomOf="@id/tv_title" app:layout_constraintTop_toBottomOf="@id/tv_title"
android:layout_marginTop="@dimen/dp_5" app:layout_constraintRight_toRightOf="parent"
tools:text="英雄联盟手游" /> tools:text="盟手游英雄联盟手游" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/dp_5">
<TextView
android:id="@+id/tv_title"
android:maxWidth="215dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp_15"
android:textStyle="bold"
tools:text="恭喜您,获得抽奖机会,点我抽奖>>" />
<TextView
android:id="@+id/tv_content"
android:maxWidth="215dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10"
android:lineSpacingMultiplier="1.2"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp_12"
tools:text="恭喜您,获得抽奖机会,点我抽奖>>" />
</LinearLayout>

View File

@@ -1,84 +1,58 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="295dp" android:layout_width="295dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@drawable/shape_white_20dp_round" android:background="@drawable/shape_white_20dp_round"
android:paddingBottom="@dimen/dp_24" android:orientation="vertical"
tools:background="@color/white_tran_10"> tools:background="@color/black_transparent_10">
<View <View
android:id="@+id/space_view"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="@dimen/dp_26" android:layout_height="@dimen/dp_26" />
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/message" android:id="@+id/message"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_marginBottom="@dimen/dp_32"
android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:lineSpacingMultiplier="1.2"
android:paddingStart="20dp" android:paddingStart="20dp"
android:paddingEnd="20dp" android:paddingEnd="20dp"
android:textColor="@color/color_333333" android:textColor="@color/color_333333"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintTop_toBottomOf="@id/space_view"
tools:text="购买成功是否立即驾驶sd水电费水电费sfasdfasdfasdfasdfasdf" /> tools:text="购买成功是否立即驾驶sd水电费水电费sfasdfasdfasdfasdfasdf" />
<LinearLayout
<TextView
android:id="@+id/sub_message"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_8" android:layout_marginBottom="24dp"
android:gravity="center" android:gravity="center_horizontal"
android:paddingStart="31dp" android:orientation="horizontal">
android:paddingEnd="31dp"
android:textColor="@color/color_999999"
android:textSize="13sp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/message"
tools:text="购买成功是否立即驾驶sd水电费水电费sfasdfasdfasdfasdfasdf" />
<TextView
android:id="@+id/btn_cancel"
android:layout_width="120dp"
android:layout_height="38dp"
android:layout_marginEnd="@dimen/dp_16"
android:background="@drawable/bg_common_cancel"
android:gravity="center"
android:text="@string/cancel"
android:textColor="@color/color_7154EE"
android:textSize="15sp" />
<androidx.constraintlayout.widget.Barrier <TextView
android:id="@+id/content_barrier" android:id="@+id/btn_ok"
android:layout_width="0dp" android:layout_width="120dp"
android:layout_height="0dp" android:layout_height="38dp"
app:barrierDirection="bottom" android:background="@drawable/bg_common_confirm"
app:constraint_referenced_ids="message,sub_message" /> android:gravity="center"
android:text="@string/text_ok"
<TextView android:textColor="@color/white"
android:id="@+id/btn_cancel" android:textSize="15sp" />
android:layout_width="120dp" </LinearLayout>
android:layout_height="38dp"
android:layout_marginTop="@dimen/dp_32"
android:layout_marginRight="@dimen/dp_16"
android:background="@drawable/bg_common_cancel"
android:gravity="center"
android:text="@string/cancel"
android:textColor="@color/color_7154EE"
android:textSize="15sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/btn_ok"
app:layout_constraintTop_toBottomOf="@id/content_barrier" />
<TextView
android:id="@+id/btn_ok"
android:layout_width="120dp"
android:layout_height="38dp"
android:layout_marginTop="@dimen/dp_32"
android:background="@drawable/bg_common_confirm"
android:gravity="center"
android:text="@string/text_ok"
android:textColor="@color/white"
android:textSize="15sp"
app:layout_constraintLeft_toRightOf="@id/btn_cancel"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/content_barrier" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

View File

@@ -1,6 +1,32 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout> <layout>
<data>
<import
alias="RI"
type="com.yizhuan.erban.skill.widget.RecordIResourceItem" />
<import type="android.view.View" />
<variable
name="recordState"
type="Integer" />
<variable
name="palyState"
type="Integer" />
<variable
name="duration"
type="String" />
<variable
name="click"
type="android.view.View.OnClickListener" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
@@ -11,102 +37,128 @@
<com.yizhuan.erban.skill.widget.TimerRecorderView <com.yizhuan.erban.skill.widget.TimerRecorderView
android:id="@+id/record_view" android:id="@+id/record_view"
android:layout_width="@dimen/dp_60" android:layout_width="167dp"
android:layout_height="@dimen/dp_60" android:layout_height="167dp"
android:src="@drawable/ic_skill_audio_ready"
android:visibility="@{(recordState==RI.RECORD_STATE_READY||recordState==RI.RECORD_STATE_RECORDING)?View.VISIBLE:View.GONE}"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/icon_music_pause" app:outerWidth="@dimen/dp_20"
app:progressWidth="@dimen/dp_5" /> app:progressColor="#5C8AFF"
app:progressWidth="@dimen/dp_10" />
<TextView <TextView
android:id="@+id/tv_record_tip" android:id="@+id/tv_record_tip"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10" android:layout_marginTop="@dimen/dp_10"
android:text="@{recordState==RI.RECORD_STATE_READY?@string/skill_record_tip_ready:@string/skill_record_tip_recording}"
android:textColor="@color/black_transparent_50"
android:visibility="@{(recordState==RI.RECORD_STATE_READY||recordState==RI.RECORD_STATE_RECORDING)?View.VISIBLE:View.GONE}"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/record_view" app:layout_constraintTop_toBottomOf="@id/record_view" />
android:text="点击录制语音15S展示才艺技能" />
<Button <Button
android:id="@+id/btn_cancel" android:id="@+id/btn_cancel"
android:layout_width="wrap_content" android:layout_width="144dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_marginTop="@dimen/dp_10" android:layout_marginTop="@dimen/dp_10"
android:background="@drawable/bg_ffce4e_trans30_20dp"
android:onClick="@{click}"
android:paddingLeft="@dimen/dp_20" android:paddingLeft="@dimen/dp_20"
android:paddingRight="@dimen/dp_20" android:paddingRight="@dimen/dp_20"
android:textColor="@color/color_7154EE"
android:visibility="@{recordState==RI.RECORD_STATE_RECORDING?View.VISIBLE:View.GONE}"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
android:textSize="@dimen/sp_14"
app:layout_constraintTop_toBottomOf="@id/tv_record_tip" app:layout_constraintTop_toBottomOf="@id/tv_record_tip"
tools:text="取消录制" /> android:text="取消重新录制" />
<!--录制完成 审核中--> <!--录制完成 审核中-->
<TextView <TextView
android:id="@+id/tv_sound" android:id="@+id/tv_sound"
android:layout_width="200dp" android:layout_width="150dp"
android:layout_height="@dimen/dp_40" android:layout_height="@dimen/dp_30"
android:background="#66000000" android:layout_marginBottom="@dimen/dp_20"
android:drawableLeft="@drawable/icon_music_pause" android:background="@drawable/bg_skill_record_sound"
android:drawablePadding="@dimen/dp_10"
android:gravity="center" android:gravity="center"
android:onClick="@{click}"
android:textColor="#8CA1FF"
android:textSize="@dimen/sp_12"
android:visibility="@{(recordState==RI.RECORD_STATE_READY||recordState==RI.RECORD_STATE_RECORDING)?View.GONE:View.VISIBLE}"
app:layout_constraintBottom_toTopOf="@id/bottom_button_barrier"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" android:text="@{@string/skill_audio_duration(duration)}"
tools:text="10s" /> tools:text="10s" />
<ImageView
android:id="@+id/iv_play"
android:layout_width="@dimen/dp_24"
android:layout_height="@dimen/dp_24"
android:layout_marginLeft="@dimen/dp_4"
android:onClick="@{click}"
android:src="@{palyState==RI.PLAY_STATE_PLAYING?@drawable/ic_skill_play:@drawable/ic_skill_pause}"
android:visibility="@{(recordState==RI.RECORD_STATE_READY||recordState==RI.RECORD_STATE_RECORDING)?View.GONE:View.VISIBLE}"
app:layout_constraintBottom_toBottomOf="@id/tv_sound"
app:layout_constraintLeft_toLeftOf="@id/tv_sound"
app:layout_constraintTop_toTopOf="@id/tv_sound" />
<TextView <TextView
android:id="@+id/tv_duration" android:id="@+id/tv_status"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_20" android:layout_marginLeft="@dimen/dp_5"
android:gravity="center" android:gravity="center"
android:textSize="@dimen/sp_10"
android:visibility="@{(recordState==RI.RECORD_STATE_READY||recordState==RI.RECORD_STATE_RECORDING)?View.GONE:View.VISIBLE}"
app:layout_constraintBottom_toBottomOf="@id/tv_sound" app:layout_constraintBottom_toBottomOf="@id/tv_sound"
app:layout_constraintStart_toEndOf="@id/tv_sound" app:layout_constraintStart_toEndOf="@id/tv_sound"
app:layout_constraintTop_toTopOf="@id/tv_sound" app:layout_constraintTop_toTopOf="@id/tv_sound"
tools:text="审核通过" /> android:text="@{recordState==RI.RECORD_STATE_JUDGE?@string/skill_record_judging:recordState==RI.RECORD_STATE_AGREE?@string/skill_record_agree:@string/skill_record_fail}" />
<Button <Button
android:id="@+id/btn_delete" android:id="@+id/btn_delete"
android:layout_width="wrap_content" android:layout_width="64dp"
android:layout_height="40dp" android:layout_height="20dp"
android:layout_marginTop="@dimen/dp_20" android:layout_marginBottom="@dimen/dp_27"
android:paddingLeft="@dimen/dp_20" android:onClick="@{click}"
android:paddingRight="@dimen/dp_20" android:background="@drawable/bg_ffce4e_trans30_20dp"
android:visibility="gone" android:textColor="@color/color_7154EE"
android:visibility="@{recordState==RI.RECORD_STATE_AGREE?View.VISIBLE:View.GONE}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_restart" app:layout_constraintEnd_toStartOf="@id/btn_restart"
app:layout_constraintHorizontal_chainStyle="packed" app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_record_tip" android:textSize="@dimen/sp_10"
tools:text="删除声音" /> android:text="删除声音" />
<Button <Button
android:id="@+id/btn_restart" android:id="@+id/btn_restart"
android:layout_width="wrap_content" android:layout_width="64dp"
android:layout_height="40dp" android:layout_height="20dp"
android:layout_marginLeft="@dimen/dp_20" android:layout_marginLeft="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_20" android:layout_marginBottom="@dimen/dp_27"
android:paddingLeft="@dimen/dp_20" android:onClick="@{click}"
android:paddingRight="@dimen/dp_20" android:background="@drawable/common_btn_bg"
android:visibility="@{(recordState==RI.RECORD_STATE_AGREE||recordState==RI.RECORD_STATE_REFUSE||recordState==RI.RECORD_STATE_JUDGE)?View.VISIBLE:View.GONE}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_delete" app:layout_constraintStart_toEndOf="@id/btn_delete"
app:layout_constraintTop_toBottomOf="@id/tv_record_tip"
app:layout_goneMarginLeft="0dp" app:layout_goneMarginLeft="0dp"
tools:text="重新录制" /> android:textColor="@color/white"
android:textSize="@dimen/sp_10"
android:text="重新录制" />
<androidx.constraintlayout.widget.Group <androidx.constraintlayout.widget.Barrier
android:id="@+id/group_ready" android:id="@+id/bottom_button_barrier"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:constraint_referenced_ids="record_view,tv_record_tip,btn_cancel" /> app:barrierDirection="top"
app:constraint_referenced_ids="btn_restart,btn_delete" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_judge"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:constraint_referenced_ids="tv_sound,tv_duration,btn_delete,btn_restart" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</layout> </layout>

View File

@@ -329,6 +329,8 @@
<declare-styleable name="LivingIconView"> <declare-styleable name="LivingIconView">
<attr name="cus_drawable" format="reference" /> <attr name="cus_drawable" format="reference" />
<attr name="cus_dp_width" format="dimension" />
<attr name="cus_dp_height" format="dimension" />
</declare-styleable> </declare-styleable>
<declare-styleable name="CodeEditText"> <declare-styleable name="CodeEditText">
<attr name="strokeLength" format="integer" /> <attr name="strokeLength" format="integer" />
@@ -358,10 +360,10 @@
<enum name="center" value="1" /> <enum name="center" value="1" />
<enum name="right" value="2" /> <enum name="right" value="2" />
</attr> </attr>
<attr name="rollviewpager_hint_paddingRight" format="dimension" /> <attr name="rollviewpager_hint_paddingRight" format="dimension"/>
<attr name="rollviewpager_hint_paddingLeft" format="dimension" /> <attr name="rollviewpager_hint_paddingLeft" format="dimension"/>
<attr name="rollviewpager_hint_paddingTop" format="dimension" /> <attr name="rollviewpager_hint_paddingTop" format="dimension"/>
<attr name="rollviewpager_hint_paddingBottom" format="dimension" /> <attr name="rollviewpager_hint_paddingBottom" format="dimension"/>
<attr name="rollviewpager_play_delay" format="integer" /> <attr name="rollviewpager_play_delay" format="integer" />
<attr name="rollviewpager_hint_color" format="color" /> <attr name="rollviewpager_hint_color" format="color" />
@@ -369,9 +371,12 @@
</declare-styleable> </declare-styleable>
<!--倒计时录音控件--> <!--倒计时录音控件-->
<declare-styleable name="TimerRecorderView"> <declare-styleable name="TimerRecorderView">
<attr name="progressWidth" format="dimension" /> <attr name="progressWidth" format="dimension" />
<attr name="outerWidth" format="dimension" />
<attr name="progressColor" format="color" />
</declare-styleable> </declare-styleable>
<!--多颜色渐变--> <!--多颜色渐变-->

View File

@@ -598,5 +598,6 @@
<color name="color_40_333333">#66333333</color> <color name="color_40_333333">#66333333</color>
<color name="color_30_ffce4e">#4DFFCE4E</color>
</resources> </resources>

View File

@@ -3,5 +3,6 @@
<integer name="tab_anim_duration">15</integer> <integer name="tab_anim_duration">15</integer>
<integer name="loading_anim_duration">70</integer> <integer name="loading_anim_duration">70</integer>
<integer name="living_icon_anim_duration">60</integer> <integer name="living_icon_anim_duration">60</integer>
<integer name="skill_icon_anim_duration">30</integer>
<integer name="dy_like_anim_duration">37</integer> <integer name="dy_like_anim_duration">37</integer>
</resources> </resources>

View File

@@ -916,6 +916,12 @@
<string name="delete_skill">删除技能卡</string> <string name="delete_skill">删除技能卡</string>
<string name="tip_save_skill">您填写的技能卡未保存,是否直接返\n回上一页</string> <string name="tip_save_skill">您填写的技能卡未保存,是否直接返\n回上一页</string>
<string name="tip_delete_skill">确定要删除该技能卡?</string> <string name="tip_delete_skill">确定要删除该技能卡?</string>
<string name="skill_record_judging">审核中</string>
<string name="skill_record_agree">审核通过</string>
<string name="skill_record_fail">审核不通过</string>
<string name="skill_record_tip_ready"> 点击录制语音15S展示才艺技能</string>
<string name="skill_record_tip_recording">录音开始不少于3s哦</string>
<string name="skill_audio_duration">%ss</string>
<!--CP--> <!--CP-->
<string name="cp_empty_text">&#160;</string> <string name="cp_empty_text">&#160;</string>

View File

@@ -15,10 +15,10 @@ import com.yizhuan.xchat_android_core.PreferencesUtils;
public class QuickLoginUiConfig { public class QuickLoginUiConfig {
public static UnifyUiConfig getUiConfig(final Context context) { public static UnifyUiConfig getUiConfig(final Context context) {
int logoToTop = 30; int logoToTop = 60;
int logoWidth = 100; int logoWidth = 100;
int logoHeight = 100; int logoHeight = 100;
int maskNumToTop = logoToTop + logoHeight + 200; int maskNumToTop = logoToTop + logoHeight + 170;
int maskNumSize = 20; int maskNumSize = 20;
int sloganToTop = maskNumToTop + maskNumSize + 10; int sloganToTop = maskNumToTop + maskNumSize + 10;
int sloganSize = 14; int sloganSize = 14;
@@ -30,15 +30,18 @@ public class QuickLoginUiConfig {
final boolean privacyState = PreferencesUtils.readPrivacyState(); final boolean privacyState = PreferencesUtils.readPrivacyState();
UnifyUiConfig uiConfig = new UnifyUiConfig.Builder() UnifyUiConfig uiConfig = new UnifyUiConfig.Builder()
// 状态栏 // 状态栏
.setStatusBarDarkColor(false) .setStatusBarDarkColor(true)
.setStatusBarColor(ContextCompat.getColor(context, R.color.bg_normal_1c1b22)) .setStatusBarColor(ContextCompat.getColor(context, R.color.bg_normal_1c1b22))
.setBackgroundImage("bg_normal") .setBackgroundImage("bg_normal")
// 设置导航栏 // 设置导航栏
.setNavigationTitle(" ") .setHideNavigation(false)
.setHideNavigationBackIcon(false)
.setNavigationIcon("quick_pass_back") .setNavigationIcon("quick_pass_back")
.setNavigationHeight(50)
.setNavigationBackIconWidth(25) .setNavigationBackIconWidth(25)
.setNavigationBackIconHeight(25) .setNavigationBackIconHeight(25)
.setHideNavigation(false) .setNavigationTitle("一键登录")
.setNavigationTitleColor(ContextCompat.getColor(context, R.color.text_normal_c6c6e9))
// 设置logo // 设置logo
.setLogoIconName("quick_pass_logo") .setLogoIconName("quick_pass_logo")
.setLogoWidth(logoWidth) .setLogoWidth(logoWidth)
@@ -85,7 +88,7 @@ public class QuickLoginUiConfig {
.setPrivacySize(12) .setPrivacySize(12)
// .setPrivacyTopYOffset(510) // .setPrivacyTopYOffset(510)
.setPrivacyBottomYOffset(20) .setPrivacyBottomYOffset(20)
.setPrivacyXOffset(20) .setPrivacyMarginLeft(20)
.setPrivacyMarginRight(20) .setPrivacyMarginRight(20)
.setCheckedImageName("quick_pass_checked") .setCheckedImageName("quick_pass_checked")
.setUnCheckedImageName("quick_pass_uncheck") .setUnCheckedImageName("quick_pass_uncheck")

View File

@@ -1,5 +1,6 @@
package com.yizhuan.xchat_android_core.manager; package com.yizhuan.xchat_android_core.manager;
import android.annotation.SuppressLint;
import android.os.Handler; import android.os.Handler;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@@ -718,6 +719,10 @@ public final class IMNetEaseManager {
} else if (attachment.getType() == NotificationType.ChatRoomMemberBlackAdd) { } else if (attachment.getType() == NotificationType.ChatRoomMemberBlackAdd) {
List<String> targets = ((ChatRoomNotificationAttachment) attachment).getTargets(); List<String> targets = ((ChatRoomNotificationAttachment) attachment).getTargets();
noticeChatMemberBlackAdd(targets.get(0)); noticeChatMemberBlackAdd(targets.get(0));
addBlankMember(targets.get(0));
} else if (attachment.getType() == NotificationType.ChatRoomMemberBlackRemove) {
List<String> targets = ((ChatRoomNotificationAttachment) attachment).getTargets();
AvRoomDataManager.get().removeBlackMember(targets.get(0));
} else if (attachment.getType() == NotificationType.ChatRoomMyRoomRoleUpdated) { } else if (attachment.getType() == NotificationType.ChatRoomMyRoomRoleUpdated) {
// 房间内的某人的贵族信息更新了 // 房间内的某人的贵族信息更新了
Map<String, Object> extension = null; Map<String, Object> extension = null;
@@ -2118,6 +2123,23 @@ public final class IMNetEaseManager {
AvRoomDataManager.get().removeManagerMember(account); AvRoomDataManager.get().removeManagerMember(account);
} }
/**
* 增加黑名单
*
* @param account -
*/
@SuppressLint("CheckResult")
private void addBlankMember(final String account) {
List<String> accounts = new ArrayList<>(1);
accounts.add(account);
fetchRoomMembersByIds(accounts).subscribe((chatRoomMembers, throwable) -> {
if (!ListUtils.isListEmpty(chatRoomMembers)) {
ChatRoomMember chatRoomMember = chatRoomMembers.get(0);
AvRoomDataManager.get().addBlackMember(chatRoomMember);
}
});
}
/** /**
* 加入黑名单 * 加入黑名单
* *

View File

@@ -559,6 +559,9 @@ public class CustomAttachParser implements MsgAttachmentParser {
case CustomAttachment.ANCHOR_ROOM_AUDIENCE_UPMIC: case CustomAttachment.ANCHOR_ROOM_AUDIENCE_UPMIC:
attachment = new RequestUpmicAttachment(CustomAttachment.ANCHOR_ROOM_AUDIENCE_UPMIC, 0); attachment = new RequestUpmicAttachment(CustomAttachment.ANCHOR_ROOM_AUDIENCE_UPMIC, 0);
break; break;
case CustomAttachment.SKILL_MSG_AUDIO:
attachment = new SkillMsgAttachment(second);
break;
case CustomAttachment.CP_INVITE_MESSAGE: case CustomAttachment.CP_INVITE_MESSAGE:
attachment = new CpInviteAttachment(CustomAttachment.CP_INVITE_MESSAGE_TOP_NOTICE); attachment = new CpInviteAttachment(CustomAttachment.CP_INVITE_MESSAGE_TOP_NOTICE);

View File

@@ -12,9 +12,7 @@ import com.yizhuan.xchat_android_core.noble.NobleInfo;
* @date 2017/6/8 * @date 2017/6/8
*/ */
public class CustomAttachment implements MsgAttachment { public class CustomAttachment implements MsgAttachment {
/** /** 自定义消息附件的类型,根据该字段区分不同的自定义消息 */
* 自定义消息附件的类型,根据该字段区分不同的自定义消息
*/
protected int first; protected int first;
protected int second; protected int second;
protected JSONObject data; protected JSONObject data;
@@ -66,13 +64,9 @@ public class CustomAttachment implements MsgAttachment {
// 贵族 // 贵族
public static final int CUSTOM_MESS_HEAD_NOBLE = 14; public static final int CUSTOM_MESS_HEAD_NOBLE = 14;
/** /** 靓号未生效提醒 */
* 靓号未生效提醒
*/
public static final int CUSTOM_MSG_HEADER_TYPE_GOOD_NUMBER_INACTIVE = 147; public static final int CUSTOM_MSG_HEADER_TYPE_GOOD_NUMBER_INACTIVE = 147;
/** /** 贵族快到期(前三天)消息 */
* 贵族快到期(前三天)消息
*/
public static final int CUSTOM_MSG_HEADER_TYPE_NOBLE_END = 144; public static final int CUSTOM_MSG_HEADER_TYPE_NOBLE_END = 144;
// 开通贵族 // 开通贵族
@@ -88,9 +82,7 @@ public class CustomAttachment implements MsgAttachment {
// 推荐房间 // 推荐房间
public static final int CUSTOM_MESS_SUB_RECOM_ROOM = 149; public static final int CUSTOM_MESS_SUB_RECOM_ROOM = 149;
/** /** 进场横幅 (客户端定义) */
* 进场横幅 (客户端定义)
*/
public static final int CUSTOM_MESS_SUB_ROOM_WELCOME = 141; public static final int CUSTOM_MESS_SUB_ROOM_WELCOME = 141;
// 座驾 // 座驾
@@ -121,14 +113,14 @@ public class CustomAttachment implements MsgAttachment {
public static final int CUSTOM_MSG_ASSISTANT_MSG = 19; public static final int CUSTOM_MSG_ASSISTANT_MSG = 19;
// 小秘书通用消息 // 小秘书通用消息
public static final int CUSTOM_MSG_ASSISTANT_COMMON_MSG = 191; public static final int CUSTOM_MSG_ASSISTANT_COMMON_MSG = 191;
// 房间信息更新 // 房间信息更新
public static final int CUSTOM_MSG_UPDATE_ROOM_INFO = 20; public static final int CUSTOM_MSG_UPDATE_ROOM_INFO=20;
public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_GIFT = 201; public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_GIFT=201;
public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_AUDIO = 202; public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_AUDIO=202;
public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_CLOSE_SCREEN = 203; public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_CLOSE_SCREEN=203;
public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_NOTICE = 204; // 通用公屏提示文案,使用于各种模式的开和关 public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_NOTICE = 204; // 通用公屏提示文案,使用于各种模式的开和关
public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_CLOSE_REDPACKAGE = 205; public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_CLOSE_REDPACKAGE=205;
// 群红包 // 群红包
public static final int CUSTOM_MSG_HEADER_TYPE_LUCKY_MONEY = 21; public static final int CUSTOM_MSG_HEADER_TYPE_LUCKY_MONEY = 21;
@@ -148,16 +140,16 @@ public class CustomAttachment implements MsgAttachment {
public static final int CUSTOM_MSG_SUB_TYPE_COMMON_SYSTEM_MSG_APPROVAL = 232; public static final int CUSTOM_MSG_SUB_TYPE_COMMON_SYSTEM_MSG_APPROVAL = 232;
//等级提升弹窗 //等级提升弹窗
public static final int CUSTOM_MSG_LEVEL_UP = 24; public static final int CUSTOM_MSG_LEVEL_UP=24;
public static final int CUSTOM_MSG_EXPER_LEVEL_UP = 241; public static final int CUSTOM_MSG_EXPER_LEVEL_UP=241;
public static final int CUSTOM_MSG_CHARM_LEVEL_UP = 242; public static final int CUSTOM_MSG_CHARM_LEVEL_UP=242;
public static final int CUSTOM_MSG_EXPER_LEVEL_UP_NOTICE = 243; public static final int CUSTOM_MSG_EXPER_LEVEL_UP_NOTICE=243;
//龙珠游戏 //龙珠游戏
public static final int CUSTOM_MSG_DRAGON_BAR = 25; public static final int CUSTOM_MSG_DRAGON_BAR=25;
public static final int CUSTOM_MSG_DRAGON_BAR_START = 251; public static final int CUSTOM_MSG_DRAGON_BAR_START=251;
public static final int CUSTOM_MSG_DRAGON_BAR_END = 252; public static final int CUSTOM_MSG_DRAGON_BAR_END=252;
public static final int CUSTOM_MSG_DRAGON_BAR_CANCEL = 253; public static final int CUSTOM_MSG_DRAGON_BAR_CANCEL=253;
public static final int CUSTOM_MSG_DRAGON_BAR_RUNAWAY = 254; public static final int CUSTOM_MSG_DRAGON_BAR_RUNAWAY=254;
//房间开宝箱 //房间开宝箱
public static final int CUSTOM_MSG_BOX = 26; public static final int CUSTOM_MSG_BOX = 26;
public static final int CUSTOM_MSG_SUB_BOX_ME = 261;//自己可见 public static final int CUSTOM_MSG_SUB_BOX_ME = 261;//自己可见
@@ -194,7 +186,7 @@ public class CustomAttachment implements MsgAttachment {
public static final int CUSTOM_MSG_QUEUING_MIC = 30; public static final int CUSTOM_MSG_QUEUING_MIC = 30;
public static final int CUSTOM_MSG_SUB_QUEUING_MIC_NON_EMPTY = 301; // 从无人排麦到有人排麦 public static final int CUSTOM_MSG_SUB_QUEUING_MIC_NON_EMPTY = 301; // 从无人排麦到有人排麦
public static final int CUSTOM_MSG_SUB_QUEUING_MIC_EMPTY = 302; // 从有人排麦到无人排麦 public static final int CUSTOM_MSG_SUB_QUEUING_MIC_EMPTY = 302; // 从有人排麦到无人排麦
public static final int CUSTOM_MSG_SUB_QUEUING_MIC_MODE_OPEN = 303; // 开启排麦模式 public static final int CUSTOM_MSG_SUB_QUEUING_MIC_MODE_OPEN = 303; // 开启排麦模式
public static final int CUSTOM_MSG_SUB_QUEUING_MIC_MODE_CLOSE = 304; // 关闭排麦模式 public static final int CUSTOM_MSG_SUB_QUEUING_MIC_MODE_CLOSE = 304; // 关闭排麦模式
public static final int CUSTOM_MSG_SUB_QUEUING_MIC_FREE_MIC_OPEN = 305; // 将坑位设置成自由麦 public static final int CUSTOM_MSG_SUB_QUEUING_MIC_FREE_MIC_OPEN = 305; // 将坑位设置成自由麦
public static final int CUSTOM_MSG_SUB_QUEUING_MIC_FREE_MIC_CLOSE = 306; // 将坑位设置成排麦 public static final int CUSTOM_MSG_SUB_QUEUING_MIC_FREE_MIC_CLOSE = 306; // 将坑位设置成排麦
@@ -433,6 +425,8 @@ public class CustomAttachment implements MsgAttachment {
///个播房观众点击空坑位,房主收到请求上麦提示 ///个播房观众点击空坑位,房主收到请求上麦提示
public static final int ANCHOR_ROOM_AUDIENCE_UPMIC = 86; public static final int ANCHOR_ROOM_AUDIENCE_UPMIC = 86;
//技能卡审核
public static final int SKILL_MSG_AUDIO = 87;
public static final int CP_INVITE_MESSAGE = 88; public static final int CP_INVITE_MESSAGE = 88;

View File

@@ -0,0 +1,42 @@
package com.yizhuan.xchat_android_core.im.custom.bean;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.yizhuan.xchat_android_core.skill.entity.SkillNotifyEntity;
public class SkillMsgAttachment extends CustomAttachment {
private SkillNotifyEntity entity;
@Override
protected void parseData(JSONObject data) {
//不服不行
if (data != null) {
String json = data.toJSONString();
if (json.contains("\\")) {
json = json.replace("\\", "");
if (json.contains("\"{")) {
json = json.replace("\"{", "{");
}
if (json.contains("}\"")) {
json = json.replace("}\"", "}");
}
}
entity = new Gson().fromJson(json, SkillNotifyEntity.class);
}
}
public SkillMsgAttachment(int second) {
super(SKILL_MSG_AUDIO, second);
}
@Override
protected JSONObject packData() {
String jsonStr = new Gson().toJson(entity);
return JSONObject.parseObject(jsonStr);
}
public SkillNotifyEntity getEntity() {
return entity;
}
}

View File

@@ -474,6 +474,32 @@ public final class AvRoomDataManager {
} }
} }
public void addBlackMember(ChatRoomMember chatRoomMember) {
if (chatRoomMember == null || containsAdminMember(chatRoomMember.getAccount())) return;
mRoomLimitMemberList.add(chatRoomMember);
}
public boolean containsBlackMember(String uid) {
for (ChatRoomMember chatRoomMember : mRoomLimitMemberList) {
if (Objects.equals(chatRoomMember.getAccount(), String.valueOf(uid))) {
return true;
}
}
return false;
}
public void removeBlackMember(String account) {
if (ListUtils.isListEmpty(mRoomLimitMemberList) || TextUtils.isEmpty(account)) return;
ListIterator<ChatRoomMember> iterator = mRoomLimitMemberList.listIterator();
while (iterator.hasNext()) {
ChatRoomMember chatRoomMember = iterator.next();
if (Objects.equals(chatRoomMember.getAccount(), account)) {
iterator.remove();
break;
}
}
}
public boolean isGuess() { public boolean isGuess() {
return !isRoomAdmin() && !isRoomOwner(); return !isRoomAdmin() && !isRoomOwner();
} }

View File

@@ -435,6 +435,9 @@ public class AvRoomModel extends RoomBaseModel implements IAvRoomModel {
if (chatRoomMember.getMemberType() == MemberType.CREATOR) { if (chatRoomMember.getMemberType() == MemberType.CREATOR) {
AvRoomDataManager.get().mRoomCreateMember = chatRoomMember; AvRoomDataManager.get().mRoomCreateMember = chatRoomMember;
} }
if (chatRoomMember.isInBlackList()) {
AvRoomDataManager.get().addBlackMember(chatRoomMember);
}
} }
AvRoomDataManager.get().mRoomFixedMemberList.addAll(chatRoomMemberList); AvRoomDataManager.get().mRoomFixedMemberList.addAll(chatRoomMemberList);
AvRoomDataManager.get().mRoomAllMemberList.addAll(chatRoomMemberList); AvRoomDataManager.get().mRoomAllMemberList.addAll(chatRoomMemberList);

View File

@@ -0,0 +1,16 @@
package com.yizhuan.xchat_android_core.skill.entity
data class SkillNotifyEntity(val layout: LayoutBean)
data class LayoutBean(
val title: ContentBean,
val time: ContentBean,
val contents: List<ContentBean>
)
data class ContentBean(
val content: String,
val fontSize: Int,
val fontColor: String,
val fontBold: Boolean
)

View File

@@ -1,5 +1,7 @@
package com.yizhuan.xchat_android_core.skill.entity package com.yizhuan.xchat_android_core.skill.entity
import com.google.gson.annotations.SerializedName
data class SkillRecordEntity( data class SkillRecordEntity(
val cardId: Int, val cardId: Int,
val createTime: String?, val createTime: String?,
@@ -9,7 +11,9 @@ data class SkillRecordEntity(
val pic: String, val pic: String,
val propRecordVo: List<PropRecordVoEntity>, val propRecordVo: List<PropRecordVoEntity>,
val type: Int,//技能卡类型 1游戏类 2才艺类 3声音秀 val type: Int,//技能卡类型 1游戏类 2才艺类 3声音秀
val updateTime: String? val updateTime: String?,
@SerializedName("status")
val audioStatus:Int//声音秀审核状态
) { ) {
@Transient @Transient
var isSelf = false//主态还是客态 var isSelf = false//主态还是客态