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(name: 'quicklogin_libary-external-release', ext: 'aar')
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 'io.github.yidun:quicklogin:3.1.5'
implementation 'com.github.fodroid:XRadioGroup:v1.5'
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 {
flatDir {
dirs 'aliyun-libs', 'quick-pass-libs', 'com.huawei.agconnect'
dirs 'aliyun-libs','com.huawei.agconnect'
}
mavenCentral()

View File

@@ -329,8 +329,11 @@
#一键登录
-dontwarn com.cmic.sso.sdk.**
-keep public class com.cmic.sso.sdk.**{*;}
-keep class cn.com.chinatelecom.account.api.**{*;}
-keep class com.cmic.sso.**{*;}
-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.listener.**{*;}
-keep class com.netease.nis.quicklogin.QuickLogin{
@@ -346,6 +349,11 @@
public <methods>;
public <fields>;
}
-keep class com.netease.nis.basesdk.**{
public *;
protected *;
}
-keep class com.bun.miitmdid.core.** {*;}
-keep class com.bun.** {*;}
-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.MsgViewHolderRedPackage;
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.SignInNoticeMsgViewHolder;
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.RedPackageAttachment;
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.SysMsgV2Attachment;
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(MatchAttachment.class, MsgViewHolderMatch.class);
//技能卡
NimUIKit.registerMsgItemViewHolder(SkillMsgAttachment.class, MsgViewHolderSkill.class);
//CP
NimUIKit.registerMsgItemViewHolder(CpInviteAttachment.class, MsgViewHolderText.class);
NimUIKit.setSessionListener(listener);

View File

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

View File

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

View File

@@ -3,6 +3,7 @@ package com.yizhuan.erban.avroom.presenter;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import com.yizhuan.erban.avroom.view.IRoomBlackView;
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_library.net.rxnet.callback.CallBack;
@@ -24,24 +25,6 @@ public class RoomBlackPresenter extends BaseMvpPresenter<IRoomBlackView> {
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")
public void queryManagerList(int limit) {
mRoomBaseModel.queryManagerList(limit)
Single.just(AvRoomDataManager.get().mRoomManagerList)
.observeOn(Schedulers.io())
.flatMap((Function<List<ChatRoomMember>, SingleSource<List<ChatRoomMember>>>) chatRoomMembers -> {
List<String> uids = new ArrayList<>();

View File

@@ -12,7 +12,8 @@ object SKillDataParser {
isSelf: Boolean,
isEdit: Boolean,
itemEventListener: ItemEventListener? = null,
item: PropRecordVoEntity
item: PropRecordVoEntity,
audioStatus: Int = 0
): ItemAttribute {
return ItemAttribute(
cardId,
@@ -20,8 +21,10 @@ object SKillDataParser {
item.state, item.isMust,
item.parentId, item.parentVal,
itemEventListener,
item.refPropVos.toMutableList()
)
item.refPropVos.toMutableList(),
).apply {
this.audioStatus = audioStatus
}
}
@@ -37,11 +40,13 @@ object SKillDataParser {
item.isEdit,
itemEventListener,
it
)
).apply {
audioStatus = item.audioStatus
}
list.add(element)
}
return SkillAttribute(
item.id, item.cardId,
item.id, item.type, item.cardId,
item.icon, item.name,
item.isSelf, item.isEdit,
item.pic, list
@@ -64,7 +69,7 @@ object SKillDataParser {
list.add(element)
}
return SkillAttribute(
-1, item.cardId,
-1, item.type, item.cardId,
item.icon, item.name,
item.isSelf, item.isEdit,
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.base.BaseBindingActivity
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.ui.widget.dialog.CommonTipDialog
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes
import org.greenrobot.eventbus.EventBus
@ActLayoutRes(R.layout.activity_skill_edit)
class EditSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
@@ -33,7 +31,7 @@ class EditSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
when (v.id) {
R.id.btn_delete -> showDeleteDialog()
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?.setOnActionListener(object : CommonTipDialog.OnActionListener {
override fun onOk() {
deleteSkill(mBinding.skillView.getAttributes().id)
mDelegate.deleteSkill()
deleteTipDialog?.dismiss()
}
@@ -63,22 +61,6 @@ class EditSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
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")
private fun loadData() {

View File

@@ -1,21 +1,12 @@
package com.yizhuan.erban.skill.activity
import android.annotation.SuppressLint
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseBindingActivity
import com.yizhuan.erban.databinding.ActivitySkillEditBinding
import com.yizhuan.erban.skill.SKillDataParser
import com.yizhuan.erban.skill.dialog.SkillSelectionDialog
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.skill.SkillDataDelegate
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.utils.toast
import org.greenrobot.eventbus.EventBus
import java.io.File
/**
* 编辑-添加 界面
@@ -53,45 +44,28 @@ class SkillEditableDelegate(
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()) }
item.invalidate()
}
selectionDialog.openDialog()
/**
* 保存 添加
*/
internal fun saveSkill() {
SkillDataDelegate(activity.mBinding.skillView, activity).saveSkill()
}
@SuppressLint("CheckResult")
internal fun saveSkill(binding: ActivitySkillEditBinding) {
if (!binding.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()
})
/**
* 删除
*/
internal fun deleteSkill() {
SkillDataDelegate(activity.mBinding.skillView, activity).deleteSkill(true)
}
/**
* 记录
*/
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)
activity.mBinding.skillView.initView(attr)
}
@@ -100,119 +74,15 @@ class SkillEditableDelegate(
* 初值属性
*/
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)
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 {
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.common.EmptyViewHelper
import com.yizhuan.erban.databinding.ActivitySkillHomeBinding
import com.yizhuan.erban.skill.SKillDataParser
import com.yizhuan.erban.skill.adapter.MineSkillCardAdapter
import com.yizhuan.erban.skill.decoration.SkillLinearVerticalDecoration
import com.yizhuan.erban.skill.dialog.AddSkillCardDialog
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.CARD_TYPE_AUDIO
import com.yizhuan.erban.skill.widget.SkillAttribute
import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes
import org.greenrobot.eventbus.EventBus
@@ -39,11 +42,13 @@ class SkillHomeActivity : BaseBindingActivity<ActivitySkillHomeBinding>() {
userId = intent.getLongExtra(USER_ID, 0)
EventBus.getDefault().register(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.addItemDecoration(SkillLinearVerticalDecoration(this, 6, 16))
adapter.setOnItemClickListener { _, _, position ->
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 {
EditSkillActivity.start(this, it.id)
}
@@ -54,6 +59,7 @@ class SkillHomeActivity : BaseBindingActivity<ActivitySkillHomeBinding>() {
mBinding.refreshLayout.setOnRefreshListener {
loadUserSkillList(userId)
}
mBinding.refreshLayout.isEnabled=false//禁用下拉刷新
loadUserSkillList(userId)
}
@@ -163,7 +169,8 @@ class SkillHomeActivity : BaseBindingActivity<ActivitySkillHomeBinding>() {
fun onDataChangedEvent(event: SkillEvent) {
loadUserSkillList(userId)
}
override fun needSteepStateBar()=true
override fun needSteepStateBar() = true
override fun setStatusBar() {
super.setStatusBar()
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.BaseViewHolder
import com.yizhuan.erban.R
import com.yizhuan.erban.base.BaseActivity
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.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) {
override fun convert(helper: BaseViewHolder, item: SkillRecordEntity) {
val itemView = helper.itemView as SkillCardView
item.isSelf = isSelf
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.yizhuan.erban.R
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) {
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) {
helper.setText(R.id.tv_item, item.propVal)
helper.setBackgroundRes(
@@ -19,15 +33,17 @@ class SkillSelectionAdapter(private val context: Context, private val itemState:
)
helper.setTextColor(
R.id.tv_item,
if (item.isSelected) context.resources.getColor(R.color.color_333333)
else Color.parseColor("#FFBC51")
if (item.isSelected) Color.parseColor("#FFBC51")
else context.resources.getColor(R.color.color_333333)
)
if (item.isSelected && !refreshByUser) {
selectedCount++
}
}
fun select(position: Int) {
refreshByUser = true
getItem(position)?.let {
it.isSelected = !it.isSelected
if (!it.isSelected) return@let
when (itemState) {
//0 单选 1 输入 2多选 3 音频 4 音频时长
0 -> singleSelect(it)
@@ -43,15 +59,44 @@ class SkillSelectionAdapter(private val context: Context, private val itemState:
private fun singleSelect(item: PropDictVo) {
data.forEach { it.isSelected = false }
selectedCount = 1
item.isSelected = true
}
private fun multiSelect(item: PropDictVo) {
item.isSelected = !item.isSelected
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 -> {
data.forEach { that -> that.isSelected = false }
item.isSelected = true
if (item.isSelected) {
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
binding.tvTitle.visibility = View.VISIBLE
binding.tvTitle.text = item?.propVal ?: ""
adapter = SkillSelectionAdapter(context, item?.state ?: 0)
adapter = SkillSelectionAdapter(context, item?.state ?: 0,item?.checkLimitNum?:-1)
adapter.setOnItemClickListener { _, _, position ->
adapter.select(position)
}

View File

@@ -7,17 +7,30 @@ data class ItemAttribute(
val cardId: Int,
val isSelf: 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 parentId: Int,
val parentVol: String,
val itemEventListener: ItemEventListener? = null,
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 {
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.view.LayoutInflater
import android.view.View
import com.netease.nim.uikit.common.util.sys.ScreenUtil
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.OnPlayListener
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 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,
TimerRecorderView.RecordListener {
TimerRecorderView.RecordListener, View.OnClickListener {
private lateinit var binding: LayoutSkillAudioBinding
private lateinit var context: Context
private var audioLength = 0
private var playState = PLAY_STATE_READY
private val cancelTipDialog by lazy {
//重新录制
private val reStartTipDialog by lazy {
CommonTipDialog(context).apply {
setTipMsg("确定要取消录制吗?")
setCancelText("取消")
setOkText("确定")
itemAttribute
setTipMsg(
if (itemAttribute.audioStatus == RECORD_STATE_JUDGE)
"您录制的声音正在审核中,确定要重新录制吗?"
else "确定要重新录制吗?"
)
setCancelText("")
setOkText("")
setBold(true)
setTextSize(ScreenUtil.dip2px(16f))
setOnActionListener(object : CommonTipDialog.OnActionListener {
override fun onCancel() {}
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 {
this.context = context
val inflater = LayoutInflater.from(context)
@@ -55,19 +79,11 @@ class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
private fun initItem() {
binding.recordView.recordListener = this
binding.recordView.recordDuration = MAX_RECORD_DURATION
binding.btnCancel.setOnClickListener {
if (cancelTipDialog.isShowing) {
cancelTipDialog.dismiss()
}
cancelTipDialog.show()
}
binding.tvSound.setOnClickListener {
if (playState == PLAY_STATE_READY) {
playAudio(itemAttribute.selectedProperties.getOrNull(0)?.propVal)
} else {
stopAudio()
}
}
binding.recordState = itemAttribute.audioStatus
itemAttribute.audioDuration?.let { binding.duration = it }
binding.btnCancel.text = if (itemAttribute.isSelf) "取消录制" else "取消重新录制"
binding.click = this
}
override fun invalidate() {}
@@ -81,16 +97,19 @@ class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
}
override fun onRecordStart(file: File?, recordType: RecordType?) {
binding.tvRecordTip.text="录音开始不少于3s喔"
binding.recordState = RECORD_STATE_RECORDING
}
override fun onRecordCancel() {
setItemByState(RECORD_STATE_READY)
//审核通过后 重新录制取消 要设置为之前审核通过的状态
binding.recordState = itemAttribute.audioStatus
}
override fun onRecordSuccess(file: File?) {
if (cancelTipDialog.isShowing) {
cancelTipDialog.dismiss()
if (audioLength < 3) {
"录制时间不能少于3s哦".toast()
binding.recordState = RECORD_STATE_READY
return
}
itemAttribute.itemEventListener?.onRecordSuccess(file, audioLength)
}
@@ -105,40 +124,18 @@ class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
* 根据状态设置View
*/
fun setItemByState(state: Int) {
when (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 -> {
}
}
binding.recordState = state
}
private fun playAudio(url: String?) {
if (playState == PLAY_STATE_PLAYING || TextUtils.isEmptyText(url)) return
playState = PLAY_STATE_PLAYING
setItemByState(PLAY_STATE_PLAYING)
binding.palyState = playState
AudioPlayerHelper.get().playInThread(url, object : OnPlayListener {
override fun onError(error: String?) {
"播放出错,请重试".toast()
playState = PLAY_STATE_READY
setItemByState(PLAY_STATE_READY)
binding.palyState = playState
}
override fun onPrepared() {}
@@ -147,7 +144,7 @@ class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
override fun onCompletion() {
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
AudioPlayerHelper.get().endPlay()
playState = PLAY_STATE_READY
//更改状态
setItemByState(PLAY_STATE_READY)
binding.palyState = playState
}
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
const val CARD_TYPE_GAME = 1
const val CARD_TYPE_ART = 2
const val CARD_TYPE_AUDIO = 3
data class SkillAttribute(
val id: Int,
val type: Int,
val cardId: Int,
val skillRes: String?,
val skillName: String,

View File

@@ -96,6 +96,8 @@ class SkillCardView(
attr.itemAttributes.forEach {
this.itemList.add(createItemView(it))
}
//暂时处理
SkillItemHelper.wrapAudio(attr)
setBackgroundImg(attr.background)
removeAllViews()
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.widget.EditText
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 {
/**
@@ -45,4 +47,12 @@ object SkillItemHelper {
contentView.isFocusable = 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 {
private var progressWidth = 0
private var outerWidth = 0
private var progressColor = 0
private val progressPaint by lazy {
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) {
val array = context.obtainStyledAttributes(attrs, R.styleable.TimerRecorderView)
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.strokeWidth = progressWidth.toFloat()
progressPaint.color = progressColor
array.recycle()
setOnClickListener {
when (state) {
@@ -59,29 +64,19 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
val dimens = width.coerceAtLeast(height) + progressWidth * 2
setMeasuredDimension(dimens, dimens)
setMeasuredDimension(width, height)
}
override fun onDraw(canvas: 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) {
progressPaint.color = Color.BLUE
val rectF = RectF()
val swipe = animatedPercent * 360
rectF.left = progressWidth.toFloat()
rectF.top = progressWidth.toFloat()
rectF.right = measuredWidth.toFloat() - progressWidth
rectF.bottom = measuredHeight.toFloat() - progressWidth
rectF.left = outerWidth.toFloat()
rectF.top = outerWidth.toFloat()
rectF.right = measuredWidth.toFloat() - outerWidth
rectF.bottom = measuredHeight.toFloat() - outerWidth
canvas.drawArc(rectF, -90f, swipe, false, progressPaint)
}
}
@@ -97,6 +92,7 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
options.audioRecordMaxTime, this
)
}
setImageResource(R.drawable.ic_skill_audio_recording)
audioMessageHelper!!.startRecord()
}
@@ -108,6 +104,7 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
fun endAudioRecord(cancel: Boolean) {
state = STATE_PAUSED
audioMessageHelper?.completeRecord(cancel)
setImageResource(R.drawable.ic_skill_audio_ready)
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 com.netease.nim.uikit.support.glide.GlideApp
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.databinding.FragmentUserinfoUserinfoBinding
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.decorationsend.UserInfoSkillDecoration
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.xchat_android_core.auth.AuthModel
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.utils.net.BeanObserver
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
@@ -50,6 +54,7 @@ class UserInfoInfoFragment : BaseViewBindingFragment<FragmentUserinfoUserinfoBin
private var giftAdapter: GiftAdapter? = null
private var skillAdapter: SkillCardAdapter? = null
private val vm: UserInfoViewModel by activityViewModels()
private var audioPlaying = false
@SuppressLint("SetTextI18n")
private fun initClanAndHall(clanAndHallInfo: ClanAndHallInfo) {
@@ -140,6 +145,22 @@ class UserInfoInfoFragment : BaseViewBindingFragment<FragmentUserinfoUserinfoBin
* 技能卡
*/
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) {
skillAdapter = SkillCardAdapter(mContext)
skillAdapter?.setHeaderAndEmpty(true)
@@ -153,12 +174,10 @@ class UserInfoInfoFragment : BaseViewBindingFragment<FragmentUserinfoUserinfoBin
LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false)
binding.recyclerSkill.adapter = skillAdapter
}
if (list.isEmpty()) {
skillAdapter?.setNewData(ArrayList(0))
if (newList.isEmpty()) {
skillAdapter?.emptyView = createSkillEmptyView()
} else {
skillAdapter?.setNewData(list)
}
skillAdapter?.setNewData(newList)
}
override fun onClick(v: View) {
@@ -216,4 +235,42 @@ class UserInfoInfoFragment : BaseViewBindingFragment<FragmentUserinfoUserinfoBin
}
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 int drawableId;
private int dpWidth = 0;
private int dpHeight = 0;
public LivingIconView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
int dp_9 = UIUtil.dip2px(context, 9);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LivingIconView);
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();
init(context);
}
private void init(Context context){
private void init(Context context) {
drawable = (AnimationDrawable) context.getResources().getDrawable(drawableId);
drawable.setOneShot(false);
setScaleType(ScaleType.FIT_CENTER);
setImageDrawable(drawable);
int dp_9 = UIUtil.dip2px(context, 9);
setLayoutParams(new ViewGroup.LayoutParams(dp_9, dp_9));
setLayoutParams(new ViewGroup.LayoutParams(dpWidth, dpHeight));
}
public void setColor(int color) {

View File

@@ -1,10 +1,17 @@
package com.yizhuan.erban.ui.widget.dialog;
import static android.graphics.Typeface.BOLD;
import android.content.Context;
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 androidx.annotation.ColorRes;
import com.yizhuan.erban.R;
import com.yizhuan.xchat_android_core.utils.TextUtils;
@@ -18,6 +25,10 @@ public class CommonTipDialog extends BaseDialog {
private String okText = "确定";
private String cancelText = "取消";
private boolean isBold;
private @ColorRes
int color = -1;
private int textSize = -1;
public CommonTipDialog(Context context) {
super(context, R.style.dialog);
@@ -36,7 +47,19 @@ public class CommonTipDialog extends BaseDialog {
TextView tip = findViewById(R.id.message);
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);
ok.setText(okText);
ok.setOnClickListener(v -> {
@@ -59,6 +82,18 @@ public class CommonTipDialog extends BaseDialog {
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;
public void setOkText(String okText) {

View File

@@ -2,20 +2,12 @@ package com.yizhuan.erban.vip
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.sdk.mobile.manager.login.views.Loading
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.utils.net.ServerException
import com.yizhuan.xchat_android_core.utils.toast
import com.yizhuan.xchat_android_core.vip.VipAuthInfo
import com.yizhuan.xchat_android_core.vip.VipInfo
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() {

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"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFBC51" />
<solid android:color="#1AFFBC51" />
<corners android:radius="@dimen/dp_8" />
</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_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
android:layout_width="match_parent"
android:layout_height="match_parent">

View File

@@ -11,19 +11,6 @@
android:layout_width="match_parent"
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
android:layout_width="match_parent"
android:layout_height="match_parent">

View File

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

View File

@@ -281,6 +281,52 @@
android:textColor="@color/color_333333"
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
android:id="@+id/recycler_skill"
android:layout_width="match_parent"
@@ -297,8 +343,8 @@
android:background="@drawable/bg_secondary_radius_10"
android:orientation="vertical"
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
android:id="@+id/tv_gift_detail"
@@ -314,8 +360,8 @@
android:id="@+id/rv_gift"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/dp_14"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/dp_14"
android:layout_marginBottom="@dimen/dp_15"
android:clipToPadding="false"
android:paddingStart="2dp"

View File

@@ -3,11 +3,11 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="142dp"
android:paddingTop="@dimen/dp_8"
android:paddingBottom="@dimen/dp_8"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/dp_5"
android:paddingTop="@dimen/dp_8"
android:paddingRight="@dimen/dp_5"
android:layout_height="wrap_content">
android:paddingBottom="@dimen/dp_8">
<ImageView
android:id="@+id/iv_icon"
@@ -30,15 +30,19 @@
<TextView
android:id="@+id/tv_desc"
android:layout_width="wrap_content"
android:layout_width="0dp"
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:textSize="@dimen/sp_12"
android:fontFamily="sans-serif"
app:layout_constraintStart_toStartOf="@id/tv_title"
app:layout_constraintLeft_toLeftOf="@id/tv_title"
app:layout_constraintTop_toBottomOf="@id/tv_title"
android:layout_marginTop="@dimen/dp_5"
tools:text="英雄联盟手游" />
app:layout_constraintRight_toRightOf="parent"
tools:text="盟手游英雄联盟手游" />
</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"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="295dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@drawable/shape_white_20dp_round"
android:paddingBottom="@dimen/dp_24"
tools:background="@color/white_tran_10">
android:orientation="vertical"
tools:background="@color/black_transparent_10">
<View
android:id="@+id/space_view"
android:layout_width="0dp"
android:layout_height="@dimen/dp_26"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:layout_height="@dimen/dp_26" />
<TextView
android:id="@+id/message"
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:lineSpacingMultiplier="1.2"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:textColor="@color/color_333333"
android:textSize="14sp"
app:layout_constraintTop_toBottomOf="@id/space_view"
tools:text="购买成功是否立即驾驶sd水电费水电费sfasdfasdfasdfasdfasdf" />
<TextView
android:id="@+id/sub_message"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_8"
android:gravity="center"
android:paddingStart="31dp"
android:paddingEnd="31dp"
android:textColor="@color/color_999999"
android:textSize="13sp"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/message"
tools:text="购买成功是否立即驾驶sd水电费水电费sfasdfasdfasdfasdfasdf" />
android:layout_marginBottom="24dp"
android:gravity="center_horizontal"
android:orientation="horizontal">
<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
android:id="@+id/content_barrier"
android:layout_width="0dp"
android:layout_height="0dp"
app:barrierDirection="bottom"
app:constraint_referenced_ids="message,sub_message" />
<TextView
android:id="@+id/btn_cancel"
android:layout_width="120dp"
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>
<TextView
android:id="@+id/btn_ok"
android:layout_width="120dp"
android:layout_height="38dp"
android:background="@drawable/bg_common_confirm"
android:gravity="center"
android:text="@string/text_ok"
android:textColor="@color/white"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>

View File

@@ -1,6 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
@@ -11,102 +37,128 @@
<com.yizhuan.erban.skill.widget.TimerRecorderView
android:id="@+id/record_view"
android:layout_width="@dimen/dp_60"
android:layout_height="@dimen/dp_60"
android:layout_width="167dp"
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_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:src="@drawable/icon_music_pause"
app:progressWidth="@dimen/dp_5" />
app:outerWidth="@dimen/dp_20"
app:progressColor="#5C8AFF"
app:progressWidth="@dimen/dp_10" />
<TextView
android:id="@+id/tv_record_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/record_view"
android:text="点击录制语音15S展示才艺技能" />
app:layout_constraintTop_toBottomOf="@id/record_view" />
<Button
android:id="@+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_width="144dp"
android:layout_height="40dp"
android:layout_marginTop="@dimen/dp_10"
android:background="@drawable/bg_ffce4e_trans30_20dp"
android:onClick="@{click}"
android:paddingLeft="@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_constraintStart_toStartOf="parent"
android:textSize="@dimen/sp_14"
app:layout_constraintTop_toBottomOf="@id/tv_record_tip"
tools:text="取消录制" />
android:text="取消重新录制" />
<!--录制完成 审核中-->
<TextView
android:id="@+id/tv_sound"
android:layout_width="200dp"
android:layout_height="@dimen/dp_40"
android:background="#66000000"
android:drawableLeft="@drawable/icon_music_pause"
android:drawablePadding="@dimen/dp_10"
android:layout_width="150dp"
android:layout_height="@dimen/dp_30"
android:layout_marginBottom="@dimen/dp_20"
android:background="@drawable/bg_skill_record_sound"
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_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="@{@string/skill_audio_duration(duration)}"
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
android:id="@+id/tv_duration"
android:id="@+id/tv_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_20"
android:layout_marginLeft="@dimen/dp_5"
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_constraintStart_toEndOf="@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
android:id="@+id/btn_delete"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginTop="@dimen/dp_20"
android:paddingLeft="@dimen/dp_20"
android:paddingRight="@dimen/dp_20"
android:visibility="gone"
android:layout_width="64dp"
android:layout_height="20dp"
android:layout_marginBottom="@dimen/dp_27"
android:onClick="@{click}"
android:background="@drawable/bg_ffce4e_trans30_20dp"
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_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_record_tip"
tools:text="删除声音" />
android:textSize="@dimen/sp_10"
android:text="删除声音" />
<Button
android:id="@+id/btn_restart"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_width="64dp"
android:layout_height="20dp"
android:layout_marginLeft="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_20"
android:paddingLeft="@dimen/dp_20"
android:paddingRight="@dimen/dp_20"
android:layout_marginBottom="@dimen/dp_27"
android:onClick="@{click}"
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_constraintStart_toEndOf="@id/btn_delete"
app:layout_constraintTop_toBottomOf="@id/tv_record_tip"
app:layout_goneMarginLeft="0dp"
tools:text="重新录制" />
android:textColor="@color/white"
android:textSize="@dimen/sp_10"
android:text="重新录制" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_ready"
<androidx.constraintlayout.widget.Barrier
android:id="@+id/bottom_button_barrier"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="record_view,tv_record_tip,btn_cancel" />
<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" />
app:barrierDirection="top"
app:constraint_referenced_ids="btn_restart,btn_delete" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

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

View File

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

View File

@@ -3,5 +3,6 @@
<integer name="tab_anim_duration">15</integer>
<integer name="loading_anim_duration">70</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>
</resources>

View File

@@ -916,6 +916,12 @@
<string name="delete_skill">删除技能卡</string>
<string name="tip_save_skill">您填写的技能卡未保存,是否直接返\n回上一页</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-->
<string name="cp_empty_text">&#160;</string>

View File

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

View File

@@ -1,5 +1,6 @@
package com.yizhuan.xchat_android_core.manager;
import android.annotation.SuppressLint;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
@@ -718,6 +719,10 @@ public final class IMNetEaseManager {
} else if (attachment.getType() == NotificationType.ChatRoomMemberBlackAdd) {
List<String> targets = ((ChatRoomNotificationAttachment) attachment).getTargets();
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) {
// 房间内的某人的贵族信息更新了
Map<String, Object> extension = null;
@@ -2118,6 +2123,23 @@ public final class IMNetEaseManager {
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:
attachment = new RequestUpmicAttachment(CustomAttachment.ANCHOR_ROOM_AUDIENCE_UPMIC, 0);
break;
case CustomAttachment.SKILL_MSG_AUDIO:
attachment = new SkillMsgAttachment(second);
break;
case CustomAttachment.CP_INVITE_MESSAGE:
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
*/
public class CustomAttachment implements MsgAttachment {
/**
* 自定义消息附件的类型,根据该字段区分不同的自定义消息
*/
/** 自定义消息附件的类型,根据该字段区分不同的自定义消息 */
protected int first;
protected int second;
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_MSG_HEADER_TYPE_GOOD_NUMBER_INACTIVE = 147;
/**
* 贵族快到期(前三天)消息
*/
/** 贵族快到期(前三天)消息 */
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_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_COMMON_MSG = 191;
// 房间信息更新
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_AUDIO = 202;
public static final int CUSTOM_MSG_UPDATE_ROOM_INFO_CLOSE_SCREEN = 203;
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_AUDIO=202;
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_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;
@@ -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_LEVEL_UP = 24;
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_EXPER_LEVEL_UP_NOTICE = 243;
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_CHARM_LEVEL_UP=242;
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_START = 251;
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_RUNAWAY = 254;
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_END=252;
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_BOX = 26;
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_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_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_FREE_MIC_OPEN = 305; // 将坑位设置成自由麦
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 SKILL_MSG_AUDIO = 87;
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() {
return !isRoomAdmin() && !isRoomOwner();
}

View File

@@ -435,6 +435,9 @@ public class AvRoomModel extends RoomBaseModel implements IAvRoomModel {
if (chatRoomMember.getMemberType() == MemberType.CREATOR) {
AvRoomDataManager.get().mRoomCreateMember = chatRoomMember;
}
if (chatRoomMember.isInBlackList()) {
AvRoomDataManager.get().addBlackMember(chatRoomMember);
}
}
AvRoomDataManager.get().mRoomFixedMemberList.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
import com.google.gson.annotations.SerializedName
data class SkillRecordEntity(
val cardId: Int,
val createTime: String?,
@@ -9,7 +11,9 @@ data class SkillRecordEntity(
val pic: String,
val propRecordVo: List<PropRecordVoEntity>,
val type: Int,//技能卡类型 1游戏类 2才艺类 3声音秀
val updateTime: String?
val updateTime: String?,
@SerializedName("status")
val audioStatus:Int//声音秀审核状态
) {
@Transient
var isSelf = false//主态还是客态