技能卡多选 增加声音秀
@@ -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;
|
||||
@@ -147,6 +148,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;
|
||||
@@ -414,6 +416,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);
|
||||
NimUIKit.setSessionListener(listener);
|
||||
NimUIKit.setContactEventListener(listener1);
|
||||
}
|
||||
|
103
app/src/main/java/com/yizhuan/erban/skill/SKillDataParser.kt
Normal file
@@ -0,0 +1,103 @@
|
||||
package com.yizhuan.erban.skill
|
||||
|
||||
import com.yizhuan.erban.skill.widget.ItemAttribute
|
||||
import com.yizhuan.erban.skill.widget.ItemEventListener
|
||||
import com.yizhuan.erban.skill.widget.SkillAttribute
|
||||
import com.yizhuan.erban.skill.widget.SkillItem
|
||||
import com.yizhuan.xchat_android_core.skill.entity.*
|
||||
|
||||
object SKillDataParser {
|
||||
private fun parseItemRecordToAttribute(
|
||||
cardId: Int,
|
||||
isSelf: Boolean,
|
||||
isEdit: Boolean,
|
||||
itemEventListener: ItemEventListener? = null,
|
||||
item: PropRecordVoEntity,
|
||||
audioStatus: Int = 0
|
||||
): ItemAttribute {
|
||||
return ItemAttribute(
|
||||
cardId,
|
||||
isSelf, isEdit,
|
||||
item.state, item.isMust,
|
||||
item.parentId, item.parentVal,
|
||||
itemEventListener,
|
||||
item.refPropVos.toMutableList(),
|
||||
).apply {
|
||||
this.audioStatus = audioStatus
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun parseSkillRecordToAttribute(
|
||||
item: SkillRecordEntity,
|
||||
itemEventListener: ItemEventListener? = null,
|
||||
): SkillAttribute {
|
||||
val list: MutableList<ItemAttribute> = ArrayList()
|
||||
item.propRecordVo.forEach {
|
||||
val element = parseItemRecordToAttribute(
|
||||
item.cardId,
|
||||
item.isSelf,
|
||||
item.isEdit,
|
||||
itemEventListener,
|
||||
it
|
||||
).apply {
|
||||
audioStatus = item.audioStatus
|
||||
}
|
||||
list.add(element)
|
||||
}
|
||||
return SkillAttribute(
|
||||
item.id, item.type, item.cardId,
|
||||
item.icon, item.name,
|
||||
item.isSelf, item.isEdit,
|
||||
item.pic, list
|
||||
)
|
||||
}
|
||||
|
||||
fun parseSkillPropertyToAttribute(
|
||||
item: SkillPropertyEntity,
|
||||
itemEventListener: ItemEventListener? = null,
|
||||
): SkillAttribute {
|
||||
val list: MutableList<ItemAttribute> = ArrayList()
|
||||
item.props.forEach {
|
||||
val element = parseItemRecordToAttribute(
|
||||
item.cardId,
|
||||
item.isSelf,
|
||||
item.isEdit,
|
||||
itemEventListener,
|
||||
it.parsePropToRecord()
|
||||
)
|
||||
list.add(element)
|
||||
}
|
||||
return SkillAttribute(
|
||||
-1, item.type, item.cardId,
|
||||
item.icon, item.name,
|
||||
item.isSelf, item.isEdit,
|
||||
item.pic, list
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成服务器数据
|
||||
*/
|
||||
fun parseSkillSelectedValue(
|
||||
recordId: Int,
|
||||
cardId: Int,
|
||||
itemList: List<SkillItem>
|
||||
): SkillPostServerEntity {
|
||||
return if (itemList.isEmpty()) {
|
||||
SkillPostServerEntity(propRecordVo = ArrayList(0))
|
||||
} else {
|
||||
val list = ArrayList<SKillValueEntity>()
|
||||
itemList.forEach {
|
||||
val item = it.getContentEntity()
|
||||
list.add(
|
||||
SKillValueEntity(
|
||||
item.parentId,
|
||||
it.getContentEntity().selectedProperties
|
||||
)
|
||||
)
|
||||
}
|
||||
SkillPostServerEntity(recordId, cardId, list)
|
||||
}
|
||||
}
|
||||
}
|
201
app/src/main/java/com/yizhuan/erban/skill/SkillDataDelegate.kt
Normal 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)
|
||||
})
|
||||
}
|
||||
}
|
@@ -1,5 +1,6 @@
|
||||
package com.yizhuan.erban.skill.activity
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -8,22 +9,23 @@ 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.entity.PropRecordVoEntity
|
||||
import com.yizhuan.xchat_android_core.skill.entity.SkillPropertyEntity
|
||||
import com.yizhuan.xchat_android_core.skill.entity.SkillRecordEntity
|
||||
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.xchat_android_library.annatation.ActLayoutRes
|
||||
|
||||
@ActLayoutRes(R.layout.activity_skill_edit)
|
||||
class AddSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
|
||||
private lateinit var delegate: SkillEditableDelegate
|
||||
private var cardId = -1
|
||||
private var cardType = -1
|
||||
override fun init() {
|
||||
delegate = SkillEditableDelegate(this)
|
||||
initTitleBar("添加技能")
|
||||
mBinding.click = this
|
||||
mBinding.btnDelete.visibility = View.GONE
|
||||
val cardId = intent?.getIntExtra(ITEM, -1) ?: -1
|
||||
cardId = intent?.getIntExtra(CARD_ID, cardId) ?: cardId
|
||||
if (cardId > 0) {
|
||||
queryCardInfo(cardId)
|
||||
}
|
||||
@@ -33,34 +35,52 @@ class AddSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
|
||||
private fun queryCardInfo(cardId: Int) {
|
||||
val propertyEntity = SkillDataManager.get().getPropertyEntity(cardId)
|
||||
if (propertyEntity != null) {
|
||||
if (propertyEntity.type == CARD_TYPE_AUDIO) {
|
||||
dealAudioView(propertyEntity)
|
||||
}
|
||||
setSkillViewData(propertyEntity)
|
||||
} else {
|
||||
SkillModel.instance.getCardInfoById(cardId)
|
||||
.compose(bindToLifecycle())
|
||||
.subscribe( {
|
||||
.subscribe({
|
||||
SkillDataManager.get().setSkillPropertyEntity(cardId, it)
|
||||
setSkillViewData(it)
|
||||
}, { th -> th.printStackTrace()
|
||||
when (it.type) {
|
||||
CARD_TYPE_AUDIO -> dealAudioView(it)
|
||||
else -> setSkillViewData(it)
|
||||
}
|
||||
}, { th ->
|
||||
th.printStackTrace()
|
||||
toast(th.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun dealAudioView(propertyEntity: SkillPropertyEntity) {
|
||||
checkPermissionAndDeal(propertyEntity)
|
||||
mBinding.btnSave.visibility = View.GONE
|
||||
cardType = propertyEntity.type
|
||||
}
|
||||
|
||||
private fun setSkillViewData(it: SkillPropertyEntity) {
|
||||
//转换
|
||||
val propList = ArrayList<PropRecordVoEntity>()
|
||||
it.props.forEach { prop ->
|
||||
propList.add(
|
||||
PropRecordVoEntity(
|
||||
prop.id, prop.propVal, -1, null, prop.state, prop.isMust
|
||||
)
|
||||
)
|
||||
}
|
||||
val entity = SkillRecordEntity(
|
||||
it.cardId, null, it.icon, -1, it.name,
|
||||
it.pic, propList, it.type, null
|
||||
it.isSelf = true
|
||||
it.isEdit = true
|
||||
delegate.setSkillViewData(it)
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun checkPermissionAndDeal(it: SkillPropertyEntity) {
|
||||
checkPermission(
|
||||
Manifest.permission.RECORD_AUDIO,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)
|
||||
delegate.setSkillViewData(isSelf = true, isEdit = true, entity = entity)
|
||||
.subscribe { aBoolean: Boolean ->
|
||||
if (aBoolean) {
|
||||
setSkillViewData(it)
|
||||
} else {
|
||||
toast("请给予应用必要权限,让程序可正常工作。")
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,28 +88,31 @@ class AddSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
|
||||
delegate.onLeftClick()
|
||||
}
|
||||
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
super.onClick(v)
|
||||
when (v?.id) {
|
||||
R.id.btn_save -> delegate.saveSkill(mBinding)
|
||||
R.id.btn_save -> delegate.saveSkill()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val ITEM = "item"
|
||||
fun start(context: Context, type: Int) {
|
||||
private const val CARD_ID = "card_id"
|
||||
fun start(context: Context, cardId: Int) {
|
||||
val intent = Intent(context, AddSkillActivity::class.java)
|
||||
intent.putExtra(ITEM, type)
|
||||
intent.putExtra(CARD_ID, cardId)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (cardType == CARD_TYPE_AUDIO) {
|
||||
super.onBackPressed()
|
||||
return
|
||||
}
|
||||
delegate.onLeftClick()
|
||||
}
|
||||
|
||||
override fun needSteepStateBar()=true
|
||||
override fun needSteepStateBar() = true
|
||||
override fun setStatusBar() {
|
||||
super.setStatusBar()
|
||||
StatusBarUtil.transparencyBar(this)
|
||||
|
@@ -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.getSavedValues().id)
|
||||
mDelegate.deleteSkill()
|
||||
deleteTipDialog?.dismiss()
|
||||
}
|
||||
|
||||
@@ -63,32 +61,18 @@ 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() {
|
||||
SkillModel.instance.getSkillDetailById(recordId)
|
||||
.compose(bindToLifecycle())
|
||||
.doOnSubscribe { dialogManager.showProgressDialog(this) }
|
||||
.subscribe( {
|
||||
mDelegate.setSkillViewData(isSelf = true, isEdit = true, entity = it)
|
||||
.subscribe({
|
||||
it.isSelf = true
|
||||
it.isEdit = true
|
||||
mDelegate.setSkillViewData(it)
|
||||
dialogManager.dismissDialog()
|
||||
}, { th ->
|
||||
}, { th ->
|
||||
th.printStackTrace()
|
||||
toast(th.message)
|
||||
dialogManager.dismissDialog()
|
||||
@@ -107,7 +91,8 @@ class EditSkillActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
|
||||
override fun onBackPressed() {
|
||||
mDelegate.onLeftClick()
|
||||
}
|
||||
override fun needSteepStateBar()=true
|
||||
|
||||
override fun needSteepStateBar() = true
|
||||
override fun setStatusBar() {
|
||||
super.setStatusBar()
|
||||
StatusBarUtil.transparencyBar(this)
|
||||
|
@@ -34,10 +34,12 @@ class SkillDetailActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
|
||||
SkillModel.instance.getSkillDetailById(recordId)
|
||||
.compose(bindToLifecycle())
|
||||
.doOnSubscribe { dialogManager.showProgressDialog(this) }
|
||||
.subscribe( {
|
||||
mDelegate.setSkillViewData(isSelf = false, isEdit = false, entity = it)
|
||||
.subscribe({
|
||||
it.isSelf = false
|
||||
it.isEdit = false
|
||||
mDelegate.setSkillViewData(it)
|
||||
dialogManager.dismissDialog()
|
||||
}, { th ->
|
||||
}, { th ->
|
||||
th.printStackTrace()
|
||||
toast(th.message)
|
||||
dialogManager.dismissDialog()
|
||||
@@ -52,7 +54,8 @@ class SkillDetailActivity : BaseBindingActivity<ActivitySkillEditBinding>() {
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
override fun needSteepStateBar()=true
|
||||
|
||||
override fun needSteepStateBar() = true
|
||||
override fun setStatusBar() {
|
||||
super.setStatusBar()
|
||||
StatusBarUtil.transparencyBar(this)
|
||||
|
@@ -1,20 +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.dialog.SkillSelectionDialog
|
||||
import com.yizhuan.xchat_android_core.skill.entity.PropsEntity
|
||||
import com.yizhuan.xchat_android_core.skill.entity.SkillPropertyEntity
|
||||
import com.yizhuan.xchat_android_core.skill.entity.SkillRecordEntity
|
||||
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.SelectionItem
|
||||
import com.yizhuan.erban.skill.widget.SkillItem
|
||||
import com.yizhuan.erban.skill.SKillDataParser
|
||||
import com.yizhuan.erban.skill.SkillDataDelegate
|
||||
import com.yizhuan.erban.ui.widget.dialog.CommonTipDialog
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import com.yizhuan.xchat_android_core.skill.entity.*
|
||||
|
||||
/**
|
||||
* 编辑-添加 界面
|
||||
@@ -52,78 +44,42 @@ class SkillEditableDelegate(
|
||||
saveTipDialog.show()
|
||||
}
|
||||
|
||||
private fun showSelectionValueDialog(item: SkillItem, propertyEntity: PropsEntity?) {
|
||||
val selectionDialog = SkillSelectionDialog(activity, propertyEntity) {
|
||||
item.getContentEntity().propId = it.id
|
||||
item.getContentEntity().propVal = it.propVal
|
||||
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 = binding.skillView.getSavedValues()
|
||||
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(isSelf: Boolean, isEdit: Boolean, entity: SkillRecordEntity) {
|
||||
entity.isSelf = isSelf
|
||||
entity.isEdit = isEdit
|
||||
val listener = if (isSelf && isEdit) DefaultItemSelectionListenerImp(entity) else null
|
||||
activity.mBinding.skillView.setItems(entity, listener)
|
||||
/**
|
||||
* 记录
|
||||
*/
|
||||
internal fun setSkillViewData(entity: SkillRecordEntity) {
|
||||
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)
|
||||
}
|
||||
|
||||
private fun setSelectionData(item: SkillItem, propertyEntity: SkillPropertyEntity?) {
|
||||
val props = propertyEntity?.props
|
||||
val propDictVos = props?.find {
|
||||
it.id == item.getContentEntity().parentId
|
||||
}
|
||||
showSelectionValueDialog(item, propDictVos)
|
||||
}
|
||||
|
||||
inner class DefaultItemSelectionListenerImp(private val entity: SkillRecordEntity) :
|
||||
SelectionItem.OnItemSelectionListener {
|
||||
@SuppressLint("CheckResult")
|
||||
override fun onItemSelection(item: SkillItem) {
|
||||
val propertyEntity = SkillDataManager.get().getPropertyEntity(entity.cardId)
|
||||
if (propertyEntity == null) {
|
||||
SkillModel.instance.getCardInfoById(entity.cardId)
|
||||
.compose(activity.bindToLifecycle())
|
||||
.doOnSubscribe { activity.dialogManager.showProgressDialog(activity) }
|
||||
.subscribe( {
|
||||
SkillDataManager.get().setSkillPropertyEntity(entity.cardId, it)
|
||||
setSelectionData(item, it)
|
||||
activity.dialogManager.dismissDialog()
|
||||
}, { th ->
|
||||
th.printStackTrace()
|
||||
activity.toast(th.message)
|
||||
setSelectionData(item, null)
|
||||
activity.dialogManager.dismissDialog()
|
||||
})
|
||||
} else {
|
||||
setSelectionData(item, propertyEntity)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 初值属性
|
||||
*/
|
||||
internal fun setSkillViewData(entity: SkillPropertyEntity) {
|
||||
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)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@@ -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)
|
||||
|
@@ -3,18 +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.setItems(item, null)
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -5,30 +5,99 @@ import android.graphics.Color
|
||||
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.PropDictVosEntity
|
||||
import com.yizhuan.xchat_android_core.skill.entity.PropDictVo
|
||||
import com.yizhuan.xchat_android_core.utils.toast
|
||||
|
||||
|
||||
class SkillSelectionAdapter(private val context: Context) :
|
||||
BaseQuickAdapter<PropDictVosEntity, BaseViewHolder>(R.layout.item_skill_selection) {
|
||||
private var selectedPosition = -1
|
||||
override fun convert(helper: BaseViewHolder, item: PropDictVosEntity) {
|
||||
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)
|
||||
val position = helper.adapterPosition
|
||||
helper.setBackgroundRes(
|
||||
R.id.tv_item,
|
||||
if (selectedPosition == position) R.drawable.bg_round_ffbc51_8
|
||||
if (item.isSelected) R.drawable.bg_round_ffbc51_8
|
||||
else R.drawable.bg_f1f1fa_8
|
||||
)
|
||||
helper.setTextColor(
|
||||
R.id.tv_item,
|
||||
if (selectedPosition == position) 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) {
|
||||
if (position == selectedPosition) return
|
||||
selectedPosition = position
|
||||
refreshByUser = true
|
||||
getItem(position)?.let {
|
||||
when (itemState) {
|
||||
//0 单选 1 输入 2多选 3 音频 4 音频时长
|
||||
0 -> singleSelect(it)
|
||||
2 -> multiSelect(it)
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun getSelectedItems(): List<PropDictVo> {
|
||||
return data.filter { it.isSelected }
|
||||
}
|
||||
|
||||
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 -> {
|
||||
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 -> {
|
||||
if (item.isSelected) {
|
||||
data.forEach { that -> that.isSelected = false }
|
||||
item.isSelected = true
|
||||
selectedCount = 1
|
||||
} else {
|
||||
selectedCount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@ package com.yizhuan.erban.skill.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.yizhuan.erban.R
|
||||
import com.yizhuan.erban.databinding.DialogAddSkillItemBinding
|
||||
@@ -30,6 +31,7 @@ class AddSkillCardDialog(
|
||||
|
||||
private lateinit var adapter: AddSkillCardAdapter
|
||||
override fun init() {
|
||||
binding.btnEnsure.visibility = View.GONE
|
||||
binding.recyclerView.layoutManager = GridLayoutManager(context, 2)
|
||||
binding.recyclerView.addItemDecoration(SkillGridDecoration(context, 26, 15))
|
||||
adapter = AddSkillCardAdapter()
|
||||
|
@@ -8,16 +8,16 @@ import com.yizhuan.erban.R
|
||||
import com.yizhuan.erban.databinding.DialogAddSkillItemBinding
|
||||
import com.yizhuan.erban.skill.adapter.SkillSelectionAdapter
|
||||
import com.yizhuan.erban.skill.decoration.SkillGridDecoration
|
||||
import com.yizhuan.xchat_android_core.skill.entity.PropDictVosEntity
|
||||
import com.yizhuan.xchat_android_core.skill.entity.PropsEntity
|
||||
import com.yizhuan.erban.treasure_box.widget.dialog.BaseBindingDialog
|
||||
import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil
|
||||
import com.yizhuan.xchat_android_core.skill.entity.PropDictVo
|
||||
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes
|
||||
|
||||
@ActLayoutRes(R.layout.dialog_add_skill_item)
|
||||
class SkillSelectionDialog(
|
||||
context: Context, var item: PropsEntity?,
|
||||
val callback: (value: PropDictVosEntity) -> Unit
|
||||
val callback: (value: List<PropDictVo>) -> Unit
|
||||
) :
|
||||
BaseBindingDialog<DialogAddSkillItemBinding>(context) {
|
||||
private lateinit var adapter: SkillSelectionAdapter
|
||||
@@ -26,16 +26,18 @@ class SkillSelectionDialog(
|
||||
height = UIUtil.dip2px(context, 406.0)
|
||||
gravity = Gravity.BOTTOM
|
||||
binding.tvTitle.visibility = View.VISIBLE
|
||||
binding.tvTitle.text = item?.propVal?:""
|
||||
adapter = SkillSelectionAdapter(context)
|
||||
binding.tvTitle.text = item?.propVal ?: ""
|
||||
adapter = SkillSelectionAdapter(context, item?.state ?: 0,item?.checkLimitNum?:-1)
|
||||
adapter.setOnItemClickListener { _, _, position ->
|
||||
adapter.select(position)
|
||||
callback(adapter.getItem(position)!!)
|
||||
closeDialog()
|
||||
}
|
||||
binding.recyclerView.layoutManager = GridLayoutManager(context, 2)
|
||||
binding.recyclerView.addItemDecoration(SkillGridDecoration(context, 30, 15))
|
||||
binding.recyclerView.adapter = adapter
|
||||
adapter.setNewData(item?.propDictVos)
|
||||
binding.btnEnsure.setOnClickListener {
|
||||
callback.invoke(adapter.getSelectedItems())
|
||||
closeDialog()
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,35 +1,55 @@
|
||||
package com.yizhuan.erban.skill.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import com.yizhuan.erban.R
|
||||
import com.yizhuan.xchat_android_core.skill.entity.PropRecordVoEntity
|
||||
import com.yizhuan.xchat_android_core.skill.entity.PropRefEntity
|
||||
import com.yizhuan.xchat_android_core.utils.TextUtils
|
||||
|
||||
class EditItem(
|
||||
private val isSelf: Boolean,
|
||||
private val isEditable: Boolean,
|
||||
entity: PropRecordVoEntity,
|
||||
context: Context
|
||||
) :
|
||||
SkillItem(entity, context) {
|
||||
class EditItem(private val itemAttr: ItemAttribute) : SkillItem {
|
||||
private lateinit var contentView: EditText
|
||||
private lateinit var titleVIew: TextView
|
||||
private fun initItem() {
|
||||
if (isContentEditable()) {
|
||||
SkillItemHelper.enableEdit(contentView)
|
||||
} else {
|
||||
SkillItemHelper.disableEdit(contentView)
|
||||
contentView.setCompoundDrawables(null, null, null, null)
|
||||
}
|
||||
SkillItemHelper.setTitleText(titleVIew, itemAttr.parentVol, itemAttr.isMust)
|
||||
itemAttr.selectedProperties.getOrNull(0)?.propVal?.let { contentView.setText(it) }
|
||||
}
|
||||
|
||||
init {
|
||||
override fun getContentEntity(): ItemAttribute {
|
||||
itemAttr.selectedProperties.apply {
|
||||
if (isEmpty()) {
|
||||
val entity = PropRefEntity(itemAttr.parentId, null)
|
||||
add(entity)
|
||||
}
|
||||
get(0).propVal = contentView.text.toString()
|
||||
}
|
||||
return itemAttr
|
||||
}
|
||||
|
||||
|
||||
override fun createItem(context: Context): View {
|
||||
val view = LayoutInflater.from(context).inflate(R.layout.layout_skill_edit, null, false)
|
||||
contentView = view.findViewById(R.id.edit_content)
|
||||
titleVIew = view.findViewById(R.id.title_view)
|
||||
initItem()
|
||||
return view
|
||||
}
|
||||
|
||||
override fun getContentEntity(): PropRecordVoEntity {
|
||||
entity.propVal = getContentView().text.toString()
|
||||
entity.propId = entity.parentId
|
||||
return entity
|
||||
}
|
||||
override fun invalidate() {}
|
||||
|
||||
override fun isValid() =
|
||||
if (entity.isMust == 0) true else !TextUtils.isEmptyText(getContentView().text.toString())
|
||||
if (itemAttr.isMust == 0) true else {
|
||||
itemAttr.selectedProperties.isNotEmpty() &&
|
||||
!TextUtils.isEmptyText(itemAttr.selectedProperties[0].propVal)
|
||||
}
|
||||
|
||||
override fun getRightRes() = R.drawable.icon_edit_black
|
||||
override fun isContentEditable(): Boolean {
|
||||
return isSelf && isEditable
|
||||
}
|
||||
|
||||
override fun isRightVisitable() = isSelf && isEditable
|
||||
private fun isContentEditable() = itemAttr.isSelf && itemAttr.editable
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package com.yizhuan.erban.skill.widget
|
||||
|
||||
import com.yizhuan.xchat_android_core.skill.entity.PropRefEntity
|
||||
import java.io.File
|
||||
|
||||
data class ItemAttribute(
|
||||
val cardId: Int,
|
||||
val isSelf: Boolean = false,
|
||||
val editable: Boolean = false,
|
||||
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 onDeleteRecordClick() {}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,21 @@
|
||||
package com.yizhuan.erban.skill.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Space
|
||||
|
||||
class RecordDurationItem(private val attr: ItemAttribute) : SkillItem {
|
||||
override fun createItem(context: Context): View {
|
||||
val view = Space(context)
|
||||
val layoutParams = ViewGroup.LayoutParams(1, 1)
|
||||
view.layoutParams = layoutParams
|
||||
return view
|
||||
}
|
||||
|
||||
override fun invalidate() {}
|
||||
|
||||
override fun isValid() = true
|
||||
|
||||
override fun getContentEntity() = attr
|
||||
}
|
@@ -0,0 +1,201 @@
|
||||
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
|
||||
import com.yizhuan.erban.ui.widget.dialog.CommonTipDialog
|
||||
import com.yizhuan.xchat_android_core.utils.TextUtils
|
||||
import com.yizhuan.xchat_android_core.utils.toast
|
||||
import java.io.File
|
||||
|
||||
class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
|
||||
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 reStartTipDialog by lazy {
|
||||
CommonTipDialog(context).apply {
|
||||
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() {
|
||||
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)
|
||||
binding = LayoutSkillAudioBinding.inflate(inflater)
|
||||
initItem()
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private fun initItem() {
|
||||
binding.recordView.recordListener = this
|
||||
binding.recordView.recordDuration = MAX_RECORD_DURATION
|
||||
binding.recordState = itemAttribute.audioStatus
|
||||
itemAttribute.audioDuration?.let { binding.duration = it }
|
||||
binding.btnCancel.text = if (itemAttribute.isSelf) "取消录制" else "取消重新录制"
|
||||
|
||||
binding.click = this
|
||||
}
|
||||
|
||||
override fun invalidate() {}
|
||||
|
||||
override fun isValid() = true
|
||||
|
||||
override fun getContentEntity() = itemAttribute
|
||||
|
||||
override fun onRecordTimeUpdate(remain: Int) {
|
||||
audioLength = binding.recordView.recordDuration - remain
|
||||
}
|
||||
|
||||
override fun onRecordStart(file: File?, recordType: RecordType?) {
|
||||
binding.recordState = RECORD_STATE_RECORDING
|
||||
}
|
||||
|
||||
override fun onRecordCancel() {
|
||||
//审核通过后 重新录制取消 要设置为之前审核通过的状态
|
||||
binding.recordState = itemAttribute.audioStatus
|
||||
}
|
||||
|
||||
override fun onRecordSuccess(file: File?) {
|
||||
if (audioLength < 3) {
|
||||
"录制时间不能少于3s哦".toast()
|
||||
binding.recordState = RECORD_STATE_READY
|
||||
return
|
||||
}
|
||||
itemAttribute.itemEventListener?.onRecordSuccess(file, audioLength)
|
||||
}
|
||||
|
||||
override fun onRecordFail() {
|
||||
"录制失败,请重试".toast()
|
||||
setItemByState(RECORD_STATE_READY)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据状态设置View
|
||||
*/
|
||||
fun setItemByState(state: Int) {
|
||||
binding.recordState = state
|
||||
}
|
||||
|
||||
private fun playAudio(url: String?) {
|
||||
if (playState == PLAY_STATE_PLAYING || TextUtils.isEmptyText(url)) return
|
||||
playState = PLAY_STATE_PLAYING
|
||||
binding.palyState = playState
|
||||
AudioPlayerHelper.get().playInThread(url, object : OnPlayListener {
|
||||
override fun onError(error: String?) {
|
||||
"播放出错,请重试".toast()
|
||||
playState = PLAY_STATE_READY
|
||||
binding.palyState = playState
|
||||
}
|
||||
|
||||
override fun onPrepared() {}
|
||||
|
||||
override fun onPlaying(currDuration: Long) {}
|
||||
|
||||
override fun onCompletion() {
|
||||
playState = PLAY_STATE_READY
|
||||
binding.palyState = playState
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun stopAudio() {
|
||||
if (playState == PLAY_STATE_READY) return
|
||||
AudioPlayerHelper.get().endPlay()
|
||||
playState = 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,37 +1,59 @@
|
||||
package com.yizhuan.erban.skill.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.yizhuan.erban.R
|
||||
import com.yizhuan.xchat_android_core.skill.entity.PropRecordVoEntity
|
||||
import com.yizhuan.xchat_android_core.utils.TextUtils
|
||||
import java.lang.StringBuilder
|
||||
|
||||
class SelectionItem(
|
||||
private val isSelf: Boolean,
|
||||
private val isEditable: Boolean,
|
||||
private val selectionListener: OnItemSelectionListener?,
|
||||
entity: PropRecordVoEntity, context: Context
|
||||
) :
|
||||
SkillItem(entity, context) {
|
||||
init {
|
||||
class SelectionItem(private val itemAttr: ItemAttribute) : SkillItem {
|
||||
private lateinit var contentView: TextView
|
||||
private lateinit var titleVIew: TextView
|
||||
private lateinit var contentFrame: ConstraintLayout
|
||||
override fun getContentEntity() = itemAttr
|
||||
override fun createItem(context: Context): View {
|
||||
val view =
|
||||
LayoutInflater.from(context).inflate(R.layout.layout_skill_selection, null, false)
|
||||
contentView = view.findViewById(R.id.edit_content)
|
||||
titleVIew = view.findViewById(R.id.title_view)
|
||||
contentFrame = view.findViewById(R.id.fl_content)
|
||||
initItem()
|
||||
return view
|
||||
}
|
||||
|
||||
override fun getContentEntity() = entity
|
||||
private fun initItem() {
|
||||
if (!isContentEditable()) {
|
||||
contentView.setCompoundDrawables(null, null, null, null)
|
||||
} else {
|
||||
contentFrame.setOnClickListener {
|
||||
itemAttr.itemEventListener?.onItemClick(this)
|
||||
}
|
||||
}
|
||||
SkillItemHelper.setTitleText(titleVIew, itemAttr.parentVol, itemAttr.isMust)
|
||||
setContent()
|
||||
}
|
||||
|
||||
private fun setContent() {
|
||||
val builder = StringBuilder()
|
||||
itemAttr.selectedProperties.forEach {
|
||||
if (!TextUtils.isEmptyText(it.propVal)) {
|
||||
builder.append(it.propVal).append("、")
|
||||
}
|
||||
}
|
||||
if (builder.isNotEmpty()) builder.deleteCharAt(builder.length - 1)
|
||||
contentView.text = builder.toString()
|
||||
builder.delete(0, builder.length)
|
||||
}
|
||||
|
||||
override fun invalidate() {
|
||||
setContent()
|
||||
}
|
||||
|
||||
override fun isValid() =
|
||||
entity.isMust == 0 || entity.propId != -1
|
||||
itemAttr.isMust == 0 || itemAttr.selectedProperties.isNotEmpty()
|
||||
|
||||
override fun getRightRes() = R.drawable.arrow_right
|
||||
override fun isContentEditable() = false
|
||||
override fun isRightVisitable() = isSelf && isEditable//需要优化代码
|
||||
|
||||
init {
|
||||
getContentView().setOnClickListener {
|
||||
selectionListener?.onItemSelection(this)
|
||||
entity.propVal?.let { getContentView().setText(it) }
|
||||
}
|
||||
}
|
||||
|
||||
interface OnItemSelectionListener {
|
||||
fun onItemSelection(item: SkillItem)
|
||||
}
|
||||
private fun isContentEditable() = itemAttr.isSelf && itemAttr.editable
|
||||
}
|
@@ -0,0 +1,17 @@
|
||||
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,
|
||||
val isSelf: Boolean = false,
|
||||
val isEdit: Boolean = false,
|
||||
val background: String?,
|
||||
val itemAttributes: List<ItemAttribute>
|
||||
)
|
@@ -10,10 +10,6 @@ import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.Nullable
|
||||
import com.yizhuan.erban.R
|
||||
import com.yizhuan.xchat_android_core.skill.entity.PropRecordVoEntity
|
||||
import com.yizhuan.xchat_android_core.skill.entity.SKillValueEntity
|
||||
import com.yizhuan.xchat_android_core.skill.entity.SkillPostServerEntity
|
||||
import com.yizhuan.xchat_android_core.skill.entity.SkillRecordEntity
|
||||
import com.yizhuan.erban.ui.utils.ImageLoadUtils
|
||||
import com.yizhuan.erban.ui.utils.ImageLoadUtilsV2
|
||||
import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil
|
||||
@@ -30,12 +26,11 @@ class SkillCardView(
|
||||
constructor(context: Context) : this(context, null)
|
||||
constructor(context: Context, @Nullable attrs: AttributeSet?) : this(context, attrs, 0)
|
||||
|
||||
private var itemList: ArrayList<SkillItem>
|
||||
private var rootEntity: SkillRecordEntity? = null
|
||||
private var itemList: MutableList<SkillItem> = emptyList<SkillItem>().toMutableList()
|
||||
private lateinit var skillAttr: SkillAttribute
|
||||
|
||||
init {
|
||||
orientation = VERTICAL
|
||||
itemList = ArrayList()
|
||||
}
|
||||
|
||||
//标题
|
||||
@@ -66,7 +61,7 @@ class SkillCardView(
|
||||
lineParams.leftMargin = lineMargin
|
||||
lineParams.rightMargin = lineMargin
|
||||
for ((index, item) in itemList.withIndex()) {
|
||||
val itemView = item.createItem()
|
||||
val itemView = item.createItem(context)
|
||||
addView(itemView, layoutParams)
|
||||
if (index != itemList.size - 1) {
|
||||
val lineView = View(context)
|
||||
@@ -76,18 +71,18 @@ class SkillCardView(
|
||||
}
|
||||
}
|
||||
|
||||
private fun createItemView(
|
||||
isSelf: Boolean,
|
||||
isEdit: Boolean,
|
||||
selectionListener: SelectionItem.OnItemSelectionListener?,
|
||||
entity: PropRecordVoEntity
|
||||
): SkillItem {
|
||||
return when (entity.state) {
|
||||
1 -> EditItem(isSelf, isEdit, entity, context)
|
||||
else -> SelectionItem(isSelf, isEdit,selectionListener, entity, context)
|
||||
//根据state创建Item视图
|
||||
private fun createItemView(item: ItemAttribute): SkillItem {
|
||||
return when (item.state) {
|
||||
1 -> EditItem(item)
|
||||
0, 2 -> SelectionItem(item)
|
||||
3 -> RecordIResourceItem(item)
|
||||
else -> RecordDurationItem(item)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//设置SkillView背景
|
||||
private fun setBackgroundImg(url: String?) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return
|
||||
@@ -95,54 +90,35 @@ class SkillCardView(
|
||||
ImageLoadUtils.loadRoundBackground(context, url, this, 8, R.drawable.bg_corner_shadow_12)
|
||||
}
|
||||
|
||||
|
||||
fun setItems(
|
||||
rootEntity: SkillRecordEntity,
|
||||
selectionListener: SelectionItem.OnItemSelectionListener?
|
||||
) {
|
||||
this.rootEntity = rootEntity
|
||||
this.itemList.clear()
|
||||
rootEntity.propRecordVo?.forEach {
|
||||
this.itemList.add(
|
||||
createItemView(
|
||||
rootEntity.isSelf,
|
||||
rootEntity.isEdit,
|
||||
selectionListener,
|
||||
it
|
||||
)
|
||||
)
|
||||
fun initView(attr: SkillAttribute) {
|
||||
this.skillAttr = attr
|
||||
itemList.clear()
|
||||
attr.itemAttributes.forEach {
|
||||
this.itemList.add(createItemView(it))
|
||||
}
|
||||
setBackgroundImg(rootEntity.pic)
|
||||
//暂时处理
|
||||
SkillItemHelper.wrapAudio(attr)
|
||||
setBackgroundImg(attr.background)
|
||||
removeAllViews()
|
||||
setSkillTitle(rootEntity.icon, rootEntity.name, rootEntity.isSelf, rootEntity.isEdit)
|
||||
setSkillTitle(attr.skillRes, attr.skillName, attr.isSelf, attr.isEdit)
|
||||
setChildItems()
|
||||
requestLayout()
|
||||
}
|
||||
|
||||
fun isValid(): Boolean {
|
||||
var isValid = true
|
||||
itemList.forEach {
|
||||
if (!it.isValid()) {
|
||||
isValid = false
|
||||
return@forEach
|
||||
run outer@{
|
||||
itemList.forEach {
|
||||
if (!it.isValid()) {
|
||||
isValid = false
|
||||
return@outer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isValid
|
||||
}
|
||||
|
||||
fun getItems(): List<SkillItem> = itemList
|
||||
|
||||
fun getSavedValues(): SkillPostServerEntity {
|
||||
return if (rootEntity == null) {
|
||||
SkillPostServerEntity(-1, -1, ArrayList(0))
|
||||
} else {
|
||||
val list = ArrayList<SKillValueEntity>()
|
||||
itemList.forEach {
|
||||
val item = it.getContentEntity()
|
||||
list.add(SKillValueEntity(item.parentId, item.propId, item.propVal))
|
||||
}
|
||||
SkillPostServerEntity(rootEntity!!.id, rootEntity!!.cardId, list)
|
||||
}
|
||||
|
||||
}
|
||||
fun getAttributes() = skillAttr
|
||||
}
|
@@ -1,98 +1,11 @@
|
||||
package com.yizhuan.erban.skill.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import com.yizhuan.erban.R
|
||||
import com.yizhuan.xchat_android_core.skill.entity.*
|
||||
import com.yizhuan.erban.ui.widget.magicindicator.buildins.UIUtil
|
||||
|
||||
abstract class SkillItem(
|
||||
protected var entity: PropRecordVoEntity,
|
||||
context: Context
|
||||
) {
|
||||
private var titleView: TextView
|
||||
private var contentView: EditText
|
||||
private var itemView: View =
|
||||
LayoutInflater.from(context).inflate(R.layout.layout_skill_item, null, false)
|
||||
private var rightDrawable: Drawable? = null
|
||||
|
||||
init {
|
||||
titleView = itemView.findViewById(R.id.title_view)
|
||||
contentView = itemView.findViewById(R.id.edit_content)
|
||||
contentView.compoundDrawablePadding = UIUtil.dip2px(context, 10.0)
|
||||
if (getRightRes() != -1) {
|
||||
rightDrawable = context.getDrawable(getRightRes())
|
||||
}
|
||||
}
|
||||
|
||||
protected fun initItem() {
|
||||
if (isContentEditable()) {
|
||||
enableEdit()
|
||||
} else {
|
||||
disableEdit()
|
||||
}
|
||||
entity.parentVal?.let { setTitleText(it) }
|
||||
entity.propVal?.let { contentView.setText(it) }
|
||||
|
||||
if (isContentEditable()) {
|
||||
contentView.hint = "请输入"
|
||||
}
|
||||
if (isRightVisitable()) {
|
||||
rightDrawable?.let {
|
||||
it.setBounds(0, 0, it.minimumWidth, it.minimumHeight)
|
||||
contentView.setCompoundDrawables(null, null, it, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setTitleText(title: String) {
|
||||
if (entity.isMust == 0) {
|
||||
titleView.text = title
|
||||
return
|
||||
}
|
||||
val spannableStringBuilder = SpannableStringBuilder(title)
|
||||
val length = spannableStringBuilder.length
|
||||
spannableStringBuilder.append("*")
|
||||
spannableStringBuilder.setSpan(
|
||||
ForegroundColorSpan(Color.parseColor("#FF2222")),
|
||||
length,
|
||||
spannableStringBuilder.length,
|
||||
SpannableStringBuilder.SPAN_INCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
titleView.text = spannableStringBuilder
|
||||
}
|
||||
|
||||
internal fun createItem(): View = itemView
|
||||
internal fun invalidate() {
|
||||
contentView.setText(getContentEntity().propVal ?: "")
|
||||
}
|
||||
|
||||
private fun disableEdit() {
|
||||
contentView.isFocusableInTouchMode = false
|
||||
contentView.isFocusable = false
|
||||
contentView.isCursorVisible = false
|
||||
}
|
||||
|
||||
private fun enableEdit() {
|
||||
contentView.isFocusableInTouchMode = true
|
||||
contentView.isFocusable = true
|
||||
contentView.isCursorVisible = true
|
||||
}
|
||||
|
||||
|
||||
internal abstract fun getContentEntity(): PropRecordVoEntity
|
||||
internal abstract fun isValid(): Boolean
|
||||
internal abstract fun getRightRes(): Int
|
||||
internal abstract fun isContentEditable(): Boolean
|
||||
internal abstract fun isRightVisitable(): Boolean
|
||||
|
||||
protected fun getContentView(): EditText = contentView
|
||||
|
||||
interface SkillItem {
|
||||
fun createItem(context: Context): View
|
||||
fun invalidate()
|
||||
fun isValid(): Boolean
|
||||
fun getContentEntity(): ItemAttribute
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
package com.yizhuan.erban.skill.widget
|
||||
|
||||
import android.graphics.Color
|
||||
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 {
|
||||
/**
|
||||
* 设置Item标题
|
||||
*/
|
||||
fun setTitleText(titleView: TextView, title: String, isMust: Int) {
|
||||
if (isMust == 0) {
|
||||
titleView.text = title
|
||||
return
|
||||
}
|
||||
val spannableStringBuilder = SpannableStringBuilder(title)
|
||||
val length = spannableStringBuilder.length
|
||||
spannableStringBuilder.append("*")
|
||||
spannableStringBuilder.setSpan(
|
||||
ForegroundColorSpan(Color.parseColor("#FF2222")),
|
||||
length,
|
||||
spannableStringBuilder.length,
|
||||
SpannableStringBuilder.SPAN_INCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
titleView.text = spannableStringBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用EditText编辑
|
||||
*/
|
||||
|
||||
fun disableEdit(contentView: EditText) {
|
||||
contentView.isFocusableInTouchMode = false
|
||||
contentView.isFocusable = false
|
||||
contentView.isCursorVisible = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用EditText编辑
|
||||
*/
|
||||
fun enableEdit(contentView: EditText) {
|
||||
contentView.isFocusableInTouchMode = true
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,180 @@
|
||||
package com.yizhuan.erban.skill.widget
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.RectF
|
||||
import android.util.AttributeSet
|
||||
import android.view.animation.LinearInterpolator
|
||||
import androidx.annotation.Nullable
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import com.netease.nim.uikit.impl.NimUIKitImpl
|
||||
import com.netease.nimlib.sdk.media.record.AudioRecorder
|
||||
import com.netease.nimlib.sdk.media.record.IAudioRecordCallback
|
||||
import com.netease.nimlib.sdk.media.record.RecordType
|
||||
import com.yizhuan.erban.R
|
||||
import java.io.File
|
||||
|
||||
private const val STATE_PAUSED = 0
|
||||
private const val STATE_PLAYED = 1
|
||||
|
||||
class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defStyleAttr: Int) :
|
||||
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)
|
||||
}
|
||||
private var state = STATE_PAUSED
|
||||
private var animator: ValueAnimator? = null
|
||||
private var animatedPercent = 0f
|
||||
internal var recordDuration = 15
|
||||
private var audioMessageHelper: AudioRecorder? = null
|
||||
|
||||
var recordListener: RecordListener? = null
|
||||
|
||||
constructor(context: Context) : this(context, null)
|
||||
|
||||
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) {
|
||||
STATE_PAUSED -> {
|
||||
startRecord()
|
||||
}
|
||||
STATE_PLAYED -> {
|
||||
endAudioRecord(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||
val width = MeasureSpec.getSize(widthMeasureSpec)
|
||||
val height = MeasureSpec.getSize(heightMeasureSpec)
|
||||
setMeasuredDimension(width, height)
|
||||
}
|
||||
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
if (state == STATE_PLAYED) {
|
||||
val rectF = RectF()
|
||||
val swipe = animatedPercent * 360
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//开始录制
|
||||
private fun startRecord() {
|
||||
if (audioMessageHelper == null) {
|
||||
val options = NimUIKitImpl.getOptions()
|
||||
options.audioRecordMaxTime = recordDuration
|
||||
audioMessageHelper = AudioRecorder(
|
||||
context, options.audioRecordType,
|
||||
options.audioRecordMaxTime, this
|
||||
)
|
||||
}
|
||||
setImageResource(R.drawable.ic_skill_audio_recording)
|
||||
audioMessageHelper!!.startRecord()
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束语音录制
|
||||
*
|
||||
* @param cancel -- true 取消 重新录制 false 录制完成
|
||||
*/
|
||||
fun endAudioRecord(cancel: Boolean) {
|
||||
state = STATE_PAUSED
|
||||
audioMessageHelper?.completeRecord(cancel)
|
||||
setImageResource(R.drawable.ic_skill_audio_ready)
|
||||
clearRecordAnim()
|
||||
}
|
||||
|
||||
|
||||
private fun playRecordAnim() {
|
||||
animator = ValueAnimator.ofFloat(0f, 360f)
|
||||
?.apply {
|
||||
duration = (recordDuration * 1000).toLong()
|
||||
addUpdateListener {
|
||||
animatedPercent = it.animatedFraction
|
||||
recordListener?.onRecordTimeUpdate((recordDuration * (1 - animatedPercent)).toInt())
|
||||
invalidate()
|
||||
}
|
||||
interpolator = LinearInterpolator()
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun clearRecordAnim() {
|
||||
animator?.let {
|
||||
it.removeAllUpdateListeners()
|
||||
if (it.isRunning) it.end()
|
||||
}
|
||||
animator = null
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
clearRecordAnim()
|
||||
audioMessageHelper?.destroyAudioRecorder()
|
||||
}
|
||||
|
||||
override fun onRecordReady() {}
|
||||
|
||||
override fun onRecordStart(audioFile: File?, recordType: RecordType?) {
|
||||
state = STATE_PLAYED
|
||||
playRecordAnim()
|
||||
recordListener?.onRecordStart(audioFile, recordType)
|
||||
}
|
||||
|
||||
override fun onRecordSuccess(audioFile: File?, audioLength: Long, recordType: RecordType?) {
|
||||
state = STATE_PAUSED
|
||||
clearRecordAnim()
|
||||
recordListener?.onRecordSuccess(audioFile)
|
||||
}
|
||||
|
||||
override fun onRecordFail() {
|
||||
state = STATE_PAUSED
|
||||
recordListener?.onRecordFail()
|
||||
clearRecordAnim()
|
||||
}
|
||||
|
||||
override fun onRecordCancel() {
|
||||
state = STATE_PAUSED
|
||||
recordListener?.onRecordCancel()
|
||||
clearRecordAnim()
|
||||
}
|
||||
|
||||
override fun onRecordReachedMaxTime(maxTime: Int) {
|
||||
state = STATE_PAUSED
|
||||
clearRecordAnim()
|
||||
audioMessageHelper?.handleEndRecord(true, maxTime)
|
||||
}
|
||||
|
||||
interface RecordListener {
|
||||
fun onRecordTimeUpdate(remain: Int)
|
||||
fun onRecordStart(file: File?, recordType: RecordType?)
|
||||
fun onRecordCancel()
|
||||
fun onRecordSuccess(file: File?)
|
||||
fun onRecordFail()
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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()
|
||||
}
|
||||
}
|
@@ -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) {
|
||||
|
@@ -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) {
|
||||
|
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_01.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_02.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_03.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_04.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_05.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_06.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_07.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_08.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_09.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_10.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_11.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_12.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_13.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_14.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_15.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_16.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_17.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_18.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_19.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_20.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_21.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_22.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_23.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_24.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_25.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_26.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_27.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_28.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_29.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_30.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_31.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_32.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_33.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_34.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_35.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_36.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_37.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_38.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_39.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_anim_40.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_ready.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_audio_recording.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_pause.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_play.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable-xhdpi/icon_skill_edit.png
Normal file
After Width: | Height: | Size: 756 B |
7
app/src/main/res/drawable/bg_ffce4e_trans30_20dp.xml
Normal 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>
|
@@ -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>
|
8
app/src/main/res/drawable/bg_skill_record_sound.xml
Normal 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>
|
16
app/src/main/res/drawable/bg_userinfo_skill_audio.xml
Normal 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>
|
126
app/src/main/res/drawable/skill_audio_animation.xml
Normal 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>
|
@@ -20,16 +20,31 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
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"
|
||||
/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/btn_ensure"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginTop="@dimen/dp_16"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_title"
|
||||
app:layout_goneMarginTop="@dimen/dp_16" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
@@ -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"
|
||||
|
@@ -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>
|
29
app/src/main/res/layout/layout_msg_view_holder_skill.xml
Normal 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>
|
@@ -5,8 +5,9 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="@drawable/shape_white_20dp_round"
|
||||
tools:background="@color/black_transparent_10"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
tools:background="@color/black_transparent_10">
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dp_26" />
|
||||
@@ -15,19 +16,20 @@
|
||||
android:id="@+id/message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginBottom="@dimen/dp_32"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:paddingEnd="20dp"
|
||||
android:lineSpacingMultiplier="1.2"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="@dimen/dp_32"
|
||||
tools:text="购买成功,是否立即驾驶sd水电费水电费?sfasdfasdfasdfasdfasdf" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="horizontal">
|
||||
|
||||
@@ -35,21 +37,21 @@
|
||||
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:layout_marginEnd="@dimen/dp_16"
|
||||
android:background="@drawable/bg_common_cancel"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<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:background="@drawable/bg_common_confirm"
|
||||
android:textSize="15sp" />
|
||||
</LinearLayout>
|
||||
|
||||
|
164
app/src/main/res/layout/layout_skill_audio.xml
Normal file
@@ -0,0 +1,164 @@
|
||||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/dp_25"
|
||||
android:paddingBottom="@dimen/dp_25">
|
||||
|
||||
<com.yizhuan.erban.skill.widget.TimerRecorderView
|
||||
android:id="@+id/record_view"
|
||||
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"
|
||||
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" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_cancel"
|
||||
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"
|
||||
android:text="取消重新录制" />
|
||||
|
||||
<!--录制完成 审核中-->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_sound"
|
||||
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"
|
||||
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_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
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"
|
||||
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="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"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:text="删除声音" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_restart"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginLeft="@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_goneMarginLeft="0dp"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:text="重新录制" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/bottom_button_barrier"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:barrierDirection="top"
|
||||
app:constraint_referenced_ids="btn_restart,btn_delete" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
@@ -2,6 +2,7 @@
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
@@ -23,18 +24,20 @@
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_content"
|
||||
tools:text="1122"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/dp_10"
|
||||
android:background="@null"
|
||||
android:drawableRight="@drawable/icon_skill_edit"
|
||||
android:ellipsize="end"
|
||||
android:gravity="right|center_vertical"
|
||||
android:maxWidth="160dp"
|
||||
android:maxLength="30"
|
||||
android:maxLines="3"
|
||||
android:minWidth="@dimen/dp_60"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/sp_16"
|
||||
app:layout_constrainedWidth="true"
|
||||
android:drawablePadding="@dimen/dp_10"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@id/title_view"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
51
app/src/main/res/layout/layout_skill_selection.xml
Normal file
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="@dimen/dp_16"
|
||||
android:paddingTop="@dimen/dp_24"
|
||||
android:paddingRight="@dimen/dp_16"
|
||||
android:paddingBottom="@dimen/dp_10">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/title_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/sp_14"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@+id/fl_content"
|
||||
app:layout_constraintTop_toTopOf="@+id/fl_content" />
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/fl_content"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="60dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@id/title_view"
|
||||
app:layout_constraintRight_toRightOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/edit_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
android:drawableRight="@drawable/arrow_right"
|
||||
android:drawablePadding="@dimen/dp_10"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="5"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="@dimen/sp_16"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@@ -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" />
|
||||
@@ -368,4 +370,11 @@
|
||||
<attr name="rollviewpager_hint_alpha" format="integer" />
|
||||
</declare-styleable>
|
||||
|
||||
|
||||
<!--倒计时录音控件-->
|
||||
<declare-styleable name="TimerRecorderView">
|
||||
<attr name="progressWidth" format="dimension" />
|
||||
<attr name="outerWidth" format="dimension" />
|
||||
<attr name="progressColor" format="color" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
@@ -598,5 +598,6 @@
|
||||
|
||||
|
||||
<color name="color_40_333333">#66333333</color>
|
||||
<color name="color_30_ffce4e">#4DFFCE4E</color>
|
||||
|
||||
</resources>
|
||||
|
@@ -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>
|
@@ -911,7 +911,14 @@
|
||||
<string name="home_like_hint">关注的人和收藏的房间都会出现在这里\n暂无关注的人和收藏的房间哦</string>
|
||||
<string name="avatar_auditing">头像已送审,审核成功后自动应用头像</string>
|
||||
<string name="vip_time_desc">剩余时间以30天为周期,以获得新的贵族等级次日起算30日后的中午12:00为截止时间,周期内贵族等级出现变化则剩余时间自动重置为30天。</string>
|
||||
<!--技能卡-->
|
||||
<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>
|
||||
</resources>
|
||||
|
@@ -556,6 +556,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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -425,7 +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 CustomAttachment() {
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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
|
||||
)
|
@@ -5,9 +5,9 @@ package com.yizhuan.xchat_android_core.skill.entity
|
||||
* (⊙o⊙)…
|
||||
*/
|
||||
data class SkillPostServerEntity(
|
||||
var id: Int,
|
||||
var cardId: Int,
|
||||
val id: Int =-1,
|
||||
val cardId: Int=-1,
|
||||
var propRecordVo: List<SKillValueEntity>
|
||||
)
|
||||
|
||||
data class SKillValueEntity(var parentId: Int, var propId: Int, var propVal: String?)
|
||||
data class SKillValueEntity(var parentId: Int, var refPropVos:List<PropRefEntity>)
|
@@ -1,5 +1,7 @@
|
||||
package com.yizhuan.xchat_android_core.skill.entity
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class SkillPropertyEntity(
|
||||
val cardId: Int,
|
||||
val name: String,
|
||||
@@ -7,7 +9,13 @@ data class SkillPropertyEntity(
|
||||
val pic: String,
|
||||
val type: Int,
|
||||
val props: List<PropsEntity>
|
||||
)
|
||||
) {
|
||||
@Transient
|
||||
var isSelf = false//主态还是客态
|
||||
|
||||
@Transient
|
||||
var isEdit = false//编辑还是展示
|
||||
}
|
||||
|
||||
data class PropsEntity(
|
||||
var id: Int,
|
||||
@@ -15,11 +23,25 @@ data class PropsEntity(
|
||||
var propVal: String,
|
||||
val state: Int,
|
||||
val isMust: Int,
|
||||
val propDictVos: List<PropDictVosEntity>
|
||||
)
|
||||
var propDictVos: List<PropDictVo>,
|
||||
val checkLimitNum: Int
|
||||
) {
|
||||
fun parsePropToRecord(): PropRecordVoEntity = PropRecordVoEntity(
|
||||
id, propVal, emptyList(), checkLimitNum, state, isMust
|
||||
)
|
||||
}
|
||||
|
||||
data class PropDictVosEntity(
|
||||
val id: Int,
|
||||
val propVal: String
|
||||
)
|
||||
data class PropDictVo(
|
||||
// 两个数据结构一致只是id的名字不一样
|
||||
@SerializedName("id")
|
||||
var id: Int,
|
||||
var propVal: String?,//输入 选项 时长
|
||||
val refIsOnlyCheck: Int//所有属性都有0-多选的选项/1表示此属性只能单选,互斥
|
||||
) {
|
||||
@Transient
|
||||
var isSelected = false
|
||||
|
||||
fun parseToRecord(): PropRefEntity = PropRefEntity(
|
||||
id, propVal, refIsOnlyCheck
|
||||
)
|
||||
}
|
@@ -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?,
|
||||
@@ -8,11 +10,14 @@ data class SkillRecordEntity(
|
||||
val name: String,
|
||||
val pic: String,
|
||||
val propRecordVo: List<PropRecordVoEntity>,
|
||||
val type: Int,
|
||||
val updateTime: String?
|
||||
val type: Int,//技能卡类型 1游戏类 2才艺类 3声音秀
|
||||
val updateTime: String?,
|
||||
@SerializedName("status")
|
||||
val audioStatus:Int//声音秀审核状态
|
||||
) {
|
||||
@Transient
|
||||
var isSelf = false//主态还是客态
|
||||
|
||||
@Transient
|
||||
var isEdit = false//编辑还是展示
|
||||
}
|
||||
@@ -20,8 +25,14 @@ data class SkillRecordEntity(
|
||||
data class PropRecordVoEntity(
|
||||
val parentId: Int,
|
||||
val parentVal: String,
|
||||
var propId: Int,
|
||||
var propVal: String?,
|
||||
var refPropVos: List<PropRefEntity>,//技能卡关联子属性集合
|
||||
val checkLimitNum: Int,//技能卡多选数量限制
|
||||
val state: Int,
|
||||
val isMust: Int
|
||||
)
|
||||
|
||||
data class PropRefEntity(
|
||||
var propId: Int,
|
||||
var propVal: String?,//输入 选项 时长
|
||||
val refIsOnlyCheck: Int = 0//所有属性都有0-多选的选项/1表示此属性只能单选,互斥
|
||||
)
|
||||
|
@@ -23,5 +23,5 @@ only_arm64=false
|
||||
|
||||
channel_file=channel.txt
|
||||
|
||||
version_name=4.2.0
|
||||
version_code=420
|
||||
version_name=4.3.0
|
||||
version_code=430
|