feat : app-main-java

This commit is contained in:
eggmanQQQ2
2025-07-07 10:45:44 +08:00
parent 9335909e8f
commit bac05f5edc
1320 changed files with 180194 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
package com.chwl.app;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Build;
import androidx.appcompat.app.AppCompatActivity;
import java.util.List;
public class AgentActivity extends AppCompatActivity {
// implements SceneRestorable {
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
// MobLink.updateNewIntent(getIntent(), this);
}
// @Override
// public void onReturnSceneData(Scene scene) {
//
// try {
// HashMap<String, Object> hashMap = scene.getParams();
//
// LogUtil.print("linkedme", hashMap);
// //根据key获取传入的参数的值,该key关键字View可为任意值,由集成方规定,请与web端商议,一致即可
// LinkedInfo linkedInfo = new LinkedInfo();
// String roomuid = (String) hashMap.get("roomuid");
// String uid = (String) hashMap.get("uid");
// String type = String.valueOf(hashMap.get("type"));
// String familyId = (String) hashMap.get("familyId");
// String url = (String) hashMap.get("url");
// String worldId = (String) hashMap.get("worldId");
// String dynamicId = (String) hashMap.get("dynamicId");
// String inviteCode = (String) hashMap.get("inviteCode");
// if (roomuid != null) {
// linkedInfo.setRoomUid(roomuid);
// }
// if (TextUtils.isEmptyText(roomuid) && uid != null) {
// linkedInfo.setRoomUid(uid);
// }
// if (uid != null) {
// linkedInfo.setUid(uid);
// }
// linkedInfo.setType(type);
// if (familyId != null) {
// linkedInfo.setFamilyId(familyId);
// }
// if (url != null) {
// linkedInfo.setUrl(url);
// }
// if (worldId != null) {
// linkedInfo.setWorldId(worldId);
// }
// if (dynamicId != null) {
// linkedInfo.setDynamicId(dynamicId);
// }
//
// linkedInfo.setInviteCode(inviteCode);
//
// LinkedModel.get().setLinkedInfo(linkedInfo);
//
// } catch (Exception e) {
// }
//
//
// if (isExistMainActivity(MainActivity.class) && UserModel.get().getCacheLoginUserInfo() != null) {//应用已开启&用户信息以获取
// MainActivity.handleLinkedJump(this);
// } else {//应用未开启
// SplashActivity.start(this);
// }
// finish();
// }
public boolean isExistMainActivity(Class<?> activity) {
try {
Intent intent = new Intent(this, activity);
ComponentName cmpName = intent.resolveActivity(getPackageManager());
boolean flag = false;
if (cmpName != null) {
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
List<ActivityManager.AppTask> taskInfoList = am.getAppTasks();
for (ActivityManager.AppTask taskInfo : taskInfoList) {
if (taskInfo.getTaskInfo().baseActivity.equals(cmpName)) {
flag = true;
break;
}
}
} else {
List<ActivityManager.RunningTaskInfo> taskInfoList = am.getRunningTasks(10);
for (ActivityManager.RunningTaskInfo taskInfo : taskInfoList) {
if (taskInfo.baseActivity.equals(cmpName)) {
flag = true;
break;
}
}
}
}
return flag;
} catch (Throwable e) {
return false;
}
}
}

View File

@@ -0,0 +1,55 @@
package com.chwl.app
import android.content.Context
import android.content.Intent
import android.view.ViewGroup
import com.chwl.app.base.BaseViewBindingActivity
import com.chwl.app.bindadapter.BaseBindingAdapter
import com.chwl.app.bindadapter.BaseBindingViewHolder
import com.chwl.app.databinding.ActivityDemoBinding
import com.chwl.app.databinding.ListItemMicroBinding
import com.chwl.core.widget.layoutmanager.pagergridlayoutmanager.PagerGridLayoutManager.LayoutParams
import com.chwl.library.common.util.ClickUtils.click
import com.chwl.library.common.util.setViewWH
import com.chwl.library.common.util.setVis
class DemoActivity : BaseViewBindingActivity<ActivityDemoBinding>() {
companion object{
@JvmStatic
fun start(context: Context) {
val starter = Intent(context, DemoActivity::class.java)
context.startActivity(starter)
}
}
override fun init() {
var isOpen = false
binding.b1.click {
binding.btnLayout.setViewWH(height = if (!isOpen) ViewGroup.LayoutParams.WRAP_CONTENT else 1 , isDP = false)
isOpen = !isOpen
}
}
class DemoAdapter : BaseBindingAdapter<ListItemMicroBinding,Int>() {
override fun convert(helper: BaseBindingViewHolder<ListItemMicroBinding>, item: Int) {
val bindingAdapterPosition = helper.bindingAdapterPosition
helper.binding.root.setViewWH(width = LayoutParams.MATCH_PARENT, height = LayoutParams.MATCH_PARENT , false)
helper.binding.avatar.setVis(true)
helper.binding.avatar.setImageResource(R.drawable.user_info_ic_id)
helper.binding.llCharmClick.setVis(true)
helper.binding.tvCharmValue.setVis(true)
helper.binding.tvCharmValue.text = "${ bindingAdapterPosition + 1}"
}
}
}

View File

@@ -0,0 +1,68 @@
package com.chwl.app;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.viewpager.widget.PagerAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2017/7/12 0012.
*/
public class GuideAdapter extends PagerAdapter {
private List<ImageView> mData=new ArrayList<ImageView>();
public GuideAdapter(Context context){
initData(context);
}
//取得适配器装配的数据
public List<ImageView> getData(){
return mData;
}
//添加视图项
public void addItem(ImageView imageView){
mData.add(imageView);
}
//初始化视图项的数据
private void initData(Context context) {
ImageView imageView=new ImageView(context);
// imageView.setImageResource(resId);//设置ImageView的前景图片
// imageView.setBackgroundResource(R.drawable.guide_one);//设置背景
mData.add(imageView);
imageView=new ImageView(context);
// imageView.setBackgroundResource(R.drawable.guide_two);//设置背景
mData.add(imageView);
imageView=new ImageView(context);
// imageView.setBackgroundResource(R.drawable.guide_three);//设置背景
mData.add(imageView);
}
//取得视图项的数量
@Override
public int getCount() {
return mData.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0==arg1;
}
//销毁视图项
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
//从父控件中移除子控件
container.removeView((View)object);
}
//初始化视图项
@Override
public Object instantiateItem(ViewGroup container, int position) {
//容器ViewPager--它是ViewGroup的子类
container.addView(mData.get(position));
return mData.get(position);
}
}

View File

@@ -0,0 +1,989 @@
package com.chwl.app;
import static com.chwl.core.channel_page.model.ChannelPageModel.KEY_FLAG_VALID_CHANNEL_PAGE;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProvider;
import com.chwl.app.application.App;
import com.chwl.app.application.IReportConstants;
import com.chwl.app.application.ReportManager;
import com.chwl.app.avroom.activity.AVRoomActivity;
import com.chwl.app.base.BaseActivity;
import com.chwl.app.base.BaseMvpActivity;
import com.chwl.app.base.GlobalViewModelOwner;
import com.chwl.app.common.widget.CircleImageView;
import com.chwl.app.common.widget.dialog.DialogManager;
import com.chwl.app.community.square.SquareFragment;
import com.chwl.app.game.core.GameStateAbility;
import com.chwl.app.game.data.GameModel2;
import com.chwl.app.game.ui.game.GameActivity;
import com.chwl.app.game.ui.game.GameIntent;
import com.chwl.app.game.ui.home.GameHomeFragment;
import com.chwl.app.home.HomeViewModel;
import com.chwl.app.home.dialog.NewUserHelloDialog;
import com.chwl.app.home.dialog.ProtocolUpdateDialog;
import com.chwl.app.home.fragment.ContactsListFragment;
import com.chwl.app.home.fragment.HomeFragment;
import com.chwl.app.home.fragment.MeFragment;
import com.chwl.app.home.presenter.MainPresenter;
import com.chwl.app.home.view.IMainView;
import com.chwl.app.home.widget.AnchorCardView;
import com.chwl.app.module.Extras;
import com.chwl.app.module_hall.secretcode.PwdCodeMgr;
import com.chwl.app.service.DaemonService;
import com.chwl.app.support.PreloadResourceViewModel;
import com.chwl.app.ui.im.ImInitHelper;
import com.chwl.app.ui.im.avtivity.NimP2PMessageActivity;
import com.chwl.app.ui.login.BindPhoneActivity;
import com.chwl.app.ui.login.LoginPasswordActivity;
import com.chwl.app.ui.login.fragment.AddUserInfoFragment;
import com.chwl.app.ui.patriarch.help.LimitEnterRoomHelper;
import com.chwl.app.ui.patriarch.help.PmDialogShowMrg;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.app.ui.utils.ImageLoadUtilsV2;
import com.chwl.app.ui.webview.CommonWebViewActivity;
import com.chwl.app.ui.widget.LivingIconView;
import com.chwl.app.ui.widget.MainTabLayout;
import com.chwl.app.utils.CleanLeakUtils;
import com.chwl.app.utils.HomeUIManager;
import com.chwl.app.utils.LoginSuccessManager;
import com.chwl.app.utils.PushMessageHandler;
import com.chwl.app.utils.ResourceManager;
import com.chwl.app.utils.ShareManager;
import com.chwl.core.Constants;
import com.chwl.core.DemoCache;
import com.chwl.core.UriProvider;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.auth.event.KickOutEvent;
import com.chwl.core.auth.event.LoginEvent;
import com.chwl.core.auth.event.LogoutEvent;
import com.chwl.core.channel_page.model.ChannelPageModel;
import com.chwl.core.community.event.SquareTaskEvent;
import com.chwl.core.community.event.UnReadCountEvent;
import com.chwl.core.home.bean.BannerInfo;
import com.chwl.core.home.bean.MainTabInfo;
import com.chwl.core.home.bean.MainTabType;
import com.chwl.core.home.event.VisitorUnreadCountEvent;
import com.chwl.core.home.model.GameHomeModel;
import com.chwl.core.home.model.HomeModel;
import com.chwl.core.initial.InitialModel;
import com.chwl.core.linked.LinkedModel;
import com.chwl.core.linked.bean.LinkedInfo;
import com.chwl.core.manager.AudioEngineManager;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.manager.IMBroadcastManager;
import com.chwl.core.manager.IMMessageManager;
import com.chwl.core.manager.RoomEvent;
import com.chwl.core.patriarch.event.CloseMinRoomEvent;
import com.chwl.core.patriarch.event.ImPushMsgPmLimitTimeEvent;
import com.chwl.core.patriarch.event.PmDismissAllLimitDialogEvent;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.core.settings.SettingsModel;
import com.chwl.core.user.UserModel;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.core.user.event.LoadLoginUserInfoEvent;
import com.chwl.core.user.event.LoginUserInfoUpdateEvent;
import com.chwl.core.user.event.NeedBindPhoneEvent;
import com.chwl.core.user.event.NeedCompleteInfoEvent;
import com.chwl.core.utils.SharedPreferenceUtils;
import com.chwl.core.utils.StringFormatUtils;
import com.chwl.core.utils.WLog;
import com.chwl.core.utils.myutil.MyUtil;
import com.chwl.library.base.factory.CreatePresenter;
import com.chwl.library.common.util.OtherExtKt;
import com.chwl.library.threadmgr.ThreadPoolManager;
import com.chwl.library.utils.JavaUtil;
import com.chwl.library.utils.ResUtil;
import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nim.uikit.common.util.string.StringUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomKickOutEvent;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.team.TeamService;
import com.netease.nimlib.sdk.team.constant.TeamMessageNotifyTypeEnum;
import com.netease.nimlib.sdk.team.model.Team;
import com.orhanobut.logger.Logger;
import com.trello.rxlifecycle3.android.ActivityEvent;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.List;
/**
* @author Administrator
*/
@CreatePresenter(MainPresenter.class)
public class MainActivity extends BaseMvpActivity<IMainView, MainPresenter>
implements MainTabLayout.OnTabClickListener, IMainView, View.OnClickListener {
public static final String MSG_TAB = "msgTab";
private static final String TAG = "MainActivity";
private static final String EXTRA_APP_QUIT = "APP_QUIT";
private final SparseArray<Fragment> fragmentArray = new SparseArray<>();
private View avatarLayout;
private CircleImageView avatarImage;
private LivingIconView userLivingView;
private MainTabLayout mMainTabLayout;
private AnchorCardView anchorCardView;
private View viewClose;
private int mCurrentTabType = MainTabType.TAB_TYPE_HOME;
/**
* 房间最小化动画换成属性动画原先的补间动画影响了activity的生命周期
*/
private ObjectAnimator roomMinAnim;
/**
* 管理限制进房
*/
private LimitEnterRoomHelper limitEnterRoomHelper;
private HomeViewModel homeViewModel;
private boolean mResumed = false;
@Nullable
private Fragment tempFragment = null;
private DialogManager resumeGameDialogManager;
private PreloadResourceViewModel mPreLoadViewModel;
@Nullable
private Runnable touchRunnable;
{
fragmentArray.put(MainTabType.TAB_TYPE_HOME, new HomeFragment());
fragmentArray.put(MainTabType.TAB_TYPE_GAME, new GameHomeFragment());
fragmentArray.put(MainTabType.TAB_TYPE_SQUARE, new SquareFragment());
fragmentArray.put(MainTabType.TAB_TYPE_MSG, new ContactsListFragment());
fragmentArray.put(MainTabType.TAB_TYPE_ME, new MeFragment());
}
public static void start(Context context) {
start(context, null);
}
public static void start(Context context, Intent extras) {
Intent intent = new Intent();
intent.setClass(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
if (extras != null) {
intent.putExtras(extras);
}
context.startActivity(intent);
}
/**
* @return true 如果处理了跳转
*/
public static boolean handleLinkedJump(BaseActivity context) {
LinkedInfo linkedInfo = LinkedModel.get().getLinkedInfo();
LinkedModel.get().setLinkedInfo(null);
if (linkedInfo != null && linkedInfo.getType() != null && !linkedInfo.getType().equals("null")) {
LogUtil.print(ResUtil.getString(R.string.yizhuan_erban_mainactivity_01));
// 跳转
if (!StringUtil.isEmpty(linkedInfo.getRoomUid()) && linkedInfo.getType().equals("2")) {
AVRoomActivity.start(context, Long.parseLong(linkedInfo.getRoomUid()));
} else if (!TextUtils.isEmpty(linkedInfo.getUrl()) && linkedInfo.getType().equals("3")) {
CommonWebViewActivity.start(context, UriProvider.getLinkUrl(linkedInfo.getUrl()));
} else if (linkedInfo.getType().equals("7") && !TextUtils.isEmpty(linkedInfo.getUid())) {
NimP2PMessageActivity.start(context, linkedInfo.getUid());
} else {
return false;
}
} else {
//执行新分享逻辑
ShareManager.INSTANCE.shareRoomGet(context,s -> {
return null;
});
return false;
}
return true;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(Constants.KEY_MAIN_POSITION, mCurrentTabType);
}
@Override
protected void onRestoreInstanceState(@NotNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mCurrentTabType = savedInstanceState.getInt(Constants.KEY_MAIN_POSITION);
}
@SuppressLint("CheckResult")
@Override
protected void onCreate(Bundle savedInstanceState) {
OtherExtKt.doLog("MainActivity onCreate()");
super.onCreate(savedInstanceState);
ViewModelProvider viewModelProvider = new ViewModelProvider(this);
homeViewModel = viewModelProvider.get(HomeViewModel.class);
NimMiddleActivity.firstEnter = false;
if (savedInstanceState != null) {
mCurrentTabType = savedInstanceState.getInt(Constants.KEY_MAIN_POSITION);
}
setContentView(R.layout.activity_main);
//自动登录
AuthModel.get().autoLogin()
.doOnError(throwable -> onNeedLogin())
.subscribe();
initView();
List<MainTabInfo> homeTabIcons = HomeUIManager.INSTANCE.getHomeTabIcons();
if (homeTabIcons != null && !homeTabIcons.isEmpty()) {
mMainTabLayout.setMainTabInfoList(homeTabIcons);
} else {
List<MainTabInfo> mainTabInfo = InitialModel.get().getMainTabInfosLiveData().getValue();
if (mainTabInfo != null) {
mMainTabLayout.setMainTabInfoList(mainTabInfo);
}
}
initMaterialView();
onParseIntent();
updateDatas();
updateRoomState();
ImInitHelper.get().init();
EventBus.getDefault().register(this);
otherModelInit();
homeViewModel.getAnchorInfoLiveData().observe(this, anchorInfo -> {
if (anchorInfo != null) {
anchorCardView.setAnchorInfo(anchorInfo);
DemoCache.saveAnchorCardView(2);
}
});
checkResumeGame();
WLog.INSTANCE.init(context,"logFile.txt");
HomeUIManager.INSTANCE.setHomeTabBg(findViewById(R.id.main_tab_layout_bg));
ResourceManager.INSTANCE.initResource();
}
@Override
protected void onNewIntent(Intent intent) {
OtherExtKt.doLog("MainActivity onNewIntent()");
super.onNewIntent(intent);
setIntent(intent);
//这里退出登录实际上mainActivity是没有销毁的当从linkme 调起来时候这里需要检查一下登录状态。
if (TextUtils.isEmpty(AuthModel.get().getTicket())) {
onNeedLogin();
return;
}
onParseIntent();
updateDatas();
InitialModel.get().regionCheck();
}
private void otherModelInit() {
PwdCodeMgr.get().onCreateInit();
//初始化线程池
ThreadPoolManager.instance().init();
IMBroadcastManager.get().onCreate();
ImageLoadUtilsV2.init(context);
SettingsModel.get().checkSysAccount();
initPreloadResource();
}
@SuppressLint("CheckResult")
private void checkResumeGame() {
GameModel2.INSTANCE.getResumeGameRoomInfo().compose(bindToLifecycle())
.doOnSuccess(gameRoomInfo -> {
if (gameRoomInfo != null && gameRoomInfo.getData() != null) {
Integer state = gameRoomInfo.getData().getMatchStatus();
if (state != null && (state == GameStateAbility.STATE_MATCH_SUCCESS || state == GameStateAbility.STATE_MATCHING)) {
if (resumeGameDialogManager == null) {
resumeGameDialogManager = new DialogManager(this);
}
resumeGameDialogManager.showOkCancelDialog(getString(R.string.resume_game_tips), getString(R.string.join_organization_ok), getString(R.string.join_organization_no), false, new DialogManager.OkCancelDialogListener() {
@Override
public void onOk() {
long gameId = JavaUtil.str2long(gameRoomInfo.getData().getMgId());
int gameMode = 0;
GameActivity.Companion.start(context, new GameIntent(gameId, gameMode));
}
@Override
public void onCancel() {
DialogManager.OkCancelDialogListener.super.onCancel();
Long roomId = gameRoomInfo.getRoomId();
if (roomId != null) {
GameModel2.INSTANCE.closeGameRx(roomId).compose(bindToLifecycle()).subscribe(s -> {
}, throwable -> {
});
}
}
});
}
}
}).doOnError(e->{
}).subscribe();
}
private void initPreloadResource() {
mPreLoadViewModel = new ViewModelProvider(
GlobalViewModelOwner.Companion.getInstance()
).get(PreloadResourceViewModel.class);
mPreLoadViewModel.start(context);
}
@Override
protected void onReceiveChatRoomEvent(RoomEvent roomEvent) {
super.onReceiveChatRoomEvent(roomEvent);
if (roomEvent == null || roomEvent.getEvent() == RoomEvent.NONE) return;
int event = roomEvent.getEvent();
if (event == RoomEvent.ENTER_ROOM) {
onEnter(AvRoomDataManager.get().mCurrentRoomInfo);
} else if (event == RoomEvent.KICK_OUT_ROOM) {
ChatRoomKickOutEvent reason = roomEvent.getReason();
if (reason == null) return;
//加入黑名单,踢出房间回调
ChatRoomKickOutEvent.ChatRoomKickOutReason reasonReason = reason.getReason();
if (reasonReason == ChatRoomKickOutEvent.ChatRoomKickOutReason.BE_BLACKLISTED
|| reasonReason == ChatRoomKickOutEvent.ChatRoomKickOutReason.KICK_OUT_BY_MANAGER
|| reasonReason == ChatRoomKickOutEvent.ChatRoomKickOutReason.KICK_OUT_BY_CONFLICT_LOGIN
|| reasonReason == ChatRoomKickOutEvent.ChatRoomKickOutReason.CHAT_ROOM_INVALID) {
exitRoom(AvRoomDataManager.get().mCurrentRoomInfo);
}
} else if (event == RoomEvent.ROOM_EXIT) {
exitRoom(roomEvent.getRoomInfo());
} else if (event == RoomEvent.ROOM_CHAT_RECONNECTION) {
updateRoomState();
} else if (event == RoomEvent.MY_SELF_KICK_OUT_ROOM_BY_S_ADMIN) {
AvRoomDataManager.get().addCurrentRoomLimitEnter();
toast(R.string.kick_out_room_by_s_admin);
getMvpPresenter().exitRoom();
}
}
private void closeOpenRoomAnimation() {
stopRoomMinAnim();
avatarLayout.setVisibility(View.GONE);
}
@Override
protected void onResume() {
super.onResume();
mResumed = true;
if (avatarLayout.getVisibility() == View.VISIBLE) {
userLivingView.start();
}
//这里是为了处理APP后台运行的情况下点击分享房间等LinkedMe链接的情况
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
if (userInfo != null) {
handleLinkedJump(this);
}
}
@Override
protected void onPause() {
super.onPause();
mResumed = false;
if (avatarLayout.getVisibility() == View.VISIBLE) {
userLivingView.stop();
}
mMainTabLayout.removeCallbacks(touchRunnable);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (touchRunnable == null) return super.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mMainTabLayout.removeCallbacks(touchRunnable);
break;
case MotionEvent.ACTION_UP:
mMainTabLayout.postDelayed(touchRunnable, 5000);
break;
}
return super.onTouchEvent(event);
}
private void initView() {
mMainTabLayout = findViewById(R.id.main_tab_layout);
avatarLayout = findViewById(R.id.avatar_image_layout);
viewClose = findViewById(R.id.view_close);
avatarImage = findViewById(R.id.avatar_image);
userLivingView = findViewById(R.id.liv_user);
userLivingView.setColor(Color.WHITE);
mMainTabLayout.setOnTabClickListener(this);
anchorCardView = findViewById(R.id.vs_anchor_card);
mMainTabLayout.setDefaultTabType(mCurrentTabType);
MyUtil.INSTANCE.initAppWidth(findViewById(R.id.rootWidth));
}
private void updateDatas() {
handleNimIntent();
}
private void onParseIntent() {
Intent intent = getIntent();
if (intent.hasExtra(EXTRA_APP_QUIT)) {
onLogout();
} else if (intent.hasExtra(Extras.EXTRA_JUMP_P2P)) {
Intent data = intent.getParcelableExtra(Extras.EXTRA_DATA);
String account = data.getStringExtra(Extras.EXTRA_ACCOUNT);
if (!TextUtils.isEmpty(account)) {
NimP2PMessageActivity.start(this, account);
}
} else if (intent.hasExtra(MSG_TAB) && intent.getBooleanExtra(MSG_TAB, false)) {
if (mMainTabLayout != null) {
mMainTabLayout.setDefaultTabType(MainTabType.TAB_TYPE_MSG);
}
}
}
private void initMaterialView() {
avatarLayout.setVisibility(View.GONE);
avatarImage.setOnClickListener(this);
viewClose.setOnClickListener(this);
}
@Override
protected void onDestroy() {
OtherExtKt.doLog("MainActivity onDestroy()");
CleanLeakUtils.fixInputMethodManagerLeak(MainActivity.this);
if (mPreLoadViewModel != null) {
mPreLoadViewModel.stopPreLoad();
}
super.onDestroy();
if (resumeGameDialogManager != null) {
resumeGameDialogManager.dismissDialog();
}
ImInitHelper.get().unInit();
EventBus.getDefault().unregister(this);
stopRoomMinAnim();
if (limitEnterRoomHelper != null) {
limitEnterRoomHelper.release();
}
IMBroadcastManager.get().onDestroy();
}
/**
* 双击返回键退出
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
/**
* 防止华为机型未加入白名单时按返回键回到桌面再锁屏后几秒钟进程被杀
*/
try {
Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
launcherIntent.addCategory(Intent.CATEGORY_HOME);
startActivity(launcherIntent);
} catch (Throwable e) {
e.printStackTrace();
}
try {
moveTaskToBack(false);
} catch (Exception e) {
return super.onKeyDown(keyCode, event);
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
try {
moveTaskToBack(false);
} catch (Exception e) {
e.printStackTrace();
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onLoginEvent(LoginEvent event) {
onLogin(AuthModel.get().getCurrentUid());
// UserModel.get().getUserInfoDetailCache(AuthModel.get().getCurrentUid()).subscribe();
}
/**
* 检查是否绑定手机
*/
private void checkBindPhone() {
BindPhoneActivity.start(context);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onLogoutEvent(LogoutEvent event) {
PwdCodeMgr.get().onLogout();
onLogout();
}
@SuppressLint("CheckResult")
public void onLogin(long uid) {
OtherExtKt.doLogW("onLogin Success ~~~~");
OtherExtKt.doLogW("onLogin");
int unreadCount = IMMessageManager.get().queryUnreadMsg();
mMainTabLayout.setMsgNum(unreadCount);
openCommunityNotice();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onLoadLoginUserInfoEvent(LoadLoginUserInfoEvent event) {
OtherExtKt.doLog("消息时间 接收到 LoadLoginUserInfoEvent 消息");
UserModel.get().updateCurrentUserInfo();
firstLoadedUserInfo();
InitialModel.get().regionCheck();
LoginSuccessManager.Companion.getInstance().onLoadLoginUserInfoEvent(this);
}
public void onLogout() {
Logger.e(TAG, "onLogout Success ~~~~");
getMvpPresenter().exitRoom();
LoginPasswordActivity.start(MainActivity.this);
PmDialogShowMrg.get().onLogout();
finish();
}
public void onNeedLogin() {
NimMiddleActivity.openCommunity = false;
LoginPasswordActivity.start(MainActivity.this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onKickedOutEvent(KickOutEvent event) {
toast(getString(R.string.you_have_been_kicked_offline));
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onReceiveRecentContactChanged(List<RecentContact> imMessages) {
int countIgnore = 0;
for (RecentContact recentContact : imMessages) {
if (recentContact.getSessionType() == SessionTypeEnum.Team) {
Team team = NIMClient.getService(TeamService.class).queryTeamBlock(recentContact.getContactId());
if (team != null && team.getMessageNotifyType() == TeamMessageNotifyTypeEnum.Mute) {
countIgnore += recentContact.getUnreadCount();
}
}
}
int unreadCount = IMMessageManager.get().queryUnreadMsg() + countIgnore;
mMainTabLayout.setMsgNum(unreadCount);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onNeedCompleteInfo(NeedCompleteInfoEvent event) {
getDialogManager().dismissDialog();
UIHelper.showAddInfoAct(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onLoginUserInfoUpdateEvent(LoginUserInfoUpdateEvent event) {
int unreadCount = IMMessageManager.get().queryUnreadMsg();
mMainTabLayout.setMsgNum(unreadCount);
}
@SuppressLint("CheckResult")
private void updateRoomState() {
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo != null) {
displayAvatarLayout(roomInfo.getAvatar(), roomInfo.getTitle(), roomInfo.getUid());
}
}
private void startRoomMinAnim() {
roomMinAnim = ObjectAnimator.ofFloat(avatarImage, "rotation", 0f, 360f);
roomMinAnim.setDuration(10000);
roomMinAnim.setRepeatCount(-1);
roomMinAnim.setInterpolator(new LinearInterpolator());
roomMinAnim.start();
}
private void stopRoomMinAnim() {
if (roomMinAnim != null) {
roomMinAnim.cancel();
roomMinAnim = null;
}
}
@SuppressLint("SetTextI18n")
private void displayAvatarLayout(String avatar, String nickName, long uid) {
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo != null) {
avatarLayout.clearAnimation();
avatarLayout.setVisibility(View.VISIBLE);
userLivingView.start();
stopRoomMinAnim();
startRoomMinAnim();
ImageLoadUtils.loadAvatar(MainActivity.this, avatar, avatarImage);
}
}
public void onEnter(RoomInfo roomInfo) {
updateRoomState();
DaemonService.start(this, roomInfo);
}
@SuppressLint("RestrictedApi")
@Override
public void onTabClick(int tabType) {
Fragment showFragment = fragmentArray.get(tabType);
if (showFragment == tempFragment) return;
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (!showFragment.isAdded()) {
transaction.add(R.id.main_fragment, showFragment, null);
}
transaction.show(showFragment);
if (tempFragment != null) {
transaction.hide(tempFragment);
}
tempFragment = showFragment;
if (!isDestroyed()) {
transaction.commitNowAllowingStateLoss();
}
mCurrentTabType = tabType;
//每次点击我的都更新当前用户信息
if (mCurrentTabType == MainTabType.TAB_TYPE_ME) {
UserModel.get().updateCurrentUserInfo().subscribe();
}
switch (tabType) {
case MainTabType.TAB_TYPE_HOME:
reportTabClick(IReportConstants.ELEVEN);
break;
case MainTabType.TAB_TYPE_MSG:
reportTabClick(IReportConstants.THIRTEEN);
break;
case MainTabType.TAB_TYPE_ME:
reportTabClick(IReportConstants.FOURTEEN);
break;
}
}
/**
* 导航栏tab板块点击
*
* @param type
*/
private void reportTabClick(int type) {
//登录页展示时
HashMap<String, Object> map = new HashMap<>(3);
map.put(IReportConstants.HOMEPAGE_TYPE, type);
map.put(IReportConstants.MODULE, IReportConstants.MOLISTAR_HOMEPAGE);
ReportManager.get().reportEvent(IReportConstants.MODULE_HOMEPAGE_CLICK, map);
}
@Override
public void exitRoom(RoomInfo roomInfo) {
AudioEngineManager.get().setNotRecord(false);
closeOpenRoomAnimation();
DaemonService.stop(MainActivity.this);
}
/**
* 第一次加载到用户信息
*/
@SuppressLint("CheckResult")
private void firstLoadedUserInfo() {
//青少年弹窗处理
PmDialogShowMrg.get().handle(new WeakReference<>(this));
handleChannelPageInfo();
checkProtocolUpdate();
// 互动消息未读数量
HomeModel.INSTANCE.getUnreadCount(AuthModel.get().getCurrentUid())
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe((integer, throwable) -> {
if (integer != null) {
EventBus.getDefault().post(new UnReadCountEvent(integer));
}
});
// checkShowAnchorCardView();
}
@SuppressLint("CheckResult")
private void checkProtocolUpdate() {
UserModel.get()
.getProtocolInfo()
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(protocolInfo -> {
float version = (float) SharedPreferenceUtils.get(ProtocolUpdateDialog.SP_KEY, 0f);
//第一次打开APP不弹,因为闪屏页已经弹了!
if (version == 0f) {
SharedPreferenceUtils.put(ProtocolUpdateDialog.SP_KEY, protocolInfo.getVer());
} else if (version < protocolInfo.getVer()) {
new ProtocolUpdateDialog(MainActivity.this, protocolInfo).show();
}
});
}
/**
* 跳转优先级 闪屏→linkedMe→邀请码→新用户打招呼引导→渠道指定房间
*/
@SuppressLint("CheckResult")
private void handleChannelPageInfo() {
if (handleSplashJump()) return;
if (handleLinkedJump(this)) return;
//渠道落地页和邀请码跳转只需要完善资料后处理一次
String spKey = KEY_FLAG_VALID_CHANNEL_PAGE + AuthModel.get().getCurrentUid();
if ((boolean) SharedPreferenceUtils.get(spKey, true)) {
SharedPreferenceUtils.put(spKey, false);
checkInviteUserInRoom();
}
}
/**
* 检查邀请码跳转
*/
@SuppressLint("CheckResult")
private void checkInviteUserInRoom() {
if (!TextUtils.isEmpty(AddUserInfoFragment.INVITE_USER_CODE)) {
ChannelPageModel.get().checkInviteUserInRoom(AddUserInfoFragment.INVITE_USER_CODE)
.subscribe(inviteUserInfo -> {
if (inviteUserInfo.isInRoom()) {
if (inviteUserInfo.getFromType() == 0) {
AVRoomActivity.start(context, inviteUserInfo.getRoomUid());
} else {
AVRoomActivity.startForFromType(context,
inviteUserInfo.getRoomUid(),
inviteUserInfo.getFromType(),
inviteUserInfo.getInviteNick(),
String.valueOf(inviteUserInfo.getInviteUid()));
}
} else {
checkNewUserInRoom();
}
}, throwable -> checkNewUserInRoom());
AddUserInfoFragment.INVITE_USER_CODE = "";
} else {
checkNewUserInRoom();
}
}
@SuppressLint("CheckResult")
private void checkNewUserInRoom() {
ChannelPageModel.get().checkNewUserInRoom()
.subscribe(newUserHelloInfo -> {
if (newUserHelloInfo.getSayHello()) {
NewUserHelloDialog.Companion.newInstance(newUserHelloInfo).show(context);
} else {
checkChannelPageInRoom();
}
}, throwable -> checkChannelPageInRoom());
}
/**
* 处理渠道落地页
*/
@SuppressLint("CheckResult")
private void checkChannelPageInRoom() {
GameHomeModel.get().getRoomShortcut()
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(uid -> {
if (StringFormatUtils.toLong(uid) != 0) {
AVRoomActivity.start(context, StringFormatUtils.toLong(uid));
}
},
Throwable::printStackTrace);
}
/**
* @return true 如果处理了跳转
*/
private boolean handleSplashJump() {
OtherExtKt.doLog("闪屏页 -> handleSplashJump 处理 闪屏页跳转");
if (getIntent().hasExtra("url") && getIntent().hasExtra("type")) {
LogUtil.print(getString(R.string.clicked_the_splash_screen));
//如果没有渠道页,就按原来的逻辑即可
int type = getIntent().getIntExtra("type", 0);
String url = getIntent().getStringExtra("url");
if (type == BannerInfo.SKIP_TYP_H5 || type == BannerInfo.SKIP_TYP_H5_CP || type == BannerInfo.SKIP_TYP_H5_WEE_STAR || type == BannerInfo.SKIP_TYP_H5_CUSTOM) {
Intent intent = new Intent(context, CommonWebViewActivity.class);
intent.putExtra("url", url);
startActivity(intent);
} else if (type == BannerInfo.SKIP_TYP_CHAT_ROOM) {
AVRoomActivity.start(context, Long.parseLong(url));
} else {
return false;
}
getIntent().putExtra("type",0);
return true;
}
return false;
}
public LimitEnterRoomHelper getLimitEnterRoomHelper() {
if (limitEnterRoomHelper == null) {
limitEnterRoomHelper = new LimitEnterRoomHelper();
}
return limitEnterRoomHelper;
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onImPushMsgPmLimitTimeEvent(ImPushMsgPmLimitTimeEvent event) {
//先判断Avroom存不存在存在的话则不处理avroom会处理
Activity reference = App.gStack.getAvRoomActivity();
if (reference != null) {
return;
}
getLimitEnterRoomHelper().handleThisContext(this, event.getData(), true, this::handlePmExitRoom);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onPmDismissAllLimitDialogEvent(PmDismissAllLimitDialogEvent event) {
if (limitEnterRoomHelper != null) {
limitEnterRoomHelper.dismissDialog();
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void SquarePublish(SquareTaskEvent event) {
}
private void handlePmExitRoom() {
if (AvRoomDataManager.get().mCurrentRoomInfo != null) {
closeOpenRoomAnimation();
getMvpPresenter().exitRoom();
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onCloseMinRoomEvent(CloseMinRoomEvent event) {
//如果房间存在,就关闭
if (AvRoomDataManager.get().mCurrentRoomInfo != null) {
handlePmExitRoom();
}
}
/**
* 处理开房限制时长
*/
public void handleOpenRoomWhenPmLimit(String error) {
getLimitEnterRoomHelper().handleThisContext(this, error, false, this::handlePmExitRoom);
}
/**
* 云信通知栏跳转的处理
*/
private void handleNimIntent() {
openCommunityNotice();
Intent intent = getIntent();
if (intent == null) {
return;
}
boolean isNimPush = intent.getBooleanExtra(NimMiddleActivity.EXTRA_IS_NIM_PUSH, false);
if (isNimPush && mMainTabLayout != null) {
mMainTabLayout.setDefaultTabType(MainTabType.TAB_TYPE_MSG);
}
}
/**
* 点击互动通知通知栏,重启进程打开互动通知页
*/
private void openCommunityNotice() {
if (NimMiddleActivity.delayOpenCommunity) {
return;
}
if (NimMiddleActivity.openCommunity) {
NimMiddleActivity.openCommunity = false;
if (NimMiddleActivity.skipType == 0) return;
new Handler().postDelayed(() -> {
if (NimMiddleActivity.skipType == PushMessageHandler.PAYLOAD_SKIPTYPE_INVITE_FANS &&
NimMiddleActivity.payloadUid > 0) {
AVRoomActivity.start(MainActivity.this, NimMiddleActivity.payloadUid);
} else if (NimMiddleActivity.skipType == PushMessageHandler.PAYLOAD_SKIPTYPE_PRIVATE_MSG &&
NimMiddleActivity.payloadUid > 0) {
NimP2PMessageActivity.start(MainActivity.this, NimMiddleActivity.payloadUid + "");
} else if (NimMiddleActivity.skipType == PushMessageHandler.PAYLOAD_SKIPTYPE_H5 &&
!TextUtils.isEmpty(NimMiddleActivity.payloadUrl)) {
CommonWebViewActivity.start(MainActivity.this, NimMiddleActivity.payloadUrl);
}
}, 2000);
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onNeedBindPhoneEvent(NeedBindPhoneEvent event) {
// checkBindPhone();
}
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onVisitorUnreadCountEvent(VisitorUnreadCountEvent event) {
if (mMainTabLayout != null) {
mMainTabLayout.setUnreadVisitorCount(event.getVisitNum());
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.avatar_image:
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo != null) {
AVRoomActivity.start(MainActivity.this, roomInfo.getUid());
} else {
toast(getString(R.string.room_information_is_empty));
}
break;
case R.id.view_close:
MainActivity.this.getMvpPresenter().exitRoom();
break;
}
}
@Override
protected boolean needSteepStateBar() {
return true;
}
@Override
protected void setStatusBar() {
super.setStatusBar();
StatusBarUtil.transparencyBar(this);
StatusBarUtil.StatusBarLightMode(this);
}
}

View File

@@ -0,0 +1,4 @@
package com.chwl.app
interface MainTabContentView {
}

View File

@@ -0,0 +1,196 @@
package com.chwl.app;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.coorchice.library.utils.LogUtils;
import com.netease.nimlib.sdk.NimIntent;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.chwl.app.avroom.activity.AVRoomActivity;
import com.chwl.app.base.BaseActivity;
import com.chwl.app.ui.im.avtivity.NimP2PMessageActivity;
import com.chwl.app.ui.webview.CommonWebViewActivity;
import com.chwl.app.utils.PushMessageHandler;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.im.custom.bean.CustomAttachment;
import com.chwl.core.im.custom.bean.OpenRoomNotiAttachment;
import com.chwl.core.im.custom.bean.OpenSignInAttachment;
import com.chwl.core.im.custom.bean.RedPackageAttachment;
import com.chwl.core.im.custom.bean.RoomInviteFansAttachment;
import com.chwl.library.utils.UIUtils;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
/**
* Created by chenran on 2017/8/5.
*/
public class NimMiddleActivity extends BaseActivity {
private static final String TAG = "mix_push";
/**
* 通知栏启动Main后自动跳转到 msg tab
*/
public final static String EXTRA_IS_NIM_PUSH = "is_nim_push";
public static String EXTRA_FROM_NOTIFICATION = "from_notification";
public static final String INTENT_ACTION_AVCHAT = "INTENT_ACTION_AVCHAT";
public static boolean firstEnter = true; // 是否首次进入
/**
* 用于点击动态通知栏跳转到CommunityNoticeAct
* openCommunity:打开CommunityNoticeAct
* <p>
* delayOpenCommunity:控制CommunityNoticeAct打开时机
* 原因部分机型可以直接打开NimMiddleActivity; 可以直接调用MainActivity.openCommunityNotice启动CommunityNoticeAct;
* 部分机型魅蓝Note5(android7.0,Flyme7.3.0.0A)会先打开Splash再打开NimMiddleActivity; 会导致Splash启动MainActivity.onNewIntent;
* 所以添加delayOpenCommunity字段让CommunityNoticeAct在MainActivity.onNewIntent再启动
*/
public static boolean openCommunity = false;
public static boolean delayOpenCommunity = false;
public static long payloadUid;
public static int skipType;
public static String payloadUrl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "NimMiddleActivity");
Intent intent = getIntent();
if (intent != null) {
try {
Map<String, String> payload = (Map<String, String>) intent.getSerializableExtra(PushMessageHandler.PAYLOAD_DATA);
if (intent.hasExtra(NimIntent.EXTRA_NOTIFY_CONTENT)) {
parseNotifyIntent(intent);
} else if (intent.hasExtra(EXTRA_FROM_NOTIFICATION) || intent.hasExtra(INTENT_ACTION_AVCHAT)) {
parseNormalIntent(intent);
} else if (payload != null) {
parsePayloadData(payload);
} else {
parseNormalIntent(null);
}
} catch (Exception e) {
LogUtils.e("NimMiddleActivity:" + e);
}
}
}
/**
* 推送通知栏点击
*
* @param intent
*/
private void parseNotifyIntent(Intent intent) {
if (intent == null) {
return;
}
intent.putExtra(EXTRA_IS_NIM_PUSH, true);
MainActivity.start(NimMiddleActivity.this, intent);
ArrayList<IMMessage> messages = (ArrayList<IMMessage>) intent.getSerializableExtra(NimIntent.EXTRA_NOTIFY_CONTENT);
if (messages != null && messages.size() > 0) {
IMMessage imMessage = messages.get(messages.size() - 1);
LogUtils.i("getMsgType:" + imMessage.getMsgType());
if (imMessage.getMsgType() == MsgTypeEnum.custom) {
CustomAttachment attachment = (CustomAttachment) imMessage.getAttachment();
if (attachment != null) {
if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_HEADER_TYPE_OPEN_ROOM_NOTI) {
OpenRoomNotiAttachment noticeAttachment = (OpenRoomNotiAttachment) attachment;
if (noticeAttachment.getUid() > 0) {
AVRoomActivity.start(this, noticeAttachment.getUid());
}
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_RED_PACKAGE) {
if (attachment.getSecond() == CustomAttachment.CUSTOM_MSG_SUB_RED_PACKAGE_RECEIVE_ALL_DIAMOND) {
RedPackageAttachment redPackageAttachment = (RedPackageAttachment) attachment;
AVRoomActivity.start(this, redPackageAttachment.getRedPackageNotifyInfo().getRoomUid());
}
} else if (attachment.getFirst() == CustomAttachment.CUSTOM_MSG_PUSH_NOTIFIFICATION) {
if (attachment.getSecond() == CustomAttachment.CUSTOM_MSG_SUB_PUSH_NOTIFICATION_IN_ROOM) {
RoomInviteFansAttachment noticeAttachment = (RoomInviteFansAttachment) attachment;
if (noticeAttachment.getRoomInviteFansInfo() == null) {
return;
}
AVRoomActivity.start(this, noticeAttachment.getRoomInviteFansInfo().getData().getData().getRoomUid());
}
} else {
NimP2PMessageActivity.start(this, imMessage.getFromAccount() + "");
}
}
} else if (imMessage.getMsgType() == MsgTypeEnum.notification) {
LogUtils.i("MsgTypeEnum.notification");
} else if (imMessage.getMsgType() == MsgTypeEnum.text) {
LogUtils.i("MsgTypeEnum.text");
NimP2PMessageActivity.start(this, imMessage.getFromAccount() + "");
}
}
finish();
}
private void parseNormalIntent(Intent intent) {
MainActivity.start(NimMiddleActivity.this, intent);
finish();
}
private void parsePayloadData(Map<String, String> payload) {
skipType = Integer.parseInt(Objects.requireNonNull(payload.get(PushMessageHandler.PAYLOAD_SKIPTYPE)));
String payloadData = payload.get(PushMessageHandler.PAYLOAD_DATA);
try {
long uid = 0;
if (skipType == PushMessageHandler.PAYLOAD_SKIPTYPE_H5) {
payloadUrl = payloadData;
} else {
JSONObject object = JSON.parseObject(payloadData);
uid = object.getLong("uid");
payloadUid = uid;
}
if (AuthModel.get().getCurrentUid() > 0) {
if (!firstEnter) {
LogUtils.e("rev pushMessage payload true:" + uid);
switch (skipType) {
case PushMessageHandler.PAYLOAD_SKIPTYPE_INVITE_FANS:
AVRoomActivity.start(this, uid);
finish();
break;
case PushMessageHandler.PAYLOAD_SKIPTYPE_H5:
CommonWebViewActivity.start(this, payloadData);
finish();
break;
case PushMessageHandler.PAYLOAD_SKIPTYPE_PRIVATE_MSG:
NimP2PMessageActivity.start(this, uid + "");
finish();
break;
default:
break;
}
} else {
openCommunity = true;
parseNormalIntent(null);
}
} else {
if (firstEnter) {
parseNormalIntent(null);
} else {
finish();
}
}
} catch (Exception ex) {
ex.printStackTrace();
if (firstEnter) {
parseNormalIntent(null);
} else {
finish();
}
}
}
}

View File

@@ -0,0 +1,136 @@
package com.chwl.app;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import com.chwl.app.audio.MyVoiceActivity;
import com.chwl.app.audio.RecordingVoiceActivity;
import com.chwl.app.audio.SoundSignatureActivity;
import com.chwl.app.ui.login.AddUserInfoActivity;
import com.chwl.app.ui.login.ModifyInfoActivity;
import com.chwl.app.ui.setting.SettingActivity;
import com.chwl.app.ui.user.activity.UserInfoActivity;
import com.chwl.app.ui.user.activity.UserInfoModifyActivity;
import com.chwl.app.ui.user.activity.UserModifyPhotosActivity;
import com.chwl.app.ui.webview.CommonWebViewActivity;
import com.chwl.core.UriProvider;
import com.chwl.core.user.bean.UserInfo;
/**
* *************************************************************************
*
* @Version 1.0
* @ClassName: UIHelper
* @Description: 应用程序UI工具包封装UI相关的一些操作
* @Author zhouxiangfeng
* @date 2013-8-6 下午1:39:11
* **************************************************************************
*/
public class UIHelper {
public static void showUserGuideAct(Context mContext) {
mContext.startActivity(new Intent(mContext, UserGuideActivity.class));
}
public static void showSettingAct(Context mContext) {
mContext.startActivity(new Intent(mContext, SettingActivity.class));
}
public static void showAddInfoAct(Context mContext) {
Intent intent = new Intent(mContext, AddUserInfoActivity.class);
mContext.startActivity(intent);
}
//修改用户资料
public static void showUserInfoModifyAct(Context mContext, long userId) {
Intent intent = new Intent(mContext, UserInfoModifyActivity.class);
intent.putExtra("userId", userId);
mContext.startActivity(intent);
}
//修改用户资料
public static void showUserInfoModifyAct(Activity mActivity, int requestCode, long userId) {
Intent intent = new Intent(mActivity, UserInfoModifyActivity.class);
intent.putExtra("userId", userId);
mActivity.startActivityForResult(intent, requestCode);
}
//侧边栏===>帮助
public static void showUsinghelp(Context mContext) {
CommonWebViewActivity.start(mContext, UriProvider.getHelp());
}
public static void showUserInfoAct(Context mContext, long userId) {
Intent intent = new Intent(mContext, UserInfoActivity.class);
intent.putExtra("userId", userId);
mContext.startActivity(intent);
}
public static void showRecordVoiceAct(Activity mActivity, int requestCode, long voiceId) {
Intent intent = new Intent(mActivity, RecordingVoiceActivity.class);
intent.putExtra(RecordingVoiceActivity.EXTRA_VOICE_ID, voiceId);
mActivity.startActivityForResult(intent, requestCode);
}
public static void showMyVoiceAct(Activity mActivity, int requestCode, String label) {
Intent intent = new Intent(mActivity, MyVoiceActivity.class);
mActivity.startActivityForResult(intent, requestCode);
}
public static void showSoundAct(Activity mActivity, int requestCode, String label, UserInfo.SoundBean audioCard) {
Intent intent = new Intent(mActivity, SoundSignatureActivity.class);
intent.putExtra(SoundSignatureActivity.AUDIO_BEAN, audioCard);
mActivity.startActivityForResult(intent, requestCode);
}
public static void showModifyInfoAct(Activity mActivity, int requestCode, String title) {
Intent intent = new Intent(mActivity, ModifyInfoActivity.class);
intent.putExtra("title", title);
mActivity.startActivityForResult(intent, requestCode);
}
public static void showModifyInfoAct(Activity mActivity, int requestCode, int modifyType) {
Intent intent = new Intent(mActivity, ModifyInfoActivity.class);
intent.putExtra(ModifyInfoActivity.MODIFY_TYPE, modifyType);
mActivity.startActivityForResult(intent, requestCode);
}
public static void showModifyPhotosAct(Activity mActivity, long userId) {
Intent intent = new Intent(mActivity, UserModifyPhotosActivity.class);
intent.putExtra("userId", userId);
mActivity.startActivity(intent);
}
public static void showMonsterResult(Context context, String monsterId) {
CommonWebViewActivity.start(context, UriProvider.IM_SERVER_URL +
"/molistar/modules/monster/index.html?monsterId=" + monsterId);
}
/**
* 跳转到举报页
*
* @param uid 被举报人
*/
public static void showReportPage(Context context, long uid, String source) {
//被举报人的id
String url = UriProvider.getUserReportUrl() + "?reportUid=" + uid + "&source=" + source;
CommonWebViewActivity.start(context, url);
}
/**
* 跳转推荐页h5
*/
public static void showRecommendPosH5(Context context) {
String cardUrl = UriProvider.JAVA_WEB_URL +
"/molistar/modules/recommend-card/index.html";
CommonWebViewActivity.start(context, cardUrl);
}
public static void openContactUs(Context context) {
CommonWebViewActivity.start(context, UriProvider.IM_SERVER_URL + "/molistar/modules/contact/contact.html");
}
}

View File

@@ -0,0 +1,70 @@
package com.chwl.app;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import androidx.viewpager.widget.ViewPager;
import com.chwl.app.base.BaseActivity;
import com.chwl.core.PreferencesUtils;
public class UserGuideActivity extends BaseActivity {
// private static final int[] images = {R.drawable.guide_one, R.drawable.guide_two, R.drawable.guide_three,};
protected static final String TAG = "UserGuide";
private ViewPager mViewPage;
private ImageView enterHome;
private GuideAdapter adapter;
public static void start(Context context) {
Intent intent = new Intent(context, UserGuideActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_guide);
initView();
}
private void initView() {
mViewPage = (ViewPager) findViewById(R.id.view_page);
enterHome = (ImageView) findViewById(R.id.enter_home);
adapter = new GuideAdapter(this);
mViewPage.setAdapter(new GuideAdapter(this));
mViewPage.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if(position == adapter.getCount()-1){
enterHome.setVisibility(View.VISIBLE);
}else{
enterHome.setVisibility(View.GONE);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
enterHome.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PreferencesUtils.setFristUser(false);
MainActivity.start(UserGuideActivity.this);
finish();
}
});
}
}

View File

@@ -0,0 +1,657 @@
package com.chwl.app.application;
import static com.chwl.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_HEADER_TYPE_OPEN_ROOM_NOTI;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Color;
import android.net.http.HttpResponseCache;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.multidex.MultiDex;
import com.alibaba.android.arouter.launcher.ARouter;
import com.bumptech.glide.request.target.ViewTarget;
import com.chwl.app.BuildConfig;
import com.chwl.app.NimMiddleActivity;
import com.chwl.app.R;
import com.chwl.app.common.app.ActivityStack;
import com.chwl.app.common.util.AppLifeCycleHelper;
import com.chwl.app.module_hall.HallDataManager;
import com.chwl.app.radish.wallet.RadishWalletManager;
import com.chwl.app.support.IMUserInfoProvider;
import com.chwl.app.utils.PushMessageHandler;
import com.chwl.core.Constants;
import com.chwl.core.DemoCache;
import com.chwl.core.UriProvider;
import com.chwl.core.XConstants;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.bean.response.ServiceResult;
import com.chwl.core.channel.ChannelModel;
import com.chwl.core.family.model.FamilyModel;
import com.chwl.core.gift.GiftModel;
import com.chwl.core.im.custom.bean.CustomAttachment;
import com.chwl.core.im.custom.bean.OpenSignInAttachment;
import com.chwl.core.initial.InitialModel;
import com.chwl.core.interceptor.NoParamsInterceptor;
import com.chwl.core.interceptor.ParamsInterceptor;
import com.chwl.core.interceptor.TimeSyncInterceptor;
import com.chwl.core.manager.IMMessageManager;
import com.chwl.core.manager.IMSystemMsgManager;
import com.chwl.core.market_verify.MarketVerifyModel;
import com.chwl.core.pay.PayModel;
import com.chwl.core.radish.RadishModel;
import com.chwl.core.radish.signin.bean.ImNotice;
import com.chwl.core.room.face.DynamicFaceModel;
import com.chwl.core.user.UserModel;
import com.chwl.core.user.event.NeedCompleteInfoEvent;
import com.chwl.core.utils.SharedPreferenceUtils;
import com.chwl.core.utils.net.ServerException;
import com.chwl.library.common.application.BaseApp;
import com.chwl.library.common.application.Env;
import com.chwl.library.common.file.FileHelper;
import com.chwl.library.common.util.OtherExtKt;
import com.chwl.library.error.CrashCat;
import com.chwl.library.language.LanguageHelper;
import com.chwl.library.net.rxnet.RxNet;
import com.chwl.library.net.rxnet.converter.GsonConverterPlugins;
import com.chwl.library.net.rxnet.utils.NetworkLatencyChecker;
import com.chwl.library.utils.AppMetaDataUtil;
import com.chwl.library.utils.DeviceUuidFactory;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.SingleToastUtil;
import com.chwl.library.utils.SystemUtils;
import com.chwl.library.utils.VersionUtil;
import com.chwl.library.utils.codec.MD5Utils;
import com.chwl.library.utils.config.BasicConfig;
import com.coorchice.library.utils.LogUtils;
import com.example.lib_utils.ServiceTime;
import com.hjq.toast.ToastUtils;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.NotificationFoldStyle;
import com.netease.nimlib.sdk.SDKOptions;
import com.netease.nimlib.sdk.StatusBarNotificationConfig;
import com.netease.nimlib.sdk.mixpush.MixPushConfig;
import com.netease.nimlib.sdk.mixpush.NIMPushClient;
import com.netease.nimlib.sdk.msg.MessageNotifierCustomization;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.util.NIMUtil;
import com.opensource.svgaplayer.SVGAParser;
import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.Logger;
import com.scwang.smart.refresh.footer.ClassicsFooter;
import com.scwang.smart.refresh.header.MaterialHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.api.RefreshFooter;
import com.scwang.smart.refresh.layout.api.RefreshHeader;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.DefaultRefreshFooterCreator;
import com.scwang.smart.refresh.layout.listener.DefaultRefreshHeaderCreator;
import com.tencent.vasdolly.helper.ChannelReaderUtil;
import org.greenrobot.eventbus.EventBus;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import io.reactivex.plugins.RxJavaPlugins;
import io.realm.Realm;
import io.realm.RealmConfiguration;
/**
* @author chenran
* @date 2017/2/11
*/
public class App extends BaseApp {
public static final String TAG = "XChatApplication";
public static Application gContext;
//static 代码段可以防止内存泄露
static {
//设置全局的Header构建器
SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() {
@Override
public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色
return new MaterialHeader(context);//.setTimeFormat(new DynamicTimeFormat("更新于 %s"));//指定为经典Header默认是 贝塞尔雷达Header
}
});
//设置全局的Footer构建器
SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() {
@Override
public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {
//指定为经典Footer默认是 BallPulseFooter
return new ClassicsFooter(context).setDrawableSize(20);
}
});
}
// 接收到退出登录事件(跳转到登录页了)
private static long logoutEventTime = 0;
private static final MessageNotifierCustomization messageNotifierCustomization = new MessageNotifierCustomization() {
@Override
public String makeNotifyContent(String nick, IMMessage message) {
if (message.getMsgType() == MsgTypeEnum.custom) {
CustomAttachment customAttachment = (CustomAttachment) message.getAttachment();
if (customAttachment.getFirst() == CUSTOM_MSG_HEADER_TYPE_OPEN_ROOM_NOTI) {
return message.getFromNick();
} else if (customAttachment instanceof OpenSignInAttachment) {
return getContentFromOpenSignIn(customAttachment);
}
}
// 采用SDK默认文案
return ResUtil.getString(R.string.erban_application_xchatapplication_01);
}
@Override
public String makeTicker(String nick, IMMessage message) {
if (message.getMsgType() == MsgTypeEnum.custom) {
CustomAttachment customAttachment = (CustomAttachment) message.getAttachment();
if (customAttachment != null) {
if (customAttachment.getFirst() == CUSTOM_MSG_HEADER_TYPE_OPEN_ROOM_NOTI) {
return message.getFromNick();
} else if (customAttachment instanceof OpenSignInAttachment) {
return getContentFromOpenSignIn(customAttachment);
}
}
}
// 采用SDK默认文案
return ResUtil.getString(R.string.erban_application_xchatapplication_02);
}
private String getContentFromOpenSignIn(CustomAttachment attachment) {
String result = null;
if (attachment instanceof OpenSignInAttachment) {
ImNotice notice = ((OpenSignInAttachment) attachment).getImNotice();
if (notice != null) {
result = notice.getContent();
}
}
if (TextUtils.isEmpty(result)) {
result = ResUtil.getString(R.string.erban_application_xchatapplication_03);
}
return result;
}
@Override
public String makeRevokeMsgTip(String s, IMMessage imMessage) {
return null;
}
@Override
public String makeCategory(IMMessage message) {
return null;
}
};
private static App instance;
//生命周期监听
private static AppLifeCycleHelper lifeCycleHelper;
public static ActivityStack gStack = new ActivityStack();
private static boolean isInitOtherSDK = false;
public static App instance() {
return instance;
}
public static void initOtherSDK() {
if (isInitOtherSDK) return;
isInitOtherSDK = true;
Context context = BasicConfig.INSTANCE.getAppContext();
Application application = (Application) context.getApplicationContext();
// 初始化 sp
long startTime = System.currentTimeMillis();
String channel = "";
channel = ChannelReaderUtil.getChannel(instance);
Log.d("APP", "localChannel:" + channel);
if (TextUtils.isEmpty(channel)) {
channel = Constants.GOOGLE;
}
Log.d("APP", "finalChannel:" + channel);
BasicConfig.INSTANCE.setOriginalChannel(channel);
BasicConfig.INSTANCE.setChannel(channel);
initEnv();
// ARouter
if (isDebug()) { // These two lines must be written before init, otherwise these configurations will be invalid in the init process
ARouter.openLog(); // Print log
ARouter.openDebug(); // Turn on debugging mode (If you are running in InstantRun mode, you must turn on debug mode! Online version needs to be closed, otherwise there is a security risk)
}
ARouter.init(application); // As early as possible, it is recommended to initialize in the Application
//延迟初始化云信
NIMClient.init(context, null, options());
//logger 配置
Logger.addLogAdapter(new AndroidLogAdapter() {
@Override
public boolean isLoggable(int priority, String tag) {
return BuildConfig.DEBUG;
}
});
ToastUtils.init(application);
if (inMainProcess(context)) {
DemoCache.saveLaunchCount();
// 注册自定义推送消息处理,这个是可选项
NIMPushClient.registerMixPushMessageHandler(new PushMessageHandler());
RxJavaPlugins.setErrorHandler(throwable -> {
if (BuildConfig.DEBUG) {
Log.e(TAG, "the subscribe() method default error handler", throwable);
}
});
//需要完善资料错误码全局处理
GsonConverterPlugins.setResultHandler(result -> {
if (result instanceof ServiceResult<?>) {
ServiceResult<?> serviceResult = (ServiceResult<?>) result;
if (serviceResult.getCode() == ServiceResult.CODE_NEED_COMPLETE_USER_INFO) {
SingleToastUtil.showToast(serviceResult.getMessage());
EventBus.getDefault().post(new NeedCompleteInfoEvent());
throw new ServerException(serviceResult.getMessage(), serviceResult.getCode());
} else if (serviceResult.getCode() == 401) {
if ((ServiceTime.INSTANCE.getTime() - logoutEventTime) > 800) {
logoutEventTime = ServiceTime.INSTANCE.getTime();
SingleToastUtil.showToast(serviceResult.getMessage());
AuthModel.get().cleanLogInfo();
}
throw new ServerException(serviceResult.getMessage(), serviceResult.getCode());
}else if (serviceResult.getCode() == ServiceResult.CODE_ROOM_MANAGER_LIMIT) {
throw new ServerException(serviceResult.getMessage(), serviceResult.getCode());
}
}
return null;
});
GsonConverterPlugins.lockdown();
//fixed: Glide Exception:"You must not call setTag() on a view Glide is targeting"
ViewTarget.setTagId(R.id.tag_glide);
init(channel);
//生命周期监听
if (lifeCycleHelper == null) {
lifeCycleHelper = new AppLifeCycleHelper();
}
registerActivityLifecycleCallback(lifeCycleHelper);
// initLinkedMe();
// MobSDK.init(context);
// MobSDK.submitPolicyGrantResult(true);
}
// SVGALogger.INSTANCE.setLogEnabled(BuildConfig.DEBUG);
// SVGASoundManager.INSTANCE.init();
LogUtils.d("init time = " + (System.currentTimeMillis() - startTime) + "ms");
}
public static void registerActivityLifecycleCallback(Application.ActivityLifecycleCallbacks callbacks) {
((Application) BasicConfig.INSTANCE.getAppContext().getApplicationContext()).registerActivityLifecycleCallbacks(callbacks);
}
// /**
// * 初始化linkedMe
// */
// private static void initLinkedMe() {
// MobSDK.init(instance, "32fd2f8457880", "ef796ca85e8cd95a76929663de133214");
// MobLink.setRestoreSceneListener(new RestoreSceneListener() {
// @Override
// public Class<? extends Activity> willRestoreScene(Scene scene) {
// return AgentActivity.class;
// }
//
// @Override
// public void completeRestore(Scene scene) {
// }
//
// @Override
// public void notFoundScene(Scene scene) {
// }
// });
// }
private static void initEnv() {
//首先初始化环境
Env.initEnv(BuildConfig.BUILD_TYPE, BuildConfig.DEBUG);
//切换生产坏境和测试环境 true/测试环境 false/生产环境
BasicConfig.INSTANCE.setDebuggable(Env.isDebug());
BasicConfig.INSTANCE.setRootDir(Constants.ERBAN_DIR_NAME);
BasicConfig.INSTANCE.setLogDir(Constants.LOG_DIR);
BasicConfig.INSTANCE.setConfigDir(Constants.CONFIG_DIR);
BasicConfig.INSTANCE.setVoiceDir(Constants.VOICE_DIR);
BasicConfig.INSTANCE.setCacheDir(Constants.CACHE_DIR);
BasicConfig.INSTANCE.setImageDir(Constants.IMAGE_CACHE_DIR);
com.example.lib_utils.log.LogUtil.INSTANCE.setConsolePrinterEnabled(BuildConfig.DEBUG);
}
/**
* 云信配置
*
* @return
*/
public static SDKOptions options() {
SDKOptions options = new SDKOptions();
options.disableAwake = true;
options.asyncInitSDK = true;
// options.customPushContentType = "";
if (isDebug()) {
options.checkManifestConfig = true;
}
// 如果将新消息通知提醒托管给 SDK 完成,需要添加以下配置。否则无需设置。
StatusBarNotificationConfig config = new StatusBarNotificationConfig();
// 点击通知栏跳转到该Activity
config.notificationEntrance = NimMiddleActivity.class;
// config.notificationSmallIconId = R.drawable.icon_msg_normal;
// 呼吸灯配置
config.ledARGB = Color.GREEN;
config.ledOnMs = 1000;
config.ledOffMs = 1500;
config.notificationFoldStyle = NotificationFoldStyle.CONTACT;
// 通知铃声的uri字符串
config.notificationSound = "android.resource://com.netease.nim.demo/raw/msg";
options.statusBarNotificationConfig = config;
// 定制通知栏提醒文案可选如果不定制将采用SDK默认文案
options.messageNotifierCustomization = messageNotifierCustomization;
options.appKey = Constants.nimAppKey;
// 配置保存图片文件log 等数据的目录
// 如果 options 中没有设置这个值SDK 会使用下面代码示例中的位置作为 SDK 的数据目录。
// 该目录目前包含 log, file, image, audio, video, thumb 这6个目录。
// 如果第三方 APP 需要缓存清理功能, 清理这个目录下面个子目录的内容即可。
String sdkPath = null;
try {
sdkPath = FileHelper.getRootCacheDir().getAbsolutePath() + "/nim";
} catch (ArrayIndexOutOfBoundsException e) {
}
options.sdkStorageRootPath = sdkPath;
// 配置是否需要预下载附件缩略图,默认为 true
options.preloadAttach = true;
// 配置附件缩略图的尺寸大小。表示向服务器请求缩略图文件的大小
// 该值一般应根据屏幕尺寸来确定, 默认值为 Screen.width / 2
int widthPixels = BasicConfig.INSTANCE.getAppContext().getResources().getDisplayMetrics().widthPixels;
options.thumbnailSize = widthPixels / 2;
// // save cache留做切换账号备用
DemoCache.setNotificationConfig(config);
MixPushConfig mixPushConfig = new MixPushConfig();
options.mixPushConfig = mixPushConfig;
return options;
}
/**
* 判断当前进程是否主进程
*
* @param context
* @return
*/
private static boolean inMainProcess(Context context) {
String packageName = context.getPackageName();
String processName = NIMUtil.getProcessName(context);
return packageName.equals(processName);
}
private static void init(String channel) {
initNimUIKit();
UriProvider.initUri(BuildConfig.BASE_URL_DEBUG, BuildConfig.BASE_URL_STAGING, BuildConfig.BASE_URL_RELEASE);
initRxNet(BasicConfig.INSTANCE.getAppContext(), UriProvider.JAVA_WEB_URL);
Env.EnvType envType = Env.getCurrentEnv();
if (envType == Env.EnvType.Release || (!BuildConfig.DEBUG)) {
OtherExtKt.doLog(" 域名 ping 环境:正式---->, 准备执行域名池相关逻辑");
List<String> firstUrls = new ArrayList<>();
firstUrls.add("api.molistar.xyz");
// firstUrls.add("api.molistar.xyzz");
NetworkLatencyChecker.INSTANCE.use(firstUrls,443,5000, firstUrl -> {
if (OtherExtKt.isVerify(firstUrl)){
OtherExtKt.doLog(" 域名 ping--> , 当前域名最优为 "+firstUrl +" 是默认优先域名,不做其他处理");
NetworkLatencyChecker.INSTANCE.checkFinishes();
}else {
OtherExtKt.doLog(" 域名 ping--> , 默认优先域名出现异常 , 执行检测 次级域名 逻辑");
List<String> secondUrls = new ArrayList<>();
secondUrls.add("api.molistars.com");
NetworkLatencyChecker.INSTANCE.use(secondUrls,443,5000, secondUrl -> {
if (OtherExtKt.isVerify(secondUrl)){
String newBaseUrl = "https://"+secondUrl+"/";
OtherExtKt.doLog(" 域名 ping--> , 次级域名检测-正常, 执行刷新域名操作 "+secondUrl);
UriProvider.initUri(BuildConfig.BASE_URL_DEBUG, BuildConfig.BASE_URL_STAGING, newBaseUrl);
RxNet.refreshBaseUrl(newBaseUrl);
refreshApi();
NetworkLatencyChecker.INSTANCE.checkFinishes();
}else {
OtherExtKt.doLog(" 域名 ping--> , 次级域名检测-异常!, 没有后续操作.. ");
NetworkLatencyChecker.INSTANCE.checkFinishes();
}
return null;
});
}
return null;
});
}else {
OtherExtKt.doLog(" 域名 ping--> 环境:测试---->, 无需执行域名池");
NetworkLatencyChecker.INSTANCE.checkFinishes();
}
SVGAParser.Companion.shareParser().init(BasicConfig.INSTANCE.getAppContext());
try {
/** svga动画缓存路径 */
String cacheDirPath = FileHelper.getRootCacheDir().getAbsolutePath();
File cacheFie = new File(cacheDirPath, "cacheDir");
HttpResponseCache.install(cacheFie, 1024 * 1024 * 128);
} catch (IOException e) {
Log.e(TAG, "HttpResponseCache install error :" + e.getMessage());
}
/**
* 使用到realm 数据库,这里配置数据库 这里必须先于模块初始化前进行初始化配置
*/
Realm.init(BasicConfig.INSTANCE.getAppContext());
RealmConfiguration config = new RealmConfiguration.Builder()
.name("accompany.realm")
.deleteRealmIfMigrationNeeded()
.build();
Realm.setDefaultConfiguration(config);
LogUtil.i(TAG, channel);
}
/**
* 初始化RxNet
*
* @param context
* @param url
*/
@SuppressLint("CheckResult")
public static void initRxNet(Context context, String url) {
Map<String, String> httpParams = new ConcurrentHashMap<>();
httpParams.put("os", "android");
httpParams.put("osVersion", Build.VERSION.RELEASE);
httpParams.put("app", XConstants.APP_MARK);
httpParams.put("ispType", String.valueOf(SystemUtils.getIspType(context)));
httpParams.put("netType", String.valueOf(SystemUtils.getNetworkType(context)));
httpParams.put("model", SystemUtils.getPhoneModel());
httpParams.put("appVersion", VersionUtil.getLocalName(context));
httpParams.put("appVersionCode", String.valueOf(VersionUtil.getVersionCode(context)));
httpParams.put("deviceId", DeviceUuidFactory.getDeviceId(context));
httpParams.put("androidId", MD5Utils.getMD5String(Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID)));
httpParams.put("channel", AppMetaDataUtil.getChannelID());
httpParams.put("lang", LanguageHelper.INSTANCE.getSystemLanguage().toLanguageTag());
RxNet.init(context)
.debug(Env.isRealDebug())
.setBaseUrl(url)
.addInterceptors(new ParamsInterceptor(httpParams))
.addInterceptors(new NoParamsInterceptor())//注意:拦截器的添加顺序,请求的拦截顺序
.addInterceptors(new TimeSyncInterceptor())
.certificates()
.build();
//单例的model 初始化
initModel();
}
/**
* 一些单例的 model
*/
private static void initModel() {
DynamicFaceModel.get().init();
PayModel.get();
UserModel.get();
//ui层的萝卜钱包
RadishWalletManager.get();
//model层的
RadishModel.get();
IMMessageManager.get().init();
IMSystemMsgManager.get().init();
FamilyModel.Instance();
AuthModel.get();
ChannelModel.get();
MarketVerifyModel.get();
GiftModel.get();
// 模厅
HallDataManager.get().application();
//全局处理
GlobalHandleManager.get().init();
InitialModel.get().init(true).subscribe();
//上报平台初始化
ReportManager.get().init();
}
private static void refreshApi() {
PayModel.get().refreshApi();
UserModel.get().refreshApi();
RadishModel.get().refreshApi();
FamilyModel.Instance().refreshApi();
AuthModel.get().refreshApi();
MarketVerifyModel.get().refreshApi();
GiftModel.get().refreshApi();
HallDataManager.get().refreshApi();
InitialModel.get().refreshApi();
InitialModel.get().init(false);
}
private static void initNimUIKit() {
// 初始化
NimUIKit.init(BasicConfig.INSTANCE.getAppContext(), new IMUserInfoProvider(), null);
}
/**
* debug 环境 受到实验室模式影响
*/
public static boolean isDebug() {
return Env.isDebug();
}
/**
* 是否是真实的debug的环境 不受实验室模式影响
*
* @return
*/
public static boolean isRealDebug() {
return Env.isRealDebug();
}
/**
* 用户没同意隐私协议之前,啥也不干!!
*/
@Override
public void onCreate() {
super.onCreate();
OtherExtKt.doLog("App onCreate() -- 启动");
instance = this;
BaseApp.init(this);
BasicConfig.INSTANCE.setAppContext(this.getApplicationContext());
SharedPreferenceUtils.init(this);
ResUtil.init(this);
ResUtil.contextSupplier = () -> App.gStack.getTopContext();
LanguageHelper.INSTANCE.wrapContext(instance);
initOtherSDK();
initContext(this);
//首次启动事件
HashMap<String, Object> map = new HashMap<>(2);
map.put(IReportConstants.MODULE, IReportConstants.MOLISTAR_ACTIVATE);
ReportManager.get().reportEvent(IReportConstants.ACTIVATE_FIRST, map);
//xxx 崩溃日志拦截
if (BuildConfig.DEBUG) {
CrashCat.getInstance(getApplicationContext(), Environment.getExternalStorageDirectory().getPath()+ "/Log","log.txt").start();
}
}
/**
* 初始化Application实例
*/
public void initContext(Application application) {
gContext = application;
}
/**
* @return 获取Application实例
*/
public static Application getApplication() {
return gContext;
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(base);
}
@Override
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LanguageHelper.INSTANCE.wrapContext(this);
}
@Override
public void onTerminate() {
super.onTerminate();
GlobalHandleManager.get().unInit();
if (lifeCycleHelper != null) {
unregisterActivityLifecycleCallbacks(lifeCycleHelper);
}
}
}

View File

@@ -0,0 +1,115 @@
package com.chwl.app.application;
import android.app.Activity;
import com.chwl.app.avroom.newuserchargegift.NewUserChargePrizeDialog;
import com.chwl.app.relation.cp.dialog.CpGlobalDialog;
import com.chwl.app.ui.widget.LevelUpDialog;
import com.chwl.app.ui.widget.RecallDialog;
import com.chwl.app.vip.dialog.VipUpgradeDialog;
import com.chwl.core.level.event.CharmLevelUpEvent;
import com.chwl.core.level.event.LevelUpEvent;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.pay.event.NewUserChargeEvent;
import com.chwl.core.recall.bean.CheckLostUserInfo;
import com.chwl.core.recall.event.CheckLostUserEvent;
import com.chwl.core.relation.cp.bean.CpInviteInfo;
import com.chwl.core.upgrade.event.ImPushUpdateAppEvent;
import com.chwl.core.user.UserModel;
import com.chwl.core.utils.SharedPreferenceUtils;
import com.chwl.core.vip.VipUpgradeEvent;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
/**
* 全局处理比如App弹窗
* create by lvzebiao @2019/8/14
*/
public class GlobalHandleManager {
private GlobalHandleManager() {
}
public static GlobalHandleManager get() {
return Helper.INSTANCE;
}
public void init() {
EventBus.getDefault().register(this);
}
public void unInit() {
EventBus.getDefault().unregister(this);
}
public Activity getActivity() {
return App.gStack.getTopActivity();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onImPushUpdateAppEvent(ImPushUpdateAppEvent event) {
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onVipUpgradeEvent(VipUpgradeEvent vipUpgradeEvent) {
Activity activity = getActivity();
if (activity == null) return;
UserModel.get().onlyUpdateLoginUserInfoCache();
VipUpgradeDialog.newInstance(vipUpgradeEvent.getVipInfo()).show(activity);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onCpInviteEvent(CpInviteInfo entity) {
Activity activity = getActivity();
if (activity == null) return;
CpGlobalDialog.newInstance(entity, activity).openDialog();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onNewUserChargeEvent(NewUserChargeEvent event) {
Activity activity = getActivity();
if (activity == null) return;
new NewUserChargePrizeDialog(activity, event.getChargeProdTitle(), event.getFirstChargeRewardList()).openDialog();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onReceiveRecallStatus(CheckLostUserEvent event) {
Activity activity = getActivity();
if (activity == null) return;
//如果没有获取到当前登录用户的信息,不弹出提示
if (UserModel.get().getCacheLoginUserInfo() == null) {
return;
}
CheckLostUserInfo checkLostUserInfo = (CheckLostUserInfo) event.getData();
boolean goBackOnce = (boolean) SharedPreferenceUtils.get(RecallDialog.GO_BACK_ONCE, false);
if (!goBackOnce && !event.isFailed() && checkLostUserInfo.isLostUser() && !checkLostUserInfo.isClaimedAward())
RecallDialog.start(activity);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onReceiveLevelUpActivity(LevelUpEvent event) {
Activity activity = getActivity();
if (activity == null) return;
if (AvRoomDataManager.get().isSelfGamePlaying()) return;
// LevelUpDialog.start(activity, event.getLevelName(), true);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onReceiveCharmLevelUpActivity(CharmLevelUpEvent event) {
Activity activity = getActivity();
if (activity == null) return;
if (AvRoomDataManager.get().isSelfGamePlaying()) return;
// LevelUpDialog.start(activity, event.getLevelName(), false);
}
private static final class Helper {
private static final GlobalHandleManager INSTANCE = new GlobalHandleManager();
}
}

View File

@@ -0,0 +1,60 @@
package com.chwl.app.application;
/**
* Created by wushaocheng on 2022/11/10.
*/
public interface IReportConstants {
//Adjust
String ADJUST_REGISTER = "yly8k0";
String ADJUST_LOGIN = "ygtnu5";
String CHANNEL = "channel";
String UID = "uid";
String APPV = "appv";
String MODULE = "module";
int ZERO = 0;
int ONE = 1;
int TWO = 2;
int THREE = 3;
int FOUR = 4;
int FIVE = 5;
int SIX = 6;
int SEVEN = 7;
int EIGHT = 8;
int NINE = 9;
int TEN = 10;
int ELEVEN = 11;
int TWELVE = 12;
int THIRTEEN = 13;
int FOURTEEN = 14;
int FIFTEEN = 15;
String ACTIVATE_FIRST = "activate_first";
String MOLISTAR_ACTIVATE = "molistar_activate";
String AGREEMENT_SHOW = "agreement_show";
String MOLISTAR_LOGIN = "molistar_login";
String AGREEMENT_CLICK = "agreement_click";
String CLICK_TYPE = "click_type";
String PAGE = "page";
String LOGIN_SHOW = "login_show";
String LOGIN_CLICK = "login_click";
String LOGIN_REQUEST = "login_request";
String LOGIN_TYPE = "login_type";
String LOGIN_RESULT = "login_result";
String RESULT = "result";
String FAIL_DETAIL = "fail_detail";
String MODULE_HOMEPAGE_CLICK = "module_homepage_click";
String HOMEPAGE_TYPE = "homepage_type";
String MOLISTAR_HOMEPAGE = "molistar_homepage";
String TAB_HOMEPAGE_CLICK = "tab_homepage_click";
String HOMEPAGE_TAB = "homepage_tab";
String PAYPAGE_SHOW = "paypage_show";
String PAYPAGE_TYPE = "paypage_type";
String ACCOUNT_BALANCE = "account_balance";
String PAY_CLICK = "pay_click";
String MONEY = "money";
String MOLISTAR_PAY = "molistar_pay";
}

View File

@@ -0,0 +1,41 @@
package com.chwl.app.application;
import android.os.Bundle;
import java.util.Map;
/**
* Created by logwee on 2018/10/10.
*/
public interface IReportService {
/**
* 设置FirebaseAnalytics公共属性
*
* @param bundle 公共属性
*/
void setFirebaseAnalyticsDefaultEventParameters(Bundle bundle);
/**
* 埋点,不需要字事件
*
* @param eventId 事件名称
*/
void reportEvent(String eventId);
/**
* 埋点
*
* @param eventId 事件名称
* @param map 事件参数和值
*/
void reportEvent(String eventId, Map<String, Object> map);
/**
* Adjust埋点
*
* @param eventId 事件名称
*/
void reportAdjustEvent(String eventId);
}

View File

@@ -0,0 +1,63 @@
package com.chwl.app.application;
import android.os.Bundle;
import java.util.Map;
/**
* 统一埋点事件
* create by lvzebiao @2019/8/14
*/
public class ReportManager implements IReportService {
private static final String TAG = "ReportManager";
private ReportManager() {
}
private static final class Helper {
private static final ReportManager INSTANCE = new ReportManager();
}
public static ReportManager get() {
return Helper.INSTANCE;
}
public void init() {
}
/**
* 设置FirebaseAnalytics公共属性
*
* @param bundle 公共属性
*/
@Override
public void setFirebaseAnalyticsDefaultEventParameters(Bundle bundle) {
}
/**
* 埋点,不需要上报网络质量和事件耗时
*
* @param eventId 事件名称
*/
@Override
public void reportEvent(String eventId) {
reportEvent(eventId, null);
}
/**
* 埋点
*
* @param eventId 事件名称
* @param map 事件参数和值
*/
@Override
public void reportEvent(String eventId, Map<String, Object> map) {
}
@Override
public void reportAdjustEvent(String eventId) {
}
}

View File

@@ -0,0 +1,373 @@
package com.chwl.app.audio;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Chronometer;
import com.netease.nimlib.sdk.media.player.AudioPlayer;
import com.netease.nimlib.sdk.media.player.OnPlayListener;
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.chwl.app.R;
import com.chwl.app.base.BaseViewBindingActivity;
import com.chwl.app.common.widget.dialog.DialogManager;
import com.chwl.app.databinding.ActivityAudiorecordBinding;
import com.chwl.core.audio.AudioPlayAndRecordManager;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.file.FileModel;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.core.room.model.AvRoomModel;
import com.chwl.core.user.UserModel;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.log.MLog;
import java.io.File;
import io.reactivex.SingleObserver;
import io.reactivex.disposables.Disposable;
/**
* @author zhouxiangfeng
* @date 2017/5/25
*/
public class AudioRecordActivity extends BaseViewBindingActivity<ActivityAudiorecordBinding> implements View.OnClickListener {
private static final String TAG = "AudioRecordActivity";
public static final String AUDIO_FILE = "AUDIO_FILE";
public static final String AUDIO_DURA = "AUDIO_DURA";
private String audioUrl;
private AudioPlayer audioPlayer;
private AudioPlayAndRecordManager audioManager;
private AudioRecorder recorder;
@Override
public void init() {
audioManager = AudioPlayAndRecordManager.getInstance();
audioPlayer = audioManager.getAudioPlayer(null, onPlayListener);
onSetListener();
}
@SuppressLint("ClickableViewAccessibility")
private void onSetListener() {
binding.llRecord.setOnClickListener(this);
binding.ivTryListen.setOnClickListener(this);
binding.ivRetryRecord.setOnClickListener(this);
binding.ivRecordSave.setOnClickListener(this);
binding.ivRecord.setOnTouchListener((v, event) -> {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
RoomInfo current = AvRoomDataManager.get().mCurrentRoomInfo;
if (current != null) {
getDialogManager().showOkCancelDialog(ResUtil.getString(R.string.erban_audio_audiorecordactivity_01),
true, new DialogManager.OkCancelDialogListener() {
@Override
public void onCancel() {
}
@Override
public void onOk() {
AvRoomModel.get().exitRoom(null);
}
});
} else {
startVoice();
}
return true;
case MotionEvent.ACTION_UP:
audioManager.stopRecord(false);
return true;
default:
}
return false;
});
binding.imgBack.setOnClickListener(v -> finish());
}
private void startVoice() {
if (audioState == STATE_RECORD_RECORDING) {
toast(ResUtil.getString(R.string.erban_audio_audiorecordactivity_02));
} else if (audioState == STATE_RECORD_NORMAL) {
audioState = STATE_RECORD_RECORDING;
showByState(audioState);
startChronometer();
recorder = audioManager.getAudioRecorder(AudioRecordActivity.this, onRecordCallback);
audioManager.startRecord();
}
}
private void startChronometer() {
binding.tvChronometer.setVisibility(View.VISIBLE);
binding.tvChronometer.setFormat("");
value = -1;
binding.tvChronometer.setOnChronometerTickListener(chronometerTickListener);
binding.tvChronometer.setBase(0);
binding.tvChronometer.start();
}
private int audioState = STATE_RECORD_NORMAL;
public static final int STATE_RECORD_RECORDING = 1;
public static final int STATE_RECORD_SUCCESS = 2;
public static final int STATE_RECORD_NORMAL = 0;
private File audioFile;
private int audioDura;
IAudioRecordCallback onRecordCallback = new IAudioRecordCallback() {
@Override
public void onRecordReady() {
Log.d(TAG, "onRecordReady");
}
@Override
public void onRecordStart(File file, RecordType recordType) {
Log.d(TAG, "onRecordStart : " + file.getPath() + "type: " + recordType.name());
}
@Override
public void onRecordSuccess(File file, long l, RecordType recordType) {
double dura = (double) l / 1000;
audioDura = (int) Math.round(dura);
Log.d(TAG, "onRecordSuccess : " + file.getPath() + "lenth " + audioDura + "type : " + recordType.name());
toast(ResUtil.getString(R.string.erban_audio_audiorecordactivity_03));
audioFile = file;
audioState = STATE_RECORD_SUCCESS;
showByState(audioState);
}
@Override
public void onRecordFail() {
Log.d(TAG, "onRecordFail");
toast(ResUtil.getString(R.string.erban_audio_audiorecordactivity_04));
audioState = STATE_RECORD_NORMAL;
showByState(audioState);
}
@Override
public void onRecordCancel() {
Log.d(TAG, "onRecordCancel");
audioState = STATE_RECORD_NORMAL;
showByState(audioState);
}
@Override
public void onRecordReachedMaxTime(int i) {
Log.d(TAG, "onRecordReachedMaxTime");
double dura = (double) i / 1000;
int max = (int) Math.round(dura);
toast(ResUtil.getString(R.string.erban_audio_audiorecordactivity_05));
}
};
private void showByState(int state) {
if (state == STATE_RECORD_NORMAL) {
binding.ivRecord.setImageResource(R.drawable.icon_record);
binding.ivRecord.setVisibility(View.VISIBLE);
binding.ivRecordSave.setVisibility(View.GONE);
binding.tvState.setVisibility(View.VISIBLE);
binding.tvState.setText(ResUtil.getString(R.string.erban_audio_audiorecordactivity_06));
binding.tvChronometer.setVisibility(View.INVISIBLE);
binding.ivRetryRecord.setVisibility(View.GONE);
binding.ivTryListen.setVisibility(View.GONE);
} else if (state == STATE_RECORD_RECORDING) {
binding.ivRecord.setImageResource(R.drawable.icon_recording);
binding.ivRecord.setVisibility(View.VISIBLE);
binding.ivRecordSave.setVisibility(View.GONE);
binding.tvState.setVisibility(View.VISIBLE);
binding.tvState.setText(ResUtil.getString(R.string.erban_audio_audiorecordactivity_07));
binding.tvChronometer.setVisibility(View.VISIBLE);
binding.ivRetryRecord.setVisibility(View.GONE);
binding.ivTryListen.setVisibility(View.GONE);
} else if (state == STATE_RECORD_SUCCESS) {
binding.ivRecord.setVisibility(View.GONE);
binding.ivRecordSave.setVisibility(View.VISIBLE);
binding.tvState.setVisibility(View.INVISIBLE);
binding.ivRetryRecord.setVisibility(View.VISIBLE);
binding.tvChronometer.setVisibility(View.INVISIBLE);
binding.tvChronometer.stop();
binding.ivTryListen.setVisibility(View.VISIBLE);
}
}
OnPlayListener onPlayListener = new OnPlayListener() {
@Override
public void onPrepared() {
Log.d(TAG, "onPrepared");
binding.ivTryListen.setImageResource(R.drawable.icon_try_listen_pause);
}
@Override
public void onCompletion() {
Log.d(TAG, "onCompletion");
binding.ivTryListen.setImageResource(R.drawable.icon_try_listen);
}
@Override
public void onInterrupt() {
Log.d(TAG, "onInterrupt");
binding.ivTryListen.setImageResource(R.drawable.icon_try_listen_pause);
}
@Override
public void onError(String s) {
Log.d(TAG, "onError :" + s);
binding.ivTryListen.setImageResource(R.drawable.icon_try_listen);
}
@Override
public void onPlaying(long l) {
Log.d(TAG, "onPlaying :" + l);
binding.ivTryListen.setImageResource(R.drawable.icon_try_listen_pause);
}
};
@SuppressLint("CheckResult")
@Override
public void onClick(View v) {
int id = v.getId();
if(id == R.id.iv_retry_record){
audioState = STATE_RECORD_NORMAL;
showByState(audioState);
if (null != recorder) {
recorder.destroyAudioRecorder();
recorder = null;
}
} else if(id == R.id.iv_try_listen){
if (!audioManager.isPlaying()) {
if (null != audioFile && audioFile.exists()) {
MLog.debug(TAG, "play audioFilePath: " + audioFile.getPath());
audioPlayer.setDataSource(audioFile.getPath());
audioManager.play();
binding.ivTryListen.setImageResource(R.drawable.icon_try_listen_pause);
}
} else {
audioManager.stopPlay();
binding.ivTryListen.setImageResource(R.drawable.icon_try_listen);
}
} else if(id == R.id.iv_record_save){
if (null != audioFile) {
Log.i("result_url", "upload before:" + audioFile.getAbsolutePath());
getDialogManager().showProgressDialog(AudioRecordActivity.this, ResUtil.getString(R.string.erban_audio_audiorecordactivity_08));
FileModel.get()
.uploadFile(audioFile.getAbsolutePath())
.compose(bindToLifecycle())
.subscribe((url, throwable) -> {
if (throwable != null) {
onUploadFail();
} else {
onUpload(url);
}
});
}
}
}
long value = -1;
Chronometer.OnChronometerTickListener chronometerTickListener = new Chronometer.OnChronometerTickListener() {
@Override
public void onChronometerTick(Chronometer chronometer) {
if (value == -1) {
// chronometer.setBase(0); // the base time value
value = chronometer.getBase();
} else {
value++; // timer add
}
if (value > 10) {
audioManager.stopRecord(false);
return;
}
String time;
if (value < 10) {
time = "00:0" + value;
} else {
time = "00:" + value;
}
chronometer.setText(time);
}
};
@Override
protected void onDestroy() {
if (audioManager.isPlaying()) {
audioManager.stopPlay();
}
if (onPlayListener != null) {
onPlayListener = null;
}
if (audioPlayer != null) {
audioPlayer.setOnPlayListener(null);
}
if (audioManager != null)
audioManager.release();
super.onDestroy();
}
private void onUpload(String url) {
audioUrl = url;
Log.i("result_url", "upload success:" + audioUrl);
UserInfo user = new UserInfo();
user.setUid(AuthModel.get().getCurrentUid());
user.setUserVoice(audioUrl);
user.setVoiceDura(audioDura);
UserModel.get().requestUpdateUserInfo(user).subscribe(new SingleObserver<UserInfo>() {
@Override
public void onSubscribe(Disposable d) {
mCompositeDisposable.add(d);
}
@Override
public void onSuccess(UserInfo userInfo) {
onRequestUserInfoUpdate();
}
@Override
public void onError(Throwable e) {
onRequestUserInfoUpdateError(e.getMessage());
}
});
}
private void onUploadFail() {
toast(ResUtil.getString(R.string.erban_audio_audiorecordactivity_09));
getDialogManager().dismissDialog();
}
private void onRequestUserInfoUpdate() {
audioState = STATE_RECORD_NORMAL;
showByState(audioState);
getDialogManager().dismissDialog();
Intent intent = new Intent();
intent.putExtra(AUDIO_FILE, audioUrl);
intent.putExtra(AUDIO_DURA, audioDura);
setResult(RESULT_OK, intent);
finish();
}
private void onRequestUserInfoUpdateError(String error) {
toast(error);
getDialogManager().dismissDialog();
}
}

View File

@@ -0,0 +1,227 @@
package com.chwl.app.audio;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.app.UIHelper;
import com.chwl.app.audio.adapter.MyVoiceListAdapter;
import com.chwl.app.audio.helper.AudioPlayerHelper;
import com.chwl.app.audio.presenter.MyVoicePresenter;
import com.chwl.app.audio.view.IMyVoiceView;
import com.chwl.app.base.BaseMvpActivity;
import com.chwl.app.common.NoDataFragment;
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import com.chwl.app.ui.widget.recyclerview.decoration.HorizontalDecoration;
import com.chwl.core.audio.bean.UserVoiceInfo;
import com.chwl.library.base.factory.CreatePresenter;
import com.chwl.library.utils.ListUtils;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.log.MLog;
import java.util.List;
/**
* 我的声音页面
*/
@CreatePresenter(MyVoicePresenter.class)
public class MyVoiceActivity extends BaseMvpActivity<IMyVoiceView, MyVoicePresenter>
implements IMyVoiceView {
public static final int REQUEST_CODE_RECORDING_VOICE = 1;
private RecyclerView recyclerView;
private MyVoiceListAdapter adapter;// 审核通过列表
private boolean isPlaying;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_voice);
getMvpPresenter().attachMvpView(this);
AudioPlayerHelper.get().onCreate();
initTitleBar(ResUtil.getString(R.string.erban_audio_myvoiceactivity_01));
findView();
initView();
getMvpPresenter().getUserVoiceInfo();
}
private void findView() {
recyclerView = findViewById(R.id.recycler_view);
}
@SuppressLint("CheckResult")
private void initView() {
if (adapter == null) {
adapter = new MyVoiceListAdapter(null);
}
recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
recyclerView.addItemDecoration(new HorizontalDecoration(UIUtil.dip2px(context, 15), false, false));
recyclerView.setAdapter(adapter);
adapter.setOnVerifiedVoiceItemClickListener((isChange, voice) -> {
if (AudioPlayerHelper.get().isPlaying()) {
// 正在播放声音时:点了同一个声音,则停止播放;点了别的声音,则先停止播放 再播放新点击的声音
stopVoice();
isPlaying = false;
if (isChange) {
playVoice(voice);
}
} else {
isPlaying = true;
// 没有在播放声音时候,即正常状态
playVoice(voice);
}
});
adapter.setOnItemChildClickListener((adapter1, view, position) -> {
UserVoiceInfo item = (UserVoiceInfo) adapter1.getItem(position);
if (view.getId() == R.id.tv_re_recording) {
checkPermission(Manifest.permission.RECORD_AUDIO)
.subscribe(result -> {
if (result) {
UIHelper.showRecordVoiceAct(MyVoiceActivity.this,
MyVoiceActivity.REQUEST_CODE_RECORDING_VOICE, item.getId());// 点击跳转到录制声音页面
}
});
}
});
}
private void playVoice(String voice) {
// AudioEngineManager.get().setOpenVoiceMatchActivity(true);
// PlayerModel.get().pause();
AudioPlayerHelper.get().playInThread(voice, new com.chwl.app.audio.helper.OnPlayListener() {
@Override
public void onError(String error) {
if (adapter != null) {
adapter.changePlayState(false);// 播放出错
}
}
@Override
public void onPrepared() {
if (adapter != null) {
adapter.changePlayState(true);// 准备完毕开始播放
}
}
@Override
public void onPlaying(long currDuration) {
}
@Override
public void onCompletion() {
// AudioEngineManager.get().setOpenVoiceMatchActivity(false);
// PlayerModel.get().play(null);
if (adapter != null) {
adapter.changePlayState(false);// 播放完成
}
}
});
}
private void stopVoice() {
// AudioEngineManager.get().setOpenVoiceMatchActivity(false);
// PlayerModel.get().play(null);
AudioPlayerHelper.get().endPlay();
adapter.changePlayState(false);// 点击停止播放
}
@Override
public void initTitleBar(String title) {
mTitleBar = findViewById(R.id.title_bar);
if (mTitleBar != null) {
if (needSteepStateBar()) {
mTitleBar.setImmersive(true);
} else {
mTitleBar.setImmersive(false);
}
mTitleBar.setTitle(title);
mTitleBar.setBackgroundColor(Color.TRANSPARENT);
mTitleBar.setTitleColor(Color.WHITE);
mTitleBar.setLeftImageResource(R.drawable.arrow_left);
mTitleBar.setLeftClickListener(v -> onLeftClickListener());
}
}
@Override
public void showNoData() {
if (!checkActivityValid()) {
return;
}
View status = findViewById(R.id.status_layout);
if (status == null) {
MLog.error(this, "xuwakao, had not set layout id ");
return;
}
@SuppressLint("CheckResult") NoDataFragment fragment = NoDataFragment.newInstance(R.layout.fragment_no_data_green_with_button,
R.drawable.icon_common_failure_green, ResUtil.getString(R.string.erban_audio_myvoiceactivity_03), () -> {
checkPermission(Manifest.permission.RECORD_AUDIO)
.subscribe(result -> {
if (result) {
// 录制入口
UIHelper.showRecordVoiceAct(this, REQUEST_CODE_RECORDING_VOICE, -1);
}
});
});
getSupportFragmentManager().beginTransaction().replace(status.getId(), fragment, STATUS_TAG).commitAllowingStateLoss();
}
@Override
protected void onPause() {
super.onPause();
AudioPlayerHelper.get().onPause();
adapter.changePlayState(false);// onPause() 停止播放
}
@Override
protected void onDestroy() {
super.onDestroy();
// if (isPlaying) {
// PlayerModel.get().play(null);
// }
// AudioEngineManager.get().setOpenVoiceMatchActivity(false);
AudioPlayerHelper.get().onDestroy();
adapter.changePlayState(false);// onDestroy() 停止播放
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CODE_RECORDING_VOICE) {
setResult(RESULT_OK, data);// 传给上一个
getMvpPresenter().getUserVoiceInfo();
}
}
}
@Override
public void showVoiceInfo(List<UserVoiceInfo> voiceList) {
if (ListUtils.isListEmpty(voiceList)) {
showNoData();
} else {
hideStatus();
adapter.setNewData(voiceList);// 审核通过列表
}
}
@Override
public void showLoadingView() {
getDialogManager().showProgressDialog(context, ResUtil.getString(R.string.erban_audio_myvoiceactivity_05));
}
@Override
public void hideLoadingView() {
getDialogManager().dismissDialog();
}
}

View File

@@ -0,0 +1,478 @@
package com.chwl.app.audio;
import static com.chwl.app.audio.presenter.RecordingVoicePresenter.STATE_RECORD_NORMAL;
import static com.chwl.app.audio.presenter.RecordingVoicePresenter.STATE_RECORD_RECORDING;
import static com.chwl.app.audio.presenter.RecordingVoicePresenter.STATE_RECORD_SUCCESS;
import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.app.audio.adapter.CardAdapter;
import com.chwl.app.audio.helper.AudioPlayerHelper;
import com.chwl.app.audio.presenter.RecordingVoicePresenter;
import com.chwl.app.audio.view.IRecordingVoiceView;
import com.chwl.app.audio.widget.OnSwipeListener;
import com.chwl.app.audio.widget.RingProgressView;
import com.chwl.app.audio.widget.VoiceCardConfig;
import com.chwl.app.audio.widget.VoiceCardItemTouchHelperCallback;
import com.chwl.app.audio.widget.VoiceCardLayoutManager;
import com.chwl.app.audio.widget.VoiceCardRecyclerView;
import com.chwl.app.audio.widget.VoiceWave;
import com.chwl.app.base.BaseMvpActivity;
import com.chwl.app.common.widget.dialog.DialogManager;
import com.chwl.core.audio.bean.VoiceCardInfo;
import com.chwl.core.room.model.AvRoomModel;
import com.chwl.library.base.factory.CreatePresenter;
import com.chwl.library.utils.ResUtil;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* 录制声音页面
*/
@CreatePresenter(RecordingVoicePresenter.class)
public class RecordingVoiceActivity extends BaseMvpActivity<IRecordingVoiceView, RecordingVoicePresenter>
implements IRecordingVoiceView, View.OnClickListener {
public static final String EXTRA_VOICE_ID = "voice_id";
public static final String AUDIO_FILE = "AUDIO_FILE";
public static final String AUDIO_DURA = "AUDIO_DURA";
/*时长限制大于等于5s小于等于60s*/
public static final int MIN_RECORD_VOICE_DURATION = 5;// 最少5秒
public static final int MAX_RECORD_VOICE_DURATION = 60;// 最多60秒
private VoiceCardRecyclerView recyclerViewCard;
private TextView tvRecordHint;
private Chronometer tvRecordChronometer;
private TextView tvRecordLeftIcon;
private RingProgressView viewProgress;
private ImageView ivRecordCenterIcon;
private TextView tvRecordRightIcon;
private VoiceWave voiceWave;
private CardAdapter cardAdapter;
private long lastClickTime;
private List<VoiceCardInfo> voiceCardInfoList;
private Drawable playDrawable, pauseDrawable;
private ItemTouchHelper touchHelper;
private VoiceCardItemTouchHelperCallback itemTouchHelperCallback;
private long changeVoiceId = -1;// 被重新录制的声音的ID
private RecordingVoiceHandler voiceHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recording_voice);
getMvpPresenter().attachMvpView(this);
AudioPlayerHelper.get().onCreate();
initTitleBar(ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_01));
findView();
initView();
initData();
setListener();
}
private void findView() {
recyclerViewCard = findViewById(R.id.recycler_view_card);
tvRecordHint = findViewById(R.id.tv_record_hint);
tvRecordChronometer = findViewById(R.id.tv_record_chronometer);
tvRecordLeftIcon = findViewById(R.id.tv_record_left_icon);
viewProgress = findViewById(R.id.view_progress);
ivRecordCenterIcon = findViewById(R.id.iv_record_center_icon);
tvRecordRightIcon = findViewById(R.id.tv_record_right_icon);
voiceWave = findViewById(R.id.voice_wave);
}
private void initView() {
lastClickTime = System.currentTimeMillis();
voiceCardInfoList = new ArrayList<>();
cardAdapter = new CardAdapter(voiceCardInfoList);
recyclerViewCard.setItemAnimator(new DefaultItemAnimator());
recyclerViewCard.setAdapter(cardAdapter);
itemTouchHelperCallback = new VoiceCardItemTouchHelperCallback();
itemTouchHelperCallback.setOnSwipedListener(new OnSwipeListener() {
@Override
public void onSwiping(RecyclerView.ViewHolder viewHolder, float ratio, int direction) {
Log.e("OnSwipeListener", "onSwiping--->" + "VH = " + viewHolder
+ ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_02) + ratio
+ ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_03) + (direction == VoiceCardConfig.SWIPING_LEFT ? ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_04) : direction == VoiceCardConfig.SWIPING_RIGHT ? ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_05) : ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_06)));
viewHolder.itemView.setAlpha(1 - Math.abs(ratio) * 0.2f);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int pos, int direction) {
Log.e("OnSwipeListener", "onSwiped--->" + "VH = " + viewHolder
+ ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_07) + pos
+ ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_08) + (direction == VoiceCardConfig.SWIPED_LEFT ? ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_09) : direction == VoiceCardConfig.SWIPED_RIGHT ? ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_010) : ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_011)));
viewHolder.itemView.setAlpha(1f);
cardAdapter.removeItem(pos);
if (cardAdapter.getItemCount() < VoiceCardConfig.DEFAULT_SHOW_ITEM) {
recyclerViewCard.post(() -> getMvpPresenter().getCardInfo());
}
}
});
touchHelper = new ItemTouchHelper(itemTouchHelperCallback);
VoiceCardLayoutManager cardLayoutManager = new VoiceCardLayoutManager(recyclerViewCard, touchHelper);
recyclerViewCard.setLayoutManager(cardLayoutManager);
// 这里开始就把 它 自己的 onTouchListener 给 RecyclerView然后用 GestureDetectorCompat 来处理那些分发下来的事件。
// 也就是说要防止快速点击1要防止按钮的快速点击 2要防止动画过程中 GestureDetectorCompat 继续响应你的快速点击手势
// 1处理就直接disable那个按钮 2就是拦截掉 RecyclerView 的 onTouchEvent 方法 用 mLayoutFrozen 属性,直接用这个就行了 我试试看
touchHelper.attachToRecyclerView(recyclerViewCard);
cardAdapter.setOnVoiceCardChangeButtonClickListener(new CardAdapter.OnVoiceCardChangeButtonClickListener() {
@Override
public void onVoiceCardChange(RecyclerView.ViewHolder viewHolder) {
long currTime = System.currentTimeMillis();
if (currTime - lastClickTime < 1000) {
return;
}
lastClickTime = currTime;
recyclerViewCard.setLayoutFrozen(true);
recyclerViewCard.post(new Runnable() {
@Override
public void run() {
ValueAnimator mValueAnimator = ValueAnimator.ofFloat(0.0F, 1.0F);
mValueAnimator.setTarget(viewHolder.itemView);
mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
touchHelper.startSwipe(viewHolder);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
mValueAnimator.addUpdateListener(valueAnimator -> {
float fraction = valueAnimator.getAnimatedFraction();
if (fraction == 1) {
itemTouchHelperCallback.onSwiped(viewHolder, ItemTouchHelper.LEFT);
recyclerViewCard.setLayoutFrozen(false);
} else {
itemTouchHelperCallback.onChildDraw(recyclerViewCard.getCanvas(),
recyclerViewCard, viewHolder,
-viewHolder.itemView.getWidth() * fraction,
viewHolder.itemView.getTranslationY(), 1, false);
}
});
mValueAnimator.setDuration(500);
mValueAnimator.start();
}
});
}
});
playDrawable = ContextCompat.getDrawable(context, R.drawable.ic_recording_listener);
pauseDrawable = ContextCompat.getDrawable(context, R.drawable.ic_recording_pause);
refreshButtonView(STATE_RECORD_NORMAL);
}
private void initData() {
if (getIntent() != null) {
changeVoiceId = getIntent().getLongExtra(EXTRA_VOICE_ID, changeVoiceId);
}
getMvpPresenter().initResource();
getMvpPresenter().getCardInfo();
}
private void setListener() {
tvRecordLeftIcon.setOnClickListener(this);
ivRecordCenterIcon.setOnClickListener(this);
tvRecordRightIcon.setOnClickListener(this);
}
@Override
public void initTitleBar(String title) {
mTitleBar = findViewById(R.id.title_bar);
if (mTitleBar != null) {
if (needSteepStateBar()) {
mTitleBar.setImmersive(true);
} else {
mTitleBar.setImmersive(false);
}
mTitleBar.setTitle(title);
mTitleBar.setBackgroundColor(Color.TRANSPARENT);
mTitleBar.setTitleColor(Color.WHITE);
mTitleBar.setLeftImageResource(R.drawable.arrow_left);
mTitleBar.setLeftClickListener(v -> onLeftClickListener());
}
}
@Override
protected void onLeftClickListener() {
getMvpPresenter().leaveThePage();
}
@Override
public void onBackPressed() {
onLeftClickListener();// 物理返回
}
@Override
protected void onPause() {
super.onPause();
getMvpPresenter().pausePage();
}
@Override
protected void onDestroy() {
super.onDestroy();
getMvpPresenter().releaseResource();
}
@SuppressLint("CheckResult")
@Override
public void onClick(View view) {
int id = view.getId();
if (id == R.id.tv_record_left_icon) {
getMvpPresenter().reRecord();
} else if (id == R.id.iv_record_center_icon) {
if (!(ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED)) {
checkPermission(Manifest.permission.RECORD_AUDIO)
.subscribe(aBoolean -> {
if (aBoolean) {
getMvpPresenter().clickCenterIcon();
} else {
toast(ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_013));
}
});
return;
}
getMvpPresenter().clickCenterIcon();
} else if (id == R.id.tv_record_right_icon) {
getMvpPresenter().clickRightIcon();
}
}
@Override
public void addCardInfo(List<VoiceCardInfo> cardInfoList) {
voiceCardInfoList.addAll(cardInfoList);
cardAdapter.notifyDataSetChanged();
}
@Override
public Long getCardPiaId() {
VoiceCardInfo itemInfo = cardAdapter.getFistItemInfo();
if (itemInfo == null) {
return null;
} else {
return itemInfo.getId();
}
}
@Override
public void refreshButtonView(int state) {
switch (state) {
case STATE_RECORD_NORMAL:// 正常默认情况下
viewProgress.setVisibility(View.INVISIBLE);
ivRecordCenterIcon.post(() -> ivRecordCenterIcon.setImageResource(R.drawable.ic_recording));
tvRecordHint.setText(ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_014));
tvRecordHint.setVisibility(View.VISIBLE);
tvRecordChronometer.setVisibility(View.INVISIBLE);
tvRecordLeftIcon.setVisibility(View.INVISIBLE);
tvRecordRightIcon.setVisibility(View.INVISIBLE);
break;
case STATE_RECORD_RECORDING:// 正在录音时
viewProgress.setVisibility(View.VISIBLE);
ivRecordCenterIcon.post(() -> ivRecordCenterIcon.setImageResource(R.drawable.ic_recording_end));
tvRecordHint.setVisibility(View.GONE);
tvRecordChronometer.setVisibility(View.VISIBLE);
tvRecordLeftIcon.setVisibility(View.INVISIBLE);
tvRecordRightIcon.setVisibility(View.INVISIBLE);
break;
case STATE_RECORD_SUCCESS:// 已经录制时
viewProgress.setVisibility(View.INVISIBLE);
ivRecordCenterIcon.post(() -> ivRecordCenterIcon.setImageResource(R.drawable.ic_recording_finish));
tvRecordHint.setVisibility(View.GONE);
tvRecordChronometer.setVisibility(View.VISIBLE);
tvRecordLeftIcon.setVisibility(View.VISIBLE);
tvRecordRightIcon.post(() ->
tvRecordRightIcon.setCompoundDrawablesWithIntrinsicBounds(null, playDrawable, null, null));
tvRecordRightIcon.setText(ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_015));
tvRecordRightIcon.setVisibility(View.VISIBLE);
break;
}
}
@Override
public void refreshListenerButton(boolean isPlaying) {
tvRecordRightIcon.setText(isPlaying ? ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_016) : ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_017));
tvRecordRightIcon.post(() ->
tvRecordRightIcon.setCompoundDrawablesWithIntrinsicBounds(null, isPlaying ? pauseDrawable : playDrawable, null, null));
}
@Override
public void startChronometer() {
tvRecordHint.setVisibility(View.GONE);
tvRecordChronometer.setVisibility(View.VISIBLE);
// tvRecordChronometer.setFormat("");
tvRecordChronometer.setOnChronometerTickListener(chronometer -> {
long elapsedMillis = SystemClock.elapsedRealtime() - chronometer.getBase();
int second = (int) (elapsedMillis / 1000);
String showStr = String.format(Locale.getDefault(), "%ds / %ds", second, MAX_RECORD_VOICE_DURATION);
chronometer.setText(showStr);
// Log.e("RecordingView", "elapsedMillis = " + elapsedMillis
// + " second = " + second
// + " show = " + showStr);
viewProgress.post(() -> {
int currentProgress = 100 * second / MAX_RECORD_VOICE_DURATION;
viewProgress.setCurrentProgress(currentProgress);
});
if (second >= MAX_RECORD_VOICE_DURATION) {
getMvpPresenter().stopRecord();// 录制时长超过上限时,停止录制
}
});
tvRecordChronometer.setBase(SystemClock.elapsedRealtime());
tvRecordChronometer.start();
}
@Override
public void stopChronometer() {
tvRecordChronometer.stop();
}
@Override
public void showConfirmDialogWithLeave() {
getDialogManager().showOkCancelDialog(ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_018),
getString(R.string.voice_tips_save_voice),
ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_019), ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_020), false, true, new DialogManager.OkCancelDialogListener() {
@Override
public void onOk() {
}
@Override
public void onCancel() {
finishView(null);// 声音未保存确认退出页面
}
});
}
@Override
public void finishView(Intent intent) {
if (intent != null) {
setResult(RESULT_OK, intent);
}
finish();
}
@Override
public void showConfirmDialogWithExitRoom() {
getDialogManager().showOkCancelDialog(ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_021),
true, new DialogManager.OkCancelDialogListener() {
@Override
public void onCancel() {
}
@Override
public void onOk() {
AvRoomModel.get().exitRoom(null);
}
});
}
@Override
public void showLoadingView() {
runOnUiThread(() -> getDialogManager().showProgressDialog(context, ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_022)));
}
@Override
public void hideLoadingView() {
runOnUiThread(() -> getDialogManager().dismissDialog());
}
@Override
public Long getChangeVoiceId() {
if (changeVoiceId == -1) {
return null;
}
return changeVoiceId;
}
@Override
public void refreshVoiceWave(double db) {
if (voiceHandler != null) {
voiceHandler.sendEmptyMessage((int) db);
}
}
@Override
public void showVoiceWave() {
voiceWave.setVisibility(View.VISIBLE);
voiceWave.startAnim();
voiceHandler = new RecordingVoiceHandler(this);
// 解决了内存泄漏,延迟5分钟后发送
voiceHandler.sendEmptyMessage(0);
}
@Override
public void hideVoiceWave() {
voiceWave.stopAnim();
voiceWave.setVisibility(View.INVISIBLE);
if (voiceHandler != null) {
voiceHandler.removeCallbacksAndMessages(null);
}
}
@Override
public void showCountDown(int duration) {
tvRecordChronometer.setVisibility(View.VISIBLE);
String showStr = String.format(Locale.getDefault(), "%ds / %ds", duration, MAX_RECORD_VOICE_DURATION);
tvRecordChronometer.setText(showStr);
}
private static class RecordingVoiceHandler extends Handler {
// 持有弱引用 Activity,GC回收时会被回收掉.
private final WeakReference<RecordingVoiceActivity> mActivity;
RecordingVoiceHandler(RecordingVoiceActivity activityWeakReference) {
mActivity = new WeakReference<>(activityWeakReference);
}
@Override
public void handleMessage(Message msg) {
RecordingVoiceActivity activity = mActivity.get();
super.handleMessage(msg);
if (activity != null) {
activity.voiceWave.setVolume(msg.what);
}
}
}
}

View File

@@ -0,0 +1,533 @@
package com.chwl.app.audio
import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.os.SystemClock
import android.util.Log
import android.view.View
import android.widget.Chronometer
import android.widget.Chronometer.OnChronometerTickListener
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import com.netease.nim.uikit.StatusBarUtil
import com.opensource.svgaplayer.SVGADrawable
import com.opensource.svgaplayer.SVGAImageView
import com.opensource.svgaplayer.SVGAParser
import com.opensource.svgaplayer.SVGAVideoEntity
import com.chwl.app.R
import com.chwl.app.audio.helper.AudioPlayerHelper
import com.chwl.app.audio.viewmodel.SoundViewModel
import com.chwl.app.base.BaseViewBindingActivity
import com.chwl.app.databinding.ActivitySoundSignatureBinding
import com.chwl.app.ui.widget.dialog.CommonDialog
import com.chwl.core.file.FileModel
import com.chwl.core.manager.AvRoomDataManager
import com.chwl.core.user.bean.UserInfo.SoundBean
import com.chwl.library.utils.ResUtil
import com.chwl.library.utils.SingleToastUtil
import io.reactivex.SingleObserver
import io.reactivex.disposables.Disposable
import java.util.*
/**
* @author wushaocheng
* 声音签名
*/
class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBinding>(),
View.OnClickListener {
companion object {
const val AUDIO_BEAN = "audio_bean"
const val AUDIO_FILE = "audio_file"
const val AUDIO_DURA = "audio_dura"
const val MIN_RECORD_VOICE_DURATION = 1 // 最少1秒
var MAX_RECORD_VOICE_DURATION = 60 //最多60s
}
private val soundViewModel: SoundViewModel by viewModels()
private var playDrawable: Drawable? = null
private var pauseDrawable: Drawable? = null
private var mCountDownTime = 0
private var timer: Timer? = null
override fun init() {
AudioPlayerHelper.get().onCreate()
initWhiteTitleBar(getString(R.string.sound_signature))
initView()
setListener()
initModel()
}
private fun initView() {
playDrawable = ContextCompat.getDrawable(context, R.drawable.ic_pause_record)
pauseDrawable = ContextCompat.getDrawable(context, R.drawable.ic_resume_record)
val audioCard = intent.getSerializableExtra(AUDIO_BEAN) as SoundBean
when (audioCard.status ?: 0) {
0 -> {
refreshButtonView(SoundViewModel.STATE_RECORD_NORMAL)
}
1 -> {
MAX_RECORD_VOICE_DURATION = audioCard.second ?: 60
binding.roundProgress.setTotalProgress((audioCard.second ?: 60) * 1000)
val showStr = String.format(
Locale.getDefault(),
"%ds / %ds",
0,
MAX_RECORD_VOICE_DURATION
)
binding.tvSoundTime.text = showStr
soundViewModel.audioState = SoundViewModel.STATE_RECORD_SAVE_SUCCESS
soundViewModel.audioUrl = audioCard.audioUrl ?: ""
refreshButtonView(SoundViewModel.STATE_RECORD_SAVE_SUCCESS)
}
2 -> {
MAX_RECORD_VOICE_DURATION = audioCard.second ?: 60
binding.roundProgress.setTotalProgress((audioCard.second ?: 60) * 1000)
val showStr = String.format(
Locale.getDefault(),
"%ds / %ds",
0,
MAX_RECORD_VOICE_DURATION
)
binding.tvSoundTime.text = showStr
soundViewModel.audioState = SoundViewModel.STATE_RECORD_AUDIT_SUCCESS
soundViewModel.audioUrl = audioCard.audioUrl ?: ""
refreshButtonView(SoundViewModel.STATE_RECORD_AUDIT_SUCCESS)
}
else -> {
refreshButtonView(SoundViewModel.STATE_RECORD_NORMAL)
}
}
}
private fun setListener() {
binding.ivSoundStatus.setOnClickListener(this)//中间按钮
binding.frSaveRecord.setOnClickListener(this)//保存按钮
binding.frDeleteBg.setOnClickListener(this)//删除按钮
binding.frRestartBg.setOnClickListener(this)//重新录制按钮
}
private fun initModel() {
soundViewModel.showConfirmLiveData.observe(this) {
if(AvRoomDataManager.get().isOwnerOnMic) {
toast(getString(R.string.on_the_mic_not_record))
} else {
soundViewModel.stopRoomSound()
soundViewModel.showRecordingState()
}
}
soundViewModel.refreshLiveData.observe(this) {
refreshButtonView(it)
}
soundViewModel.startChronometerLiveData.observe(this) {
startChronometer()
}
soundViewModel.stopChronometerLiveData.observe(this) {
stopChronometer()
}
soundViewModel.refreshPlayStatusLiveData.observe(this) {
refreshListenerButton(it)
}
soundViewModel.resetStatusLiveData.observe(this) {
resetStatus()
}
soundViewModel.showCountDownLiveData.observe(this) {
showCountDown(it)
}
soundViewModel.finishViewLiveData.observe(this) {
finishView(it)
}
soundViewModel.saveRecordLiveData.observe(this) {
hideLoad()
refreshButtonView(SoundViewModel.STATE_RECORD_SAVE_SUCCESS)
soundViewModel.audioState = SoundViewModel.STATE_RECORD_SAVE_SUCCESS
SingleToastUtil.showToast(getString(R.string.update_success))
//设置最大计时数
MAX_RECORD_VOICE_DURATION = soundViewModel.audioDur
binding.roundProgress.setTotalProgress(soundViewModel.audioDur * 1000)
val intent = Intent()
intent.putExtra(AUDIO_FILE, soundViewModel.audioUrl)
intent.putExtra(AUDIO_DURA, soundViewModel.audioDur)
setResult(RESULT_OK, intent)// 上传声音成功之后给上个页面传递信息
}
soundViewModel.hideLoadLiveData.observe(this) {
hideLoad()
}
soundViewModel.loadingLiveData.observe(this) { loading ->
if (loading) dialogManager.showProgressDialog(this)
else dialogManager.dismissDialog()
}
soundViewModel.deleteRecordLiveData.observe(this) {
val intent = Intent()
intent.putExtra(AUDIO_FILE, "")
intent.putExtra(AUDIO_DURA, 0)
setResult(RESULT_OK, intent)// 上传声音成功之后给上个页面传递信息
soundViewModel.showNormalState()
}
soundViewModel.showSaveConfirmDialogLiveData.observe(this) {
CommonDialog(this).apply {
setTipMsg(ResUtil.getString(R.string.sound_has_not_been_saved))
setOnActionListener(
object : CommonDialog.OnActionListener {
override fun onOk() {
finishView(null)
}
}
)
show()
}
}
soundViewModel.showRecordConfirmDialogLiveData.observe(this) {
CommonDialog(this).apply {
setTipMsg(ResUtil.getString(R.string.sound_has_not_been_recorded_yet))
setOnActionListener(
object : CommonDialog.OnActionListener {
override fun onOk() {
finishView(null)
}
}
)
show()
}
}
}
private fun showLoad() {
runOnUiThread {
dialogManager.showProgressDialog(
context,
ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_022)
)
}
}
private fun hideLoad() {
runOnUiThread { dialogManager.dismissDialog() }
}
@SuppressLint("CheckResult")
override fun onClick(view: View?) {
when (view?.id) {
R.id.ivSoundStatus -> {//中间按钮
if (ContextCompat.checkSelfPermission(
context,
Manifest.permission.RECORD_AUDIO
) != PackageManager.PERMISSION_GRANTED
) {
checkPermission(Manifest.permission.RECORD_AUDIO)
.subscribe { aBoolean: Boolean ->
if (aBoolean) {
soundViewModel.clickCenterIcon()
} else {
toast(ResUtil.getString(R.string.erban_audio_recordingvoiceactivity_013))
}
}
return
} else {
soundViewModel.clickCenterIcon()
}
}
R.id.frSaveRecord -> {//保存按钮
finishRecord()
}
R.id.frDeleteBg -> {//删除按钮
deleteRecord()
}
R.id.frRestartBg -> {//重新录制按钮
soundViewModel.reRecord()
}
}
}
private fun deleteRecord() {
CommonDialog(this).apply {
setTipMsg(ResUtil.getString(R.string.sure_to_delete_sound))
setOnActionListener(
object : CommonDialog.OnActionListener {
override fun onOk() {
soundViewModel.deleteRecord()
}
}
)
show()
}
}
/**
* 上传声音,完成录制
*/
private fun finishRecord() {
soundViewModel.audioFile?.let {
Log.i("result_url", "upload before:" + it.absolutePath)
showLoad()
FileModel.get()
.uploadFile(it.absolutePath)
.compose(bindToLifecycle())
.subscribe(object : SingleObserver<String> {
override fun onSubscribe(d: Disposable) {}
override fun onSuccess(url: String) {
Log.i("result_url", "upload success:$url")
soundViewModel.saveRecord(url)
}
override fun onError(e: Throwable) {
SingleToastUtil.showToast(ResUtil.getString(R.string.audio_presenter_recordingvoicepresenter_01))
hideLoad()// 声音文件上传失败时
}
})
}
}
private fun refreshButtonView(state: Int) {
when (state) {
SoundViewModel.STATE_RECORD_NORMAL -> {
MAX_RECORD_VOICE_DURATION = 60
binding.roundProgress.setProgress(0)
binding.roundProgress.setTotalProgress(60000)
binding.tvRecordTip.text = getString(R.string.start_record)
val showStr = String.format(
Locale.getDefault(),
"%ds / %ds",
0,
MAX_RECORD_VOICE_DURATION
)
binding.tvSoundTime.text = showStr
binding.ivSoundStatus.post { binding.ivSoundStatus.setImageResource(R.drawable.ic_prepare_record) }
binding.groupRsRecord.visibility = View.INVISIBLE
binding.groupSaveSound.visibility = View.INVISIBLE
binding.groupDeleteSound.visibility = View.INVISIBLE
binding.tvUnderReview.visibility = View.INVISIBLE
stopSvga()
mCountDownTime = 0
}
SoundViewModel.STATE_RECORD_RECORDING -> {
binding.ivSoundStatus.post { binding.ivSoundStatus.setImageResource(R.drawable.ic_start_record) }
binding.tvRecordTip.text = getString(R.string.click_stop)
binding.groupRsRecord.visibility = View.INVISIBLE
binding.groupSaveSound.visibility = View.INVISIBLE
binding.groupDeleteSound.visibility = View.INVISIBLE
binding.tvUnderReview.visibility = View.INVISIBLE
playSvgaBg(binding.svgRecorder, "svga/sound_record.svga")
}
SoundViewModel.STATE_RECORD_SUCCESS -> {
binding.ivSoundStatus.post { binding.ivSoundStatus.setImageResource(R.drawable.ic_pause_record) }
binding.tvRecordTip.text = getString(R.string.click_to_listen)
binding.groupRsRecord.visibility = View.VISIBLE
binding.groupSaveSound.visibility = View.VISIBLE
binding.groupDeleteSound.visibility = View.INVISIBLE
binding.tvUnderReview.visibility = View.INVISIBLE
stopSvga()
}
SoundViewModel.STATE_RECORD_SAVE_SUCCESS -> {
binding.ivSoundStatus.post { binding.ivSoundStatus.setImageResource(R.drawable.ic_pause_record) }
binding.tvRecordTip.text = getString(R.string.click_to_listen)
binding.groupRsRecord.visibility = View.VISIBLE
binding.groupSaveSound.visibility = View.INVISIBLE
binding.groupDeleteSound.visibility = View.VISIBLE
binding.tvUnderReview.visibility = View.VISIBLE
stopSvga()
}
SoundViewModel.STATE_RECORD_AUDIT_SUCCESS -> {
binding.ivSoundStatus.post { binding.ivSoundStatus.setImageResource(R.drawable.ic_pause_record) }
binding.tvRecordTip.text = getString(R.string.click_to_listen)
binding.groupRsRecord.visibility = View.VISIBLE
binding.groupSaveSound.visibility = View.INVISIBLE
binding.groupDeleteSound.visibility = View.VISIBLE
binding.tvUnderReview.visibility = View.GONE
stopSvga()
}
}
}
private fun playSvgaBg(svgaBg: SVGAImageView, assets: String) {
val mSVGAParser = SVGAParser(svgaBg.context)
mSVGAParser.decodeFromAssets(assets, object : SVGAParser.ParseCompletion {
override fun onComplete(videoItem: SVGAVideoEntity) {
val drawable = SVGADrawable(videoItem)
svgaBg.setImageDrawable(drawable)
svgaBg.stepToFrame(0, true)
}
override fun onError() {
}
}, null)
}
/**
* 开始录音
*/
private fun startChronometer() {
startProgress()
binding.tvSoundTime.onChronometerTickListener =
OnChronometerTickListener { chronometer: Chronometer ->
val elapsedMillis =
SystemClock.elapsedRealtime() - chronometer.base
val second = (elapsedMillis / 1000).toInt()
val showStr = String.format(
Locale.getDefault(),
"%ds / %ds",
second,
MAX_RECORD_VOICE_DURATION
)
chronometer.text = showStr
mCountDownTime = second
if (second >= MAX_RECORD_VOICE_DURATION) {
soundViewModel.stopRecord() // 录制时长超过上限时,停止录制
}
}
binding.tvSoundTime.base = SystemClock.elapsedRealtime()
binding.tvSoundTime.start()
}
private fun startProgress() {
var progress = 0 //进度条进度值
timer = Timer()
timer?.schedule(object : TimerTask() {
override fun run() {
runOnUiThread {
progress += 16
if (progress <= MAX_RECORD_VOICE_DURATION * 1000) {
if(mCountDownTime != 60 && soundViewModel.audioState == 1) {
binding.roundProgress.setProgress(progress)
}
}
}
}
}, 0, 16) //间隔时间(单位为毫秒)
}
/**
* 停止录音
*/
private fun stopChronometer() {
binding.tvSoundTime.stop()
timer?.cancel()
val showStr = String.format(
Locale.getDefault(),
"%ds / %ds",
0,
mCountDownTime
)
binding.tvSoundTime.text = showStr
binding.roundProgress.setProgress(0)
binding.roundProgress.setTotalProgress(mCountDownTime * 1000)
MAX_RECORD_VOICE_DURATION = mCountDownTime
soundViewModel.audioState = SoundViewModel.STATE_RECORD_SUCCESS
}
/**
* 刷新试听按钮
*/
private fun refreshListenerButton(isPlaying: Boolean) {
binding.tvRecordTip.text = if (isPlaying) ResUtil.getString(R.string.click_to_stop_playing)
else ResUtil.getString(R.string.click_to_listen)
binding.ivSoundStatus.post {
if (isPlaying) binding.ivSoundStatus.setImageResource(R.drawable.ic_resume_record)
else binding.ivSoundStatus.setImageResource(R.drawable.ic_pause_record)
if (isPlaying) {
playSvgaBg(binding.svgRecorder, "svga/sound_record.svga")
} else {
stopSvga()
}
}
}
private fun resetStatus() {
binding.roundProgress.setProgress(0)
val showStr = String.format(
Locale.getDefault(),
"%ds / %ds",
0,
MAX_RECORD_VOICE_DURATION
)
binding.tvSoundTime.text = showStr
}
private fun stopSvga() {
binding.svgRecorder.stopAnimation()
binding.svgRecorder.clear()
}
/**
* 开始试听
*/
private fun showCountDown(duration: Int) {
val dur = if (60000L - duration <= 500) {
(duration / 1000) + 1
} else {
duration / 1000
}
if (dur <= MAX_RECORD_VOICE_DURATION) {
val showStr = String.format(
Locale.getDefault(),
"%ds / %ds",
dur,
MAX_RECORD_VOICE_DURATION
)
binding.roundProgress.setProgress(duration)
binding.tvSoundTime.text = showStr
}
}
fun finishView(intent: Intent?) {
if (intent != null) {
setResult(RESULT_OK, intent)
}
finish()
}
override fun onLeftClickListener() {
soundViewModel.leaveThePage()
}
override fun onBackPressed() {
onLeftClickListener() // 物理返回
}
override fun onPause() {
super.onPause()
soundViewModel.pausePage()
}
override fun onDestroy() {
super.onDestroy()
timer?.cancel()
mCountDownTime = 0
soundViewModel.releaseResource()
stopSvga()
}
override fun needSteepStateBar(): Boolean {
return true
}
override fun setStatusBar() {
StatusBarUtil.transparencyBar(this)
StatusBarUtil.StatusBarLightMode(this)
}
}

View File

@@ -0,0 +1,637 @@
package com.chwl.app.audio;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.opensource.svgaplayer.SVGACallback;
import com.trello.rxlifecycle3.android.ActivityEvent;
import com.chwl.app.R;
import com.chwl.app.UIHelper;
import com.chwl.app.audio.helper.AudioPlayerHelper;
import com.chwl.app.audio.helper.OnPlayListener;
import com.chwl.app.audio.helper.OnRefreshListener;
import com.chwl.app.audio.helper.SvgaCacheManager;
import com.chwl.app.audio.helper.VmSoundManager;
import com.chwl.app.audio.helper.VoiceMacthHelper;
import com.chwl.app.audio.view.IBottleOpListener;
import com.chwl.app.audio.widget.VoiceBottleFilterGenderBottomDialog;
import com.chwl.app.audio.widget.VoiceLine;
import com.chwl.app.base.BaseViewBindingActivity;
import com.chwl.app.base.TitleBar;
import com.chwl.app.common.widget.dialog.DialogManager;
import com.chwl.app.databinding.ActivityVoiceMatchBinding;
import com.chwl.app.ui.im.avtivity.NimP2PMessageActivity;
import com.chwl.app.ui.widget.higuide.TuTuGuideHelper;
import com.chwl.core.audio.AudioModel;
import com.chwl.core.audio.bean.HistoryVoiceInfo;
import com.chwl.core.audio.bean.VoiceMatchInfo;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.music.model.PlayerModel;
import com.chwl.core.user.UserModel;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.core.utils.ActivityUtil;
import com.chwl.core.utils.SharedPreferenceUtils;
import com.chwl.core.utils.net.DontWarnObserver;
import com.chwl.library.utils.ListUtils;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.SingleToastUtil;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import io.reactivex.SingleSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
/**
* create by lvzebiao @2019/6/6
*/
public class VoiceMatchActivity extends BaseViewBindingActivity<ActivityVoiceMatchBinding> implements View.OnClickListener {
public static final String KEY_VOICE_MUST_LIMIT = "voice_must_limit_";// 是否受限限制喜欢和不喜欢3次
public static final String KEY_VOICE_LIMIT_COUNT = "voice_limit_count_of_";// 限制不喜欢的次数
public static final int REQUEST_CODE_RECORDING_VOICE_WITH_HAS_LIMIT = 1;
public static final int REQUEST_CODE_RECORDING_VOICE_WITH_SYNC_HISTORY_VOICE = 2;
public static final int REQUEST_CODE_RECORDING_VOICE_WITH_MY_VOICE = 3;
private ImageView playIcon;
private VoiceLine voiceLine;
private boolean isLoading;
private boolean isFirst;// 记录是否首次进入页面
private VoiceMacthHelper helper = new VoiceMacthHelper();
private int filterGender;// 当前筛选的性别
private VoiceBottleFilterGenderBottomDialog filterGenderBottomDialog;
private TranslateAnimation showAnim;
private AlphaAnimation alphaAnimation;
public static void start(Context context) {
Intent intent = new Intent(context, VoiceMatchActivity.class);
context.startActivity(intent);
}
@Override
public void init() {
VmSoundManager.get().onCreate();
AudioPlayerHelper.get().onCreate();
SvgaCacheManager.get().onCreate();
initWhiteTitleBar(ResUtil.getString(R.string.erban_audio_voicematchactivity_01));
initView();
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
if (userInfo == null) {
hideStatus();
toast(ResUtil.getString(R.string.erban_audio_voicematchactivity_02));
finish();
return;
}
int oppositeGender = userInfo.getGender() == 1 ? 2 : 1;
filterGender = (int) SharedPreferenceUtils.get("voice_match_filter_gender_" + AuthModel.get().getCurrentUid(), oppositeGender);
isFirst = true;
loadingData(filterGender);// 进入页面加载数据
/*展示我的声音的入口动画*/
showMyVoiceEntranceAnim();
binding.layoutMyVoiceEntrance.setOnClickListener(this);
binding.flGroupContent.setOpListener(new IBottleOpListener() {
@Override
public void onLimit(boolean isRight) {
showDialogWithHasLimit(isRight);
}
@Override
public void onLikeOrUnLike(VoiceMatchInfo info, boolean isRight, boolean needLoading) {
if (needLoading) {
binding.groupVoiceLayout.setVisibility(View.INVISIBLE);
}
likeOrUnlikeVoice(info, isRight, needLoading);
playLikeOrUnLikeBtnAnim(isRight, false);
}
});
}
private void initView() {
binding.ivGroupDontLike.setOnClickListener(this);
binding.svgaGroupVoiceLike.setOnClickListener(this);
}
private void showMyVoiceEntranceAnim() {
if (binding.layoutMyVoiceEntrance.getAnimation() != null) {
binding.layoutMyVoiceEntrance.getAnimation().cancel();
binding.layoutMyVoiceEntrance.clearAnimation();
}
if (binding.tvMyVoiceEntrance.getAnimation() != null) {
binding.tvMyVoiceEntrance.getAnimation().cancel();
binding.tvMyVoiceEntrance.clearAnimation();
}
binding.layoutMyVoiceEntrance.post(() -> {
if (showAnim == null) {
int width = binding.layoutMyVoiceEntrance.getWidth();
showAnim = new TranslateAnimation(0, width / 3 * 1.8f, 1, 1);
showAnim.setStartOffset(2000);
showAnim.setDuration(600);
showAnim.setInterpolator(new AccelerateDecelerateInterpolator());
showAnim.setFillAfter(true);
}
if (alphaAnimation == null) {
alphaAnimation = new AlphaAnimation(1, 0);
alphaAnimation.setStartOffset(2000);
alphaAnimation.setDuration(600);
alphaAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
alphaAnimation.setFillAfter(true);
}
binding.layoutMyVoiceEntrance.startAnimation(showAnim);
binding.tvMyVoiceEntrance.startAnimation(alphaAnimation);
});
}
/**
* 显示引导图的时机
* 1. 首次进入页面isNeedHiGuide
* 2. 请求数据且数据不为空时
*/
private void showGuide() {
/*引导图*/
binding.svgaGroupVoiceLike.postDelayed(() -> {
if (!ActivityUtil.isValidContext(context)) {
return;
}
TuTuGuideHelper guideHelper = new TuTuGuideHelper(context);
guideHelper.createHiGuide(() -> guideHelper.createVoiceMatchGuide(binding.svgaGroupVoiceLike, binding.layoutMyVoiceEntrance));
TuTuGuideHelper.setNoNeedHiGuide(TuTuGuideHelper.KEY_GUIDE_VOICE_MATCH);
}, 500);
}
private void queryHistoryVoice() {
AudioModel.get().queryHistoryVoice(AuthModel.get().getCurrentUid())
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new DontWarnObserver<HistoryVoiceInfo>() {
@Override
public void accept(HistoryVoiceInfo historyVoiceInfo, String error) {
super.accept(historyVoiceInfo, error);
if (error == null) {
if (historyVoiceInfo != null) {
HistoryVoiceInfo.HistoryVoiceBean historyVoice = historyVoiceInfo.getHistoryVoice();// 是否在旧版录制过打招呼
boolean hasVoice = historyVoiceInfo.isHasVoice();// 是否已录制声音,包括待审核、审核通过
if (historyVoice != null) {// 存在旧版的个人介绍声音:是否使用原来的打招呼或重新录制
showDialogWithSyncHistoryVoice(historyVoice);
SharedPreferenceUtils.put(KEY_VOICE_MUST_LIMIT + AuthModel.get().getCurrentUid(), true);// 存在旧版个人介绍声音,设置受限
} else {// 没有在旧版的打招呼中录制过声音
if (hasVoice) {// 录制过声音
SharedPreferenceUtils.put(KEY_VOICE_MUST_LIMIT + AuthModel.get().getCurrentUid(), false);// 没有在旧版录制过个人介绍 且 录制过声音瓶子,设置不受限
} else {// 没有录制过声音
SharedPreferenceUtils.put(KEY_VOICE_MUST_LIMIT + AuthModel.get().getCurrentUid(), true);// 没有在旧版录制过个人介绍 且 没有录制过声音瓶子,设置受限
}
}
} else {
SharedPreferenceUtils.put(KEY_VOICE_MUST_LIMIT + AuthModel.get().getCurrentUid(), true);// 请求成功但返回数据为空,设置受限
}
} else {
SharedPreferenceUtils.put(KEY_VOICE_MUST_LIMIT + AuthModel.get().getCurrentUid(), true);// 请求失败,设置受限
}
}
});
}
private void showDialogWithSyncHistoryVoice(HistoryVoiceInfo.HistoryVoiceBean voiceInfo) {
VmSoundManager.get().onPause(null);// 显示弹框的时候 暂停播放
// 弹窗:是否使用原来的打招呼或重新录制
View syncHistoryVoiceView = LayoutInflater.from(context).inflate(R.layout.dialog_custom_voice_match_sync_history_voice, null);
LinearLayout voiceBar = syncHistoryVoiceView.findViewById(R.id.layout_voice_bar);
playIcon = syncHistoryVoiceView.findViewById(R.id.iv_voice_bar_play);
if (voiceLine != null) {
voiceLine.stopAnim();
}
voiceLine = syncHistoryVoiceView.findViewById(R.id.layout_voice_line);
TextView voiceDuration = syncHistoryVoiceView.findViewById(R.id.tv_voice_duration);
voiceDuration.setText(String.format(Locale.getDefault(), "%ds", voiceInfo.getVoiceLength()));
voiceBar.setOnClickListener(view -> {
VmSoundManager.get().onPause(status -> {
if (status == VmSoundManager.ConstantStatus.playing ||
status == VmSoundManager.ConstantStatus.preparing) {
binding.flGroupContent.onlySetPlayOrStopIconForBigBottle(true);
}
});
if (AudioPlayerHelper.get().isPlaying()) {
stopVoice();
} else {
playVoice(voiceInfo.getVoiceUrl());
}
});
getDialogManager().showOkCancelCustomDialog(syncHistoryVoiceView, ResUtil.getString(R.string.erban_audio_voicematchactivity_03), ResUtil.getString(R.string.erban_audio_voicematchactivity_04),
false, new DialogManager.OkCancelDialogListener() {
@Override
public void onOk() {
// 确定使用旧版打招呼的声音上传到声音瓶子
stopVoice();
syncHistoryVoice(voiceInfo.getId());
}
@Override
public void onCancel() {
// 跳转到录制页面
//跳转界面时停止播放声音
stopVoice();
UIHelper.showRecordVoiceAct(VoiceMatchActivity.this, REQUEST_CODE_RECORDING_VOICE_WITH_SYNC_HISTORY_VOICE, voiceInfo.getId());
}
});
}
private void playVoice(String voice) {
AudioPlayerHelper.get().playInThread(voice, new OnPlayListener() {
@Override
public void onError(String error) {
refreshVoiceBarLayout(false);// 播放出错
}
@Override
public void onPrepared() {
refreshVoiceBarLayout(true);// 准备完毕开始播放
}
@Override
public void onPlaying(long currDuration) {
}
@Override
public void onCompletion() {
refreshVoiceBarLayout(false);// 播放完成
}
});
}
private void stopVoice() {
AudioPlayerHelper.get().endPlay();
refreshVoiceBarLayout(false);// 点击停止播放
}
private void refreshVoiceBarLayout(boolean isPlaying) {
if (playIcon != null) {
playIcon.post(() ->
// 切换图标
playIcon.setImageResource(isPlaying ?
R.drawable.ic_voice_bar_pause : R.drawable.ic_voice_bar_play));
}
if (voiceLine != null) {
voiceLine.stopAnim();
if (isPlaying) {
voiceLine.startAnim();
} else {
voiceLine.stopAnim();
}
}
}
private void syncHistoryVoice(long voiceId) {
getDialogManager().showProgressDialog(context, ResUtil.getString(R.string.erban_audio_voicematchactivity_07), false);
AudioModel.get().syncHistoryVoice(AuthModel.get().getCurrentUid(), voiceId)
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new DontWarnObserver<String>() {
@Override
public void accept(String s, String error) {
super.accept(s, error);
if (error == null) {
getDialogManager().dismissDialog();
SharedPreferenceUtils.put(KEY_VOICE_MUST_LIMIT + AuthModel.get().getCurrentUid(), false);// 同步历史声音到瓶子成功,设置不受限
} else {
getDialogManager().dismissDialog();
SingleToastUtil.showToast(error);
}
}
});
VmSoundManager.get().onResume(status -> {
if (status == VmSoundManager.ConstantStatus.playing ||
status == VmSoundManager.ConstantStatus.preparing) {
binding.flGroupContent.onlySetPlayOrStopIconForBigBottle(false);
}
});
}
@Override
public void initWhiteTitleBar(String title) {
super.initWhiteTitleBar(title);
binding.titleBar.addAction(new TitleBar.ImageAction(R.drawable.ic_voice_match_filter_gender) {
@Override
public void performAction(View view) {
if (isLoading) {
return;
}
// 筛选性别
if (filterGenderBottomDialog == null) {
filterGenderBottomDialog = new VoiceBottleFilterGenderBottomDialog(context, filterGender, gender -> {
String label = gender == 1 ? ResUtil.getString(R.string.erban_audio_voicematchactivity_08) : gender == 2 ? ResUtil.getString(R.string.erban_audio_voicematchactivity_09) : ResUtil.getString(R.string.erban_audio_voicematchactivity_010);
filterGender = gender;
SharedPreferenceUtils.put("voice_match_filter_gender_" + AuthModel.get().getCurrentUid(), filterGender);
//重新加载数据时,停止掉声音播放
VmSoundManager.get().getHelper().endPlay();
loadingData(gender);// 筛选性别 重新加载数据
});
}
filterGenderBottomDialog.show();
}
});
}
/**
* @param filterGender 1:男 2
*/
private void loadingData(int filterGender) {
if (isLoading) {
return;
}
binding.groupVoiceLayout.setVisibility(View.INVISIBLE);
showVoiceStatusLoadingView();
isLoading = true;
SvgaCacheManager.get().initSvga(context)
.observeOn(AndroidSchedulers.mainThread())
.flatMap((Function<String, SingleSource<List<VoiceMatchInfo>>>)
s -> AudioModel.get().getVoiceMatchList(filterGender, 10))
.delay(300, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new DontWarnObserver<List<VoiceMatchInfo>>() {
@Override
public void accept(List<VoiceMatchInfo> voiceMatchInfos, String error) {
super.accept(voiceMatchInfos, error);
if (isFinishing() || isDestroyed()) {
return;
}
if (TuTuGuideHelper.isNeedHiGuide(TuTuGuideHelper.KEY_GUIDE_VOICE_MATCH)
&& !ListUtils.isListEmpty(voiceMatchInfos)) {
showGuide();// 首次进入页面isNeedHiGuide且 请求成功数据不为空时,显示引导图
}
if (voiceMatchInfos != null) {
if (voiceMatchInfos.size() == 0) {
binding.groupVoiceLayout.setVisibility(View.INVISIBLE);
showVoiceStatusView(new VoiceRefreshListener(), R.drawable.icon_voice_no_bottle, ResUtil.getString(R.string.erban_audio_voicematchactivity_012));
} else {
hideVoiceStatusView();
binding.groupVoiceLayout.setVisibility(View.VISIBLE);
binding.flGroupContent.initData(voiceMatchInfos);
}
} else {
binding.groupVoiceLayout.setVisibility(View.INVISIBLE);
showVoiceStatusView(new VoiceRefreshListener(), R.drawable.icon_voice_net_error, ResUtil.getString(R.string.erban_audio_voicematchactivity_013));
}
if (isFirst) {
queryHistoryVoice();
isFirst = false;
}
isLoading = false;
}
});
}
/**
* 状态页面:网络出错 / 无数据
*/
private void showVoiceStatusView(OnRefreshListener listener, int statusImageId, String statusText) {
hideVoiceStatusView();
View view = View.inflate(context, R.layout.fragment_voice_status, null);
ImageView ivStatusImage = view.findViewById(R.id.iv_status_image);
ivStatusImage.setImageResource(statusImageId);
TextView tvStatusText = view.findViewById(R.id.tv_status_text);
tvStatusText.setText(statusText);
View stvRefresh = view.findViewById(R.id.stv_refresh);
if (listener != null) {
stvRefresh.setVisibility(View.VISIBLE);
stvRefresh.setOnClickListener(v -> listener.refresh());
} else {
stvRefresh.setVisibility(View.GONE);
}
binding.flStatusParent.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
}
private VoiceLine loadingLine;
private void releaseLoadingLine() {
if (loadingLine != null) {
loadingLine.stopAnim();
}
}
/**
* 状态页:正在加载
*/
private void showVoiceStatusLoadingView() {
hideVoiceStatusView();
View view = View.inflate(context, R.layout.fragment_voice_status_loading, null);
releaseLoadingLine();
loadingLine = view.findViewById(R.id.voice_line);
loadingLine.post(loadingLine::startAnim);
TextView tvStatusText = view.findViewById(R.id.tv_status_text);
tvStatusText.setText(ResUtil.getString(R.string.erban_audio_voicematchactivity_014));
binding.flStatusParent.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
}
/**
* 清除状态页
*/
private void hideVoiceStatusView() {
binding.flStatusParent.removeAllViews();
}
@Override
protected void onDestroy() {
super.onDestroy();
binding.flGroupContent.onDestroy();
VmSoundManager.get().onDestroy();
AudioPlayerHelper.get().onDestroy();
SvgaCacheManager.get().onDestroy();
if (showAnim != null) {
showAnim.cancel();
showAnim = null;
}
if (alphaAnimation != null) {
alphaAnimation.cancel();
alphaAnimation = null;
}
releaseLoadingLine();
if (voiceLine != null) {
voiceLine.stopAnim();
}
}
private void toNext(boolean isLike) {
boolean isLimit = (boolean) SharedPreferenceUtils.get(KEY_VOICE_MUST_LIMIT + AuthModel.get().getCurrentUid(), true);
if (isLimit) {
binding.flGroupContent.dealBigBottleLimit(isLike);
} else {
playLikeOrUnLikeBtnAnim(isLike, true);
}
}
private void playLikeOrUnLikeBtnAnim(boolean isLike, boolean isNeedDealToNext) {
if (!isLike) {
//播放不喜欢按钮的属性动画
if (helper.isDontLikeAnimRun()) {
return;
}
helper.playDontLikeAnim(binding.ivGroupDontLike);
} else {
if (binding.svgaGroupVoiceLike.isAnimating()) {
return;
}
binding.flGroupContent.addBigBottleLikeCount();
helper.playDontLikeAnim(binding.ivGroupLike);
//播放喜欢按钮的svga动画
binding.svgaGroupVoiceLike.startAnimation();
binding.svgaGroupVoiceLike.setCallback(new SVGACallback() {
@Override
public void onPause() {
}
@Override
public void onFinished() {
}
@Override
public void onRepeat() {
}
@Override
public void onStep(int i, double v) {
}
});
}
if (isNeedDealToNext) {
binding.flGroupContent.dealToNext(isLike);
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.layout_my_voice_entrance:
if (isLoading) {
return;
}
UIHelper.showMyVoiceAct(VoiceMatchActivity.this, REQUEST_CODE_RECORDING_VOICE_WITH_MY_VOICE, ResUtil.getString(R.string.erban_audio_voicematchactivity_015));// 跳转到我的声音页面
break;
case R.id.iv_group_dont_like:
toNext(false);
break;
case R.id.svga_group_voice_like:
toNext(true);
break;
}
}
private void showDialogWithHasLimit(boolean isRight) {
String showMessage;
if (isRight) {
showMessage = ResUtil.getString(R.string.erban_audio_voicematchactivity_018);
} else {
showMessage = ResUtil.getString(R.string.erban_audio_voicematchactivity_019);
}
getDialogManager().showTipsDialog(showMessage, ResUtil.getString(R.string.erban_audio_voicematchactivity_020), () -> {
// 跳转到录制页面
UIHelper.showRecordVoiceAct(VoiceMatchActivity.this, REQUEST_CODE_RECORDING_VOICE_WITH_HAS_LIMIT, -1);
});
}
private void likeOrUnlikeVoice(VoiceMatchInfo info, boolean isRight, boolean needLoading) {
AudioModel.get().likeOrUnlikeVoice(AuthModel.get().getCurrentUid(), info.getId(), isRight ? 1 : 0)
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new DontWarnObserver<String>() {
@Override
public void accept(String s, String error) {
super.accept(s, error);
if (needLoading) {
loadingData(filterGender);
}
if (error == null) {
if (isRight) {
NimP2PMessageActivity.start(context, String.valueOf(info.getUid()), true);
}
}
}
});
}
public class VoiceRefreshListener implements OnRefreshListener {
@Override
public void refresh() {
loadingData(filterGender);// 状态页面刷新一下 重新加载数据
}
}
@Override
protected void onResume() {
super.onResume();
PlayerModel.get().pause();
VmSoundManager.get().onResume(status -> {
if (status == VmSoundManager.ConstantStatus.playing ||
status == VmSoundManager.ConstantStatus.preparing) {
binding.flGroupContent.onlySetPlayOrStopIconForBigBottle(false);
}
});
}
@Override
protected void onPause() {
super.onPause();
PlayerModel.get().play(null);
VmSoundManager.get().onPause(status -> {
if (status == VmSoundManager.ConstantStatus.playing ||
status == VmSoundManager.ConstantStatus.preparing) {
binding.flGroupContent.onlySetPlayOrStopIconForBigBottle(true);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_RECORDING_VOICE_WITH_MY_VOICE) {
showMyVoiceEntranceAnim();
}
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CODE_RECORDING_VOICE_WITH_HAS_LIMIT && data != null) {
SharedPreferenceUtils.put(KEY_VOICE_MUST_LIMIT + AuthModel.get().getCurrentUid(), false);// 录制完声音,重置不受限制
} else if (requestCode == REQUEST_CODE_RECORDING_VOICE_WITH_MY_VOICE && data != null) {
SharedPreferenceUtils.put(KEY_VOICE_MUST_LIMIT + AuthModel.get().getCurrentUid(), false);// 录制完声音,重置不受限制
}
}
if (requestCode == REQUEST_CODE_RECORDING_VOICE_WITH_SYNC_HISTORY_VOICE) {
queryHistoryVoice();// 重新查询是否有历史声音
}
}
}

View File

@@ -0,0 +1,120 @@
package com.chwl.app.audio.adapter;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.core.audio.bean.VoiceCardInfo;
import java.util.ArrayList;
import java.util.List;
/**
* 录制声音页面的声音卡片
*/
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardVH> {
private List<VoiceCardInfo> dataList;
private OnVoiceCardChangeButtonClickListener onVoiceCardChangeButtonClickListener;
public CardAdapter(List<VoiceCardInfo> cardInfoList) {
if (cardInfoList == null) {
cardInfoList = new ArrayList<>();
}
this.dataList = cardInfoList;
}
@NonNull
@Override
public CardVH onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fragment_voice_card, viewGroup, false);
return new CardVH(itemView);
}
@Override
public void onBindViewHolder(@NonNull CardVH cardVH, int i) {
if (dataList.get(i) == null) {
return;
}
if (i == 0) {
cardVH.layout.setAlpha(1);
cardVH.title.setAlpha(1);
cardVH.content.setAlpha(1);
} else if (i == 1) {
cardVH.layout.setAlpha(0.5f);
cardVH.title.setAlpha(0);
cardVH.content.setAlpha(0);
} else if (i == 2) {
cardVH.layout.setAlpha(0.3f);
cardVH.title.setAlpha(0);
cardVH.content.setAlpha(0);
} else {
cardVH.layout.setAlpha(0);
cardVH.title.setAlpha(0);
cardVH.content.setAlpha(0);
}
cardVH.title.setText(dataList.get(i).getTitle());
cardVH.content.setText(dataList.get(i).getPlayBook());
cardVH.changeButton.setVisibility(i == 0 ? View.VISIBLE : View.GONE);
cardVH.changeButton.setOnClickListener(view -> {
if (onVoiceCardChangeButtonClickListener != null) {
onVoiceCardChangeButtonClickListener.onVoiceCardChange(cardVH);
}
});
cardVH.content.post(() -> {
// 超过五行显示阴影
cardVH.shadow.setVisibility(cardVH.content.getLineCount() > 5 ? View.VISIBLE : View.GONE);
});
}
@Override
public int getItemCount() {
return dataList.size();
}
public void removeItem(int pos) {
dataList.remove(pos);
notifyDataSetChanged();
}
public VoiceCardInfo getFistItemInfo() {
return dataList.get(0);
}
public class CardVH extends RecyclerView.ViewHolder {
FrameLayout layout;
TextView title;
TextView content;
RelativeLayout changeButton;
View shadow;
CardVH(@NonNull View itemView) {
super(itemView);
layout = itemView.findViewById(R.id.layout_voice_card);
title = itemView.findViewById(R.id.tv_voice_card_title);
content = itemView.findViewById(R.id.tv_voice_card_content);
changeButton = itemView.findViewById(R.id.layout_voice_card_change);
shadow = itemView.findViewById(R.id.iv_voice_card_bottom_shadow);
content.setMovementMethod(ScrollingMovementMethod.getInstance());
}
}
public interface OnVoiceCardChangeButtonClickListener {
void onVoiceCardChange(RecyclerView.ViewHolder viewHolder);
}
public void setOnVoiceCardChangeButtonClickListener(OnVoiceCardChangeButtonClickListener onVoiceCardChangeButtonClickListener) {
this.onVoiceCardChangeButtonClickListener = onVoiceCardChangeButtonClickListener;
}
}

View File

@@ -0,0 +1,262 @@
package com.chwl.app.audio.adapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chwl.app.R;
import com.chwl.app.audio.widget.VoiceLine;
import com.chwl.core.audio.bean.UserVoiceInfo;
import com.chwl.core.utils.StringFormatUtils;
import com.chwl.library.utils.ResUtil;
import java.util.List;
import java.util.Locale;
/**
* 我的声音.审核通过状态的列表
*/
public class MyVoiceListAdapter extends BaseQuickAdapter<UserVoiceInfo, BaseViewHolder> {
private OnVerifiedVoiceItemClickListener onVerifiedVoiceItemClickListener;
private boolean isPlayingVoice;
private int voiceClickPos = -1;
private static final int TYPE_IN_REVIEW = 0;
private static final int TYPE_VERIFIED = 1;
private static final int TYPE_NO_SUBMITTED = 2;
public MyVoiceListAdapter(@Nullable List<UserVoiceInfo> data) {
super(data);
}
@Override
public int getItemViewType(int position) {
UserVoiceInfo item = getItem(position);
if (item == null) {
return TYPE_NO_SUBMITTED;
} else {
return item.getStatus();
}
}
@Override
protected BaseViewHolder onCreateDefViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_IN_REVIEW) {
return onCreateViewHolderWithInReview(parent);
} else if (viewType == TYPE_VERIFIED) {
return onCreateViewHolderWithVerified(parent);
} else {
return onCreateViewHolderWithNoSubmitted(parent);
}
}
private BaseViewHolder onCreateViewHolderWithInReview(ViewGroup parent) {
return new InReviewViewHolder(mLayoutInflater.inflate(R.layout.item_my_voice_in_review, parent, false));
}
private BaseViewHolder onCreateViewHolderWithVerified(ViewGroup parent) {
return new VerifiedViewHolder(mLayoutInflater.inflate(R.layout.item_my_voice_verified, parent, false));
}
private BaseViewHolder onCreateViewHolderWithNoSubmitted(ViewGroup parent) {
return new NoSubmittedViewHolder(mLayoutInflater.inflate(R.layout.item_my_voice_no_submitted, parent, false));
}
@Override
protected void convert(BaseViewHolder helper, UserVoiceInfo item) {
if (item == null) {
return;
}
if (helper instanceof InReviewViewHolder) {
onBindViewHolderWithInReview((InReviewViewHolder) helper, item);
} else if (helper instanceof VerifiedViewHolder) {
onBindViewHolderWithVerified((VerifiedViewHolder) helper, item);
} else if (helper instanceof NoSubmittedViewHolder) {
onBindViewHolderWithNoSubmitted((NoSubmittedViewHolder) helper, item);
}
}
private void onBindViewHolderWithInReview(InReviewViewHolder helper, UserVoiceInfo item) {
helper.tvDuration.setText(String.format(Locale.getDefault(), "%ds", item.getVoiceLength()));// 声音时长
// 播放动画
if (helper.voiceLine != null) {
helper.voiceLine.stopAnim();
}
helper.ivVoicePlay.post(() -> {
if (helper.getAdapterPosition() == voiceClickPos) {
if (isPlayingVoice) {
helper.ivVoicePlay.setImageResource(R.drawable.ic_voice_bar_pause);
helper.voiceLine.startAnim();
} else {
helper.ivVoicePlay.setImageResource(R.drawable.ic_voice_bar_play);
helper.voiceLine.stopAnim();
}
} else {
helper.ivVoicePlay.setImageResource(R.drawable.ic_voice_bar_play);
helper.voiceLine.stopAnim();
}
});
// 点击播放声音/停止声音
helper.voiceBarLayout.setOnClickListener(view -> {
if (StringFormatUtils.isEmpty(item.getVoiceUrl())) {
return;
}
boolean isChange = helper.getAdapterPosition() != voiceClickPos;
voiceClickPos = helper.getAdapterPosition();
if (onVerifiedVoiceItemClickListener != null) {
onVerifiedVoiceItemClickListener.onVoiceClick(isChange, item.getVoiceUrl());
}
});
// 点击重新录制:跳转到录制声音页面
helper.addOnClickListener(helper.tvReRecord.getId());
}
private void onBindViewHolderWithVerified(VerifiedViewHolder helper, UserVoiceInfo item) {
helper.tvDuration.setText(String.format(Locale.getDefault(), "%ds", item.getVoiceLength()));// 声音时长
// 播放动画
if (helper.voiceLine != null) {
helper.voiceLine.stopAnim();
}
helper.ivVoicePlay.post(() -> {
if (helper.getAdapterPosition() == voiceClickPos) {
if (isPlayingVoice) {
helper.ivVoicePlay.setImageResource(R.drawable.ic_voice_bar_pause);
helper.voiceLine.startAnim();
} else {
helper.ivVoicePlay.setImageResource(R.drawable.ic_voice_bar_play);
helper.voiceLine.stopAnim();
}
} else {
helper.ivVoicePlay.setImageResource(R.drawable.ic_voice_bar_play);
helper.voiceLine.stopAnim();
}
});
// 点击播放声音/停止声音
helper.voiceBarLayout.setOnClickListener(view -> {
if (StringFormatUtils.isEmpty(item.getVoiceUrl())) {
return;
}
boolean isChange = helper.getAdapterPosition() != voiceClickPos;
voiceClickPos = helper.getAdapterPosition();
if (onVerifiedVoiceItemClickListener != null) {
onVerifiedVoiceItemClickListener.onVoiceClick(isChange, item.getVoiceUrl());
}
});
// 点击重新录制:跳转到录制声音页面
helper.addOnClickListener(helper.tvReRecord.getId());
helper.tvHeardCount.setText(String.format(Locale.getDefault(), ResUtil.getString(R.string.audio_adapter_myvoicelistadapter_01), item.getPlayCount()));// 听过人数
helper.tvLikeCount.setText(String.format(Locale.getDefault(), ResUtil.getString(R.string.audio_adapter_myvoicelistadapter_02), item.getLikeCount()));// 喜欢人数
}
private void onBindViewHolderWithNoSubmitted(NoSubmittedViewHolder helper, UserVoiceInfo item) {
helper.tvDuration.setText(String.format(Locale.getDefault(), "%ds", item.getVoiceLength()));// 声音时长
// 播放动画
if (helper.voiceLine != null) {
helper.voiceLine.stopAnim();
}
helper.ivVoicePlay.post(() -> {
if (helper.getAdapterPosition() == voiceClickPos) {
if (isPlayingVoice) {
helper.ivVoicePlay.setImageResource(R.drawable.ic_voice_bar_pause);
helper.voiceLine.startAnim();
} else {
helper.ivVoicePlay.setImageResource(R.drawable.ic_voice_bar_play);
helper.voiceLine.stopAnim();
}
} else {
helper.ivVoicePlay.setImageResource(R.drawable.ic_voice_bar_play);
helper.voiceLine.stopAnim();
}
});
// 点击播放声音/停止声音
helper.voiceBarLayout.setOnClickListener(view -> {
if (StringFormatUtils.isEmpty(item.getVoiceUrl())) {
return;
}
boolean isChange = helper.getAdapterPosition() != voiceClickPos;
voiceClickPos = helper.getAdapterPosition();
if (onVerifiedVoiceItemClickListener != null) {
onVerifiedVoiceItemClickListener.onVoiceClick(isChange, item.getVoiceUrl());
}
});
// 点击重新录制:跳转到录制声音页面
helper.addOnClickListener(helper.tvReRecord.getId());
}
public void changePlayState(boolean isPlaying) {
this.isPlayingVoice = isPlaying;
notifyDataSetChanged();
}
private class InReviewViewHolder extends BaseViewHolder {
LinearLayout voiceBarLayout;
ImageView ivVoicePlay;
VoiceLine voiceLine;
TextView tvDuration;
TextView tvReRecord;
InReviewViewHolder(View view) {
super(view);
voiceBarLayout = view.findViewById(R.id.layout_voice_bar);
ivVoicePlay = view.findViewById(R.id.iv_voice_bar_play);
voiceLine = view.findViewById(R.id.layout_voice_line);
tvDuration = view.findViewById(R.id.tv_voice_duration);
tvReRecord = view.findViewById(R.id.tv_re_recording);
}
}
private class VerifiedViewHolder extends BaseViewHolder {
LinearLayout voiceBarLayout;
ImageView ivVoicePlay;
VoiceLine voiceLine;
TextView tvDuration;
TextView tvReRecord;
TextView tvHeardCount, tvLikeCount;
VerifiedViewHolder(View view) {
super(view);
voiceBarLayout = view.findViewById(R.id.layout_voice_bar);
ivVoicePlay = view.findViewById(R.id.iv_voice_bar_play);
voiceLine = view.findViewById(R.id.layout_voice_line);
tvDuration = view.findViewById(R.id.tv_voice_duration);
tvReRecord = view.findViewById(R.id.tv_re_recording);
tvHeardCount = view.findViewById(R.id.tv_voice_heard_count);
tvLikeCount = view.findViewById(R.id.tv_voice_like_count);
}
}
private class NoSubmittedViewHolder extends BaseViewHolder {
LinearLayout voiceBarLayout;
ImageView ivVoicePlay;
VoiceLine voiceLine;
TextView tvDuration;
TextView tvReRecord;
NoSubmittedViewHolder(View view) {
super(view);
voiceBarLayout = view.findViewById(R.id.layout_voice_bar);
ivVoicePlay = view.findViewById(R.id.iv_voice_bar_play);
voiceLine = view.findViewById(R.id.layout_voice_line);
tvDuration = view.findViewById(R.id.tv_voice_duration);
tvReRecord = view.findViewById(R.id.tv_re_recording);
}
}
public interface OnVerifiedVoiceItemClickListener {
void onVoiceClick(boolean isChange, String voice);
}
public void setOnVerifiedVoiceItemClickListener(OnVerifiedVoiceItemClickListener onVerifiedVoiceItemClickListener) {
this.onVerifiedVoiceItemClickListener = onVerifiedVoiceItemClickListener;
}
}

View File

@@ -0,0 +1,221 @@
package com.chwl.app.audio.helper;
import android.annotation.SuppressLint;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import com.chwl.app.R;
import com.chwl.library.utils.ResUtil;
import java.io.IOException;
/**
* create by lvzebiao @2019/6/14
*/
public class AudioPlayerHelper {
private final static long mIntervalTime = 16L;
public interface WHAT_STATUS {
int ERROR = 1;
int COUNT_PLAY = 2;
int COMPLETION = 3;
int PREPARED = 4;
}
private static final class Helper {
public static final AudioPlayerHelper INSTANCE = new AudioPlayerHelper();
}
public static AudioPlayerHelper get() {
return Helper.INSTANCE;
}
private MediaPlayer player;
private String audioFile;
private boolean isLoop;
public void onCreate() {
}
public void onPause() {
endPlay();
}
public void onDestroy() {
endPlay();
}
private boolean preparing = false;
private boolean pause = false;
public void playInThread(String filePath, OnPlayListener l) {
playInThread(filePath, false, l);
}
public void rePlayInThread() {
if (listener != null && !TextUtils.isEmpty(audioFile)) {
playInThread(audioFile, isLoop, listener);
}
}
public void playInThread(String filePath, boolean isLoop, OnPlayListener l) {
endPlay();
this.listener = l;
if (listener != null) {
listener.onPreStart();
}
this.audioFile = filePath;
this.isLoop = isLoop;
player = new MediaPlayer();
player.setLooping(isLoop);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
player.setDataSource(filePath);
} catch (IOException e) {
e.printStackTrace();
}
preparing = true;
try {
player.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
preparing = false;
handler.sendEmptyMessage(WHAT_STATUS.ERROR);
}
player.setOnPreparedListener(mp -> {
if (player != null) {
player.start();
}
preparing = false;
handler.sendEmptyMessage(WHAT_STATUS.PREPARED);
});
player.setOnErrorListener((mp, what, extra) -> {
handler.sendEmptyMessage(WHAT_STATUS.ERROR);
return false;
});
player.setOnCompletionListener(mp -> {
handler.removeMessages(WHAT_STATUS.COUNT_PLAY);
handler.sendEmptyMessage(WHAT_STATUS.COMPLETION);
});
}
public void endPlay() {
if (listener != null) {
listener.onCompletion();
}
handler.removeMessages(WHAT_STATUS.COUNT_PLAY);
if (player != null) {
if (preparing) {
player.setOnPreparedListener(null);
player.setOnErrorListener(null);
player.setOnCompletionListener(null);
}
if (player.isPlaying() && !preparing) {
player.stop();
}
player.release();
player = null;
}
preparing = false;
pause = false;
this.listener = null;
this.audioFile = null;
}
public void releaseWhenPreparing() {
handler.removeMessages(WHAT_STATUS.COUNT_PLAY);
if (player != null) {
if (player.isPlaying()) {
player.stop();
}
player.setOnErrorListener(null);
player.setOnPreparedListener(null);
player.setOnCompletionListener(null);
player.release();
player = null;
}
preparing = false;
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case WHAT_STATUS.ERROR:
if (listener != null) {
listener.onError(ResUtil.getString(R.string.audio_helper_audioplayerhelper_01));
}
break;
case WHAT_STATUS.PREPARED:
preparing = false;
if (listener != null) {
listener.onPrepared();
}
handler.sendEmptyMessage(WHAT_STATUS.COUNT_PLAY);
break;
case WHAT_STATUS.COUNT_PLAY:
if (listener != null) {
if (player != null) {
listener.onPlaying(player.getCurrentPosition());
}
}
sendEmptyMessageDelayed(WHAT_STATUS.COUNT_PLAY, mIntervalTime);
break;
case WHAT_STATUS.COMPLETION:
preparing = false;
if (listener != null) {
listener.onCompletion();
}
break;
}
}
};
public void pausePlay() {
if (player == null) {
return;
}
if (isPlaying()) {
player.pause();
pause = true;
}
}
public void continuePlay() {
if (player == null) {
return;
}
player.start();
pause = false;
}
private OnPlayListener listener;
public boolean isPlaying() {
return player != null && player.isPlaying();
}
public boolean isPause() {
return pause;
}
public boolean isPreparing() {
return preparing;
}
public long getDuration() {
return player == null ? 0 : player.getDuration();
}
}

View File

@@ -0,0 +1,39 @@
package com.chwl.app.audio.helper;
/**
* create by lvzebiao @2019/6/17
*/
public interface OnPlayListener {
/**
* 播放之前的操作
*/
default void onPreStart() {
}
/**
* 出错了
* 1. prepare 出错
* 2. setOnErrorListener 回调
*/
void onError(String error);
/**
* 准备完毕
* 1. setOnPreparedListener 回调
*/
void onPrepared();
/**
* 播放中
* 1. onPlaying
*/
void onPlaying(long currDuration);
/**
* 播放完毕回调
* 1. setOnCompletionListener 回调
*/
void onCompletion();
}

View File

@@ -0,0 +1,10 @@
package com.chwl.app.audio.helper;
/**
* create by lvzebiao @2019/6/11
*/
public interface OnRefreshListener {
void refresh();
}

View File

@@ -0,0 +1,171 @@
package com.chwl.app.audio.helper;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import com.opensource.svgaplayer.SVGADrawable;
import com.opensource.svgaplayer.SVGAParser;
import com.opensource.svgaplayer.SVGAVideoEntity;
import javax.annotation.Nullable;
import io.reactivex.Single;
import io.reactivex.SingleOnSubscribe;
import io.reactivex.schedulers.Schedulers;
import lombok.Getter;
/**
* create by lvzebiao @2019/6/21
*/
public class SvgaCacheManager {
private boolean voiceMatchActivityHasDestroy;
/**
* 大瓶子水波纹
*/
@Getter
private SVGADrawable bigBottleSvga;
/**
* 大瓶子气泡
*/
@Getter
private SVGADrawable bigBubbleSvga;
/**
* 小瓶子水波纹
*/
@Getter
private SVGADrawable smallBottleSvga;
/**
* 小瓶子气泡
*/
@Getter
private SVGADrawable smallBubbleSvga;
private static SvgaCacheManager instance;
private SvgaCacheManager() {
}
public static SvgaCacheManager get() {
if (instance == null) {
instance = new SvgaCacheManager();
}
return instance;
}
public Single<String> initSvga(Context context) {
if (!isMoreAndroid7_0()) {
return Single.just("");
}
if (bigBottleSvga != null && bigBubbleSvga != null &&
smallBottleSvga != null && smallBubbleSvga != null) {
return Single.just("");
}
SVGAParser parser = new SVGAParser(context);
return Single.just("")
.flatMap(s -> {
if (bigBottleSvga == null) {
return createSvga(parser, true, true);
}
return Single.just("");
})
.flatMap(s -> {
if (bigBubbleSvga == null) {
return createSvga(parser, true, false);
}
return Single.just("");
})
.flatMap(s -> {
if (smallBottleSvga == null) {
return createSvga(parser, false, true);
}
return Single.just("");
})
.flatMap(s -> {
if (smallBubbleSvga == null) {
return createSvga(parser, false, false);
}
return Single.just("");
});
}
private Single<String> createSvga(SVGAParser parser, boolean isBig, boolean isBottle) {
return Single.create((SingleOnSubscribe<String>) emitter -> {
String path = isBottle ? "svga/svga_voice_bottle.svga" : "svga/svga_voice_bubble.svga";
parser.decodeFromAssets(path, new SVGAParser.ParseCompletion() {
@Override
public void onComplete(@Nullable SVGAVideoEntity svgaVideoEntity) {
if (isBig) {
if (isBottle) {
bigBottleSvga = new SVGADrawable(svgaVideoEntity);
} else {
bigBubbleSvga = new SVGADrawable(svgaVideoEntity);
}
} else {
if (isBottle) {
smallBottleSvga = new SVGADrawable(svgaVideoEntity);
} else {
smallBubbleSvga = new SVGADrawable(svgaVideoEntity);
}
}
emitter.onSuccess("");
}
@Override
public void onError() {
emitter.onError(new Throwable("svga error"));
}
},null);
}).subscribeOn(Schedulers.io());
}
public void onCreate() {
if (!isMoreAndroid7_0()) {
return;
}
voiceMatchActivityHasDestroy = false;
handler.removeMessages(0);
}
public void onDestroy() {
if (!isMoreAndroid7_0()) {
return;
}
voiceMatchActivityHasDestroy = true;
//发送消息释放资源,资源存活时间过后再回收,防止频繁调用声音匹配界面
handler.sendEmptyMessageDelayed(0, 90 * 1000);
}
private void release() {
bigBottleSvga = null;
bigBubbleSvga = null;
smallBottleSvga = null;
smallBubbleSvga = null;
instance = null;
//gc
System.gc();
}
@SuppressLint("HandlerLeak")
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
release();
}
};
/**
* 是否是android 7.0或者以上
*/
public boolean isMoreAndroid7_0() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
}
}

View File

@@ -0,0 +1,77 @@
package com.chwl.app.audio.helper;
import lombok.Getter;
/**
* 声音匹配界面播放管理,写一个单例类,管理
* create by lvzebiao @2019/6/20
*/
public class VmSoundManager {
public interface ConstantStatus {
int init = 0;
/**准备播放的状态*/
int preparing = 1;
/**播放中的状态*/
int playing = 2;
}
private int playStatus = 0;
private static final class Helper {
public static final VmSoundManager INSTANCE = new VmSoundManager();
}
public static VmSoundManager get() {
return Helper.INSTANCE;
}
@Getter
private AudioPlayerHelper helper;
public void onCreate() {
helper = new AudioPlayerHelper();
helper.onCreate();
}
public void onResume(OnResumeListener onResumeListener) {
if (playStatus == ConstantStatus.playing) {
VmSoundManager.get().getHelper().continuePlay();
} else if (playStatus == ConstantStatus.preparing) {
VmSoundManager.get().getHelper().rePlayInThread();
}
if (onResumeListener != null) {
onResumeListener.onHandleResume(playStatus);
}
playStatus = ConstantStatus.init;
}
public void onPause(OnPauseListener onPauseListener) {
if (VmSoundManager.get().getHelper().isPlaying()) {
VmSoundManager.get().getHelper().pausePlay();
playStatus = ConstantStatus.playing;
} else if (VmSoundManager.get().getHelper().isPreparing()) {
VmSoundManager.get().getHelper().releaseWhenPreparing();
playStatus = ConstantStatus.preparing;
}
if (onPauseListener != null) {
onPauseListener.onHandlePause(playStatus);
}
}
public void onDestroy() {
if (helper != null) {
helper.onDestroy();
}
}
public interface OnResumeListener {
void onHandleResume(int status);
}
public interface OnPauseListener {
void onHandlePause(int status);
}
}

View File

@@ -0,0 +1,36 @@
package com.chwl.app.audio.helper;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.view.View;
import lombok.Getter;
/**
* create by lvzebiao @2019/6/11
*/
public class VoiceMacthHelper {
@Getter
private boolean dontLikeAnimRun;
public void playDontLikeAnim(View view) {
dontLikeAnimRun = true;
ObjectAnimator animatorX = ObjectAnimator.ofFloat(view, "scaleX", 1.0f, 0.9f, 1.2f, 1.0f);
ObjectAnimator animatorY = ObjectAnimator.ofFloat(view, "scaleY", 1.0f, 0.9f, 1.2f, 1.0f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(600);
animatorSet.play(animatorX).with(animatorY);
animatorSet.start();
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
dontLikeAnimRun = false;
}
});
}
}

View File

@@ -0,0 +1,35 @@
package com.chwl.app.audio.presenter;
import com.chwl.app.audio.view.IMyVoiceView;
import com.chwl.app.base.BaseMvpPresenter;
import com.chwl.core.audio.AudioModel;
import com.chwl.core.audio.bean.UserVoiceInfo;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.utils.net.DontWarnObserver;
import com.chwl.library.base.PresenterEvent;
import java.util.List;
/**
* 我的声音页面
*/
public class MyVoicePresenter extends BaseMvpPresenter<IMyVoiceView> {
public void getUserVoiceInfo() {
getMvpView().showLoadingView();
AudioModel.get().getMyVoiceInfoList(AuthModel.get().getCurrentUid())
.compose(bindUntilEvent(PresenterEvent.DESTROY))
.subscribe(new DontWarnObserver<List<UserVoiceInfo>>() {
@Override
public void accept(List<UserVoiceInfo> userVoiceInfos, String error) {
super.accept(userVoiceInfos, error);
if (getMvpView() == null) {
return;
}
getMvpView().hideLoadingView();
getMvpView().showVoiceInfo(userVoiceInfos);
}
});
}
}

View File

@@ -0,0 +1,462 @@
package com.chwl.app.audio.presenter;
import static com.chwl.app.audio.RecordingVoiceActivity.AUDIO_DURA;
import static com.chwl.app.audio.RecordingVoiceActivity.AUDIO_FILE;
import static com.chwl.app.audio.RecordingVoiceActivity.MIN_RECORD_VOICE_DURATION;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
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.chwl.app.R;
import com.chwl.app.audio.helper.AudioPlayerHelper;
import com.chwl.app.audio.helper.OnPlayListener;
import com.chwl.app.audio.view.IRecordingVoiceView;
import com.chwl.app.base.BaseMvpPresenter;
import com.chwl.core.audio.AudioModel;
import com.chwl.core.audio.AudioPlayAndRecordManager;
import com.chwl.core.audio.bean.SaveVoiceSuccessResultInfo;
import com.chwl.core.audio.bean.VoiceCardInfo;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.file.FileModel;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.core.utils.net.DontWarnObserver;
import com.chwl.library.base.PresenterEvent;
import com.chwl.library.utils.ListUtils;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.SingleToastUtil;
import com.chwl.library.utils.log.MLog;
import java.io.File;
import java.util.List;
import io.reactivex.SingleObserver;
import io.reactivex.disposables.Disposable;
/**
* 录制声音页面
*/
public class RecordingVoicePresenter extends BaseMvpPresenter<IRecordingVoiceView> {
private static final String TAG = "RecordingVoiceActivity";
public static final int STATE_RECORD_NORMAL = 0;
public static final int STATE_RECORD_RECORDING = 1;
public static final int STATE_RECORD_SUCCESS = 2;
private int audioState = STATE_RECORD_NORMAL;
private AudioPlayAndRecordManager audioManager;
private AudioRecorder audioRecorder;
private File audioFile;
private int audioDur;
private String audioUrl;
private static final int WHAT_COUNT_PLAY = 1;
/**
* 获取卡片信息
*/
public void getCardInfo() {
AudioModel.get().getVoiceCardInfoList(AuthModel.get().getCurrentUid(), null, 10)
.compose(bindUntilEvent(PresenterEvent.DESTROY))
.subscribe(new DontWarnObserver<List<VoiceCardInfo>>() {
@Override
public void accept(List<VoiceCardInfo> voiceCardInfos, String error) {
super.accept(voiceCardInfos, error);
if (getMvpView() == null) {
return;
}
if (error == null) {
if (ListUtils.isListEmpty(voiceCardInfos)) {
return;
}
getMvpView().addCardInfo(voiceCardInfos);
}
}
});
}
/**
* 初始化资源
*/
public void initResource() {
audioManager = AudioPlayAndRecordManager.getInstance();
}
/**
* 离开页面处理
*/
public void leaveThePage() {
if (audioRecorder != null && audioRecorder.isRecording()) {
stopRecord();// 录制过程被中断(如点了返回按钮或电话接入等):【自动跳转到试听状态】停止录音
return;
}
if (AudioPlayerHelper.get().isPlaying()) {
AudioPlayerHelper.get().endPlay();
if (getMvpView() != null) {
getMvpView().refreshListenerButton(false);// 返回页面时,此时正在播放声音,则停止播放并显示停止状态(播放按钮)
}
}
if (audioState == STATE_RECORD_SUCCESS) {// 已经录制未保存:未保存提示(确定则返回页面/取消则保留当前页面)
if (getMvpView() != null) {
getMvpView().showConfirmDialogWithLeave();
}
} else {
if (getMvpView() != null) {
getMvpView().finishView(null);// 退出页面
}
}
}
/**
* onPause()回调
*/
public void pausePage() {
// 正在录制:则停止录制
if (audioRecorder != null && audioRecorder.isRecording()) {
stopRecord();// onPause()时,如果正在录制,则停止录制
}
// 正在播放:停止播放
AudioPlayerHelper.get().onPause();
if (getMvpView() != null) {
getMvpView().refreshListenerButton(false);// onPause() 停止播放并显示停止状态(播放按钮)
}
}
/**
* 重录
*/
public void reRecord() {
if (audioState == STATE_RECORD_SUCCESS) {
AudioPlayerHelper.get().endPlay();
showNormalState();// 点击重录,回到初始状态
}
}
/**
* 试听按钮
*/
public void clickRightIcon() {
if (audioState == STATE_RECORD_SUCCESS) {
if (AudioPlayerHelper.get().isPlaying()) {
AudioPlayerHelper.get().pausePlay();
if (getMvpView() != null) {
getMvpView().refreshListenerButton(false);// 点击试听按钮此时正在播放声音,则暂停播放并显示停止状态(播放按钮)
}
} else if (AudioPlayerHelper.get().isPause()) {
AudioPlayerHelper.get().continuePlay();
if (getMvpView() != null) {
getMvpView().refreshListenerButton(true);// 点击试听按钮此时正在暂停声音,则继续播放并显示播放状态(停止按钮)
}
} else if (AudioPlayerHelper.get().isPreparing()) {
AudioPlayerHelper.get().endPlay();
if (getMvpView() != null) {
getMvpView().refreshListenerButton(false);// 点击试听按钮此时正在准备状态,则停止播放并显示停止状态(播放按钮)
}
} else {
if (null != audioFile && audioFile.exists()) {
MLog.debug(TAG, "play audioFilePath: " + audioFile.getPath());
AudioPlayerHelper.get().playInThread(audioFile.getPath(), new OnPlayListener() {
@Override
public void onError(String error) {
if (getMvpView() != null) {
getMvpView().refreshListenerButton(false);// 出错:停止状态(播放按钮)
}
}
@Override
public void onPrepared() {
if (getMvpView() != null) {
getMvpView().refreshListenerButton(true);// 准备完毕要开始播放:播放状态(暂停按钮)
}
}
@Override
public void onPlaying(long currDuration) {
MLog.debug(TAG, "duration = " + currDuration);
if (getMvpView() != null) {
getMvpView().showCountDown((int) (currDuration / 1000));
}
}
@Override
public void onCompletion() {
if (getMvpView() != null) {
getMvpView().refreshListenerButton(false);// 播放完成:停止状态(播放按钮)
}
}
});
if (getMvpView() != null) {
getMvpView().refreshListenerButton(true);// 点击试听按钮此时并没有正在播放声音,则播放声音并显示正在播放状态(暂停按钮)
}
}
}
}
}
/**
* 中间按钮被点击
*/
public void clickCenterIcon() {
switch (audioState) {
case STATE_RECORD_NORMAL:
startRecord();// 默认状态,点击了中间按钮:开始录音
break;
case STATE_RECORD_RECORDING:
stopRecord();// 录制中状态,点击了中间按钮:停止录音
break;
case STATE_RECORD_SUCCESS:
finishRecord();// 试听状态,点击了中间按钮:上传声音
break;
}
}
/**
* 停止录音
*/
public void stopRecord() {
audioManager.stopRecord(false);
if (getMvpView() != null) {
getMvpView().stopChronometer();
}
}
/**
* 开始录音
*/
private void startRecord() {
RoomInfo current = AvRoomDataManager.get().mCurrentRoomInfo;
if (current != null) {
if (getMvpView() != null) {
getMvpView().showConfirmDialogWithExitRoom();
}
} else {
showRecordingState();// 开始录制,显示录制状态
}
}
/**
* 上传声音,完成录制
*/
private void finishRecord() {
if (null != audioFile) {
Log.i("result_url", "upload before:" + audioFile.getAbsolutePath());
if (getMvpView() != null) {
getMvpView().showLoadingView();
}
FileModel.get()
.uploadFile(audioFile.getAbsolutePath())
.compose(bindToLifecycle())
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(String url) {
audioUrl = url;
Log.i("result_url", "upload success:" + audioUrl);
saveVoice();
}
@Override
public void onError(Throwable e) {
SingleToastUtil.showToast(ResUtil.getString(R.string.audio_presenter_recordingvoicepresenter_01));
if (getMvpView() != null) {
getMvpView().hideLoadingView();// 声音文件上传失败时
}
}
});
}
}
/**
* 上传声音文件成功,提交保存声音
*/
private void saveVoice() {
if (getMvpView() != null) {
Long piaId = getMvpView().getCardPiaId();
Long changeVoiceId = getMvpView().getChangeVoiceId();
AudioModel.get().saveVoice(AuthModel.get().getCurrentUid(), audioUrl, audioDur, changeVoiceId, piaId, 0)
.compose(bindUntilEvent(PresenterEvent.DESTROY))
.subscribe(new DontWarnObserver<SaveVoiceSuccessResultInfo>() {
@Override
public void accept(SaveVoiceSuccessResultInfo saveVoiceSuccessResultInfo, String error) {
super.accept(saveVoiceSuccessResultInfo, error);
if (getMvpView() == null) {
return;
}
if (error == null) {
showNormalState();// 提交声音成功,显示初始状态
getMvpView().hideLoadingView();// 提交声音成功时
SingleToastUtil.showToast(ResUtil.getString(R.string.audio_presenter_recordingvoicepresenter_03));
Intent intent = new Intent();
intent.putExtra(AUDIO_FILE, audioUrl);
intent.putExtra(AUDIO_DURA, audioDur);
getMvpView().finishView(intent);// 上传声音成功之后退出页面
} else {
SingleToastUtil.showToast(error);
getMvpView().hideLoadingView();// 上传声音到用户信息中失败时
}
}
})
;
}
}
/**
* 显示默认状态,即初始状态
*/
private void showNormalState() {
audioState = STATE_RECORD_NORMAL;
if (getMvpView() != null) {
getMvpView().refreshButtonView(audioState);
}
if (null != audioRecorder) {
audioRecorder.destroyAudioRecorder();
audioRecorder = null;
}
}
/**
* 显示录音中状态
*/
private void showRecordingState() {
audioState = STATE_RECORD_RECORDING;
if (getMvpView() != null) {
getMvpView().refreshButtonView(audioState);
getMvpView().startChronometer();
}
audioRecorder = audioManager.getAudioRecorder((Context) mMvpView, new IAudioRecordCallback() {
@Override
public void onRecordReady() {
Log.d(TAG, "onRecordReady");
}
@Override
public void onRecordStart(File audioFile, RecordType recordType) {
Log.d(TAG, "onRecordStart : " + audioFile.getPath() + "type: " + recordType.name());
mHandler.sendEmptyMessage(WHAT_COUNT_PLAY);
if (getMvpView() != null) {
getMvpView().showVoiceWave();
}
}
@Override
public void onRecordSuccess(File file, long audioLength, RecordType recordType) {
double dura = (double) audioLength / 1000;
audioDur = (int) Math.round(dura);
audioFile = file;
Log.d(TAG, "onRecordSuccess : " + file.getPath()
+ " dura:" + dura
+ " length:" + audioDur
+ " type:" + recordType.name());
if (audioDur < MIN_RECORD_VOICE_DURATION) {
recordFailWithDurationShort();// 时长小于5sToast提示录音时间太短
} else {
showRecordSuccessState();// 否则:【跳转到试听状态】
}
mHandler.removeMessages(WHAT_COUNT_PLAY);
if (getMvpView() != null) {
getMvpView().hideVoiceWave();
}
}
@Override
public void onRecordFail() {
Log.d(TAG, "onRecordFail");
recordFailWithDurationShort();// 录音结束,出错
mHandler.removeMessages(WHAT_COUNT_PLAY);
if (getMvpView() != null) {
getMvpView().hideVoiceWave();
}
}
@Override
public void onRecordCancel() {
Log.d(TAG, "onRecordCancel");
showNormalState();// 录制过程被取消,显示初始状态
mHandler.removeMessages(WHAT_COUNT_PLAY);
if (getMvpView() != null) {
getMvpView().hideVoiceWave();
}
}
@Override
public void onRecordReachedMaxTime(int maxTime) {
Log.d(TAG, "onRecordReachedMaxTime");
// double dura = (double) maxTime / 1000;
// int max = (int) Math.round(dura);
SingleToastUtil.showToast(ResUtil.getString(R.string.audio_presenter_recordingvoicepresenter_04));
mHandler.removeMessages(WHAT_COUNT_PLAY);
if (getMvpView() != null) {
getMvpView().hideVoiceWave();
}
}
});
audioManager.startRecord();
}
/**
* 显示试听状态
*/
private void showRecordSuccessState() {
audioState = STATE_RECORD_SUCCESS;
if (getMvpView() != null) {
getMvpView().refreshButtonView(audioState);
}
}
/**
* 录音失败因时长太短
*/
private void recordFailWithDurationShort() {
SingleToastUtil.showToast(ResUtil.getString(R.string.audio_presenter_recordingvoicepresenter_05));
showNormalState();// 录制时长太短,显示初始状态
}
/**
* 释放资源
*/
public void releaseResource() {
if (audioManager != null) {
audioManager.release();
}
AudioPlayerHelper.get().onDestroy();
if (getMvpView() != null) {
getMvpView().refreshListenerButton(false);// onDestroy() 停止播放并显示停止状态(播放按钮)
}
}
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
switch (message.what) {
case WHAT_COUNT_PLAY:
double ratio = (double) audioRecorder.getCurrentRecordMaxAmplitude() / 100;
double db = 0;// 分贝
if (ratio > 1) {
db = 20 * Math.log10(ratio);
}
Log.d(TAG, ResUtil.getString(R.string.audio_presenter_recordingvoicepresenter_06) + db);
if (getMvpView() != null) {
getMvpView().refreshVoiceWave(db);
}
mHandler.sendEmptyMessageDelayed(WHAT_COUNT_PLAY, 500L);
break;
}
return false;
}
});
}

View File

@@ -0,0 +1,290 @@
package com.chwl.app.audio.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import com.chwl.core.audio.bean.VoiceMatchInfo;
import com.chwl.library.utils.ListUtils;
import java.util.ArrayList;
import java.util.List;
import lombok.Setter;
/**
* create by lvzebiao @2019/6/18
*/
public class BottleContainer extends FrameLayout {
private Context context;
private List<VoiceMatchInfo> list = new ArrayList<>();
private int currPosition = 0;
private int minOffset;
private int maxOffset;
public BottleContainer(@NonNull Context context) {
this(context, null);
}
public BottleContainer(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.context = context;
minOffset = UIUtil.dip2px(context, 20);
maxOffset = UIUtil.dip2px(context, 270);
}
public void initData(List<VoiceMatchInfo> list) {
if (!ListUtils.isListEmpty(list)) {
this.list.clear();
this.list.addAll(list);
}
if (getChildCount() == 0) {
removeAllViews();
initBottleViews();
}
currPosition = 0;
initBottleData();
}
public void initBottleViews() {
BottleLayout smallBottle = new BottleLayout(context, false);
addView(smallBottle);
BottleLayout bigBottle = new BottleLayout(context, true);
addView(bigBottle);
bigBottle.setSvga(true);
smallBottle.setSvga(false);
}
private void initBottleData() {
//设置大瓶子的数据
setBigBottleDataAndSvga();
//设置小瓶子的数据
setSmallBottleDataAndSvga();
//自动播放大瓶子的声音
autoPlayBigBottleSound();
//更新监听
updateBottleStatus();
//只有一个数据小瓶子隐藏
updateVisibleStatus();
}
private void setBigBottleDataAndSvga() {
if (currPosition < list.size()) {
if (getChildCount() >= 2) {
//bigBottle
BottleLayout bigBottle = ((BottleLayout) getChildAt(1));
bigBottle.setData(list.get(currPosition));
bigBottle.stop();
bigBottle.play();
}
}
}
private void setSmallBottleDataAndSvga() {
if (currPosition + 1 < list.size()) {
if (getChildCount() >= 1) {
//smallBottle
BottleLayout smallBottle = ((BottleLayout) getChildAt(0));
smallBottle.setData(list.get(currPosition + 1));
smallBottle.stop();
smallBottle.play();
}
}
}
/**
* 自动播放大瓶子的声音
*/
public void autoPlayBigBottleSound() {
if (getChildCount() >= 2) {
((BottleLayout) getChildAt(1)).startPlay();
}
}
private void updateBottleStatus() {
if (getChildCount() >= 2) {
//bigBottle
BottleLayout bigBottle = ((BottleLayout) getChildAt(1));
bigBottle.setOnNextPageListener(new BottleOnNextPageListener());
bigBottle.setCanDrag(true);
if (bigBottle.getTag() != null) {
bigBottle.getViewTreeObserver().removeOnGlobalLayoutListener(
(ViewTreeObserver.OnGlobalLayoutListener) bigBottle.getTag());
bigBottle.setTag(null);
}
BottleLayoutListener listener = new BottleLayoutListener();
bigBottle.getViewTreeObserver().addOnGlobalLayoutListener(listener);
bigBottle.setTag(listener);
}
if (getChildCount() >= 1) {
//smallBottle
BottleLayout smallBottle = ((BottleLayout) getChildAt(0));
smallBottle.setOnNextPageListener(null);
smallBottle.setCanDrag(false);
if (smallBottle.getTag() != null) {
smallBottle.getViewTreeObserver().removeOnGlobalLayoutListener(
(ViewTreeObserver.OnGlobalLayoutListener) smallBottle.getTag());
smallBottle.setTag(null);
}
}
}
public class BottleOnNextPageListener implements BottleLayout.OnNextPageListener {
@Override
public void onLimit(boolean isRight) {
if (opListener != null) {
opListener.onLimit(isRight);
}
}
@Override
public void onNext(boolean isRight) {
VoiceMatchInfo info = null;
if (currPosition < list.size()) {
info = list.get(currPosition);
}
if (getChildCount() == 2) {
//将上面第一个瓶子移除,并且添加到底下的瓶子,也就是大小瓶子位置互换
BottleLayout bigBottle = (BottleLayout) getChildAt(1);
bigBottle.resetSoundPlayStatus();
removeView(bigBottle);
currPosition++;
if (bigBottle.getParent() == null) {
addView(bigBottle, 0);
setSmallBottleDataAndSvga();
} else {
}
updateVisibleStatus();// 切换到下一个瓶子时
updateBottleStatus();
if (currPosition < list.size()) {
autoPlayBigBottleSound();
}
if (info != null) {
if (opListener != null) {
opListener.onLikeOrUnLike(info, isRight, currPosition >= list.size());
}
}
}
}
}
@Setter
private IBottleOpListener opListener;
/**
* 更新显示的瓶子状态
*/
private void updateVisibleStatus() {
if (currPosition == list.size() - 1 && getChildCount() >= 1) {
// 如果是最后一个瓶子,需要将底部的小瓶子隐藏掉
getChildAt(0).setVisibility(View.INVISIBLE);
} else {
for (int i = 0; i < getChildCount(); i++) {
getChildAt(i).setVisibility(View.VISIBLE);
}
}
}
public class BottleLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
@Override
public void onGlobalLayout() {
if (getChildCount() != 2) {
return;
}
BottleLayout child = (BottleLayout) getChildAt(0);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getChildAt(1).getLayoutParams();
int leftMargin = params.leftMargin;
int topMargin = params.topMargin;
int dx = leftMargin - child.getInitLeft();
int dy = topMargin - child.getInitTop();
//平方后再开方
int offset = (int) Math.sqrt(dx * dx + dy * dy);
if (offset < minOffset) {
offset = minOffset;
}
if (offset > maxOffset) {
offset = maxOffset;
}
float percent = (float) (offset - minOffset) / (maxOffset - minOffset);
float scale = BottleLayout.MIN_SCALE_VALUE + (1f - BottleLayout.MIN_SCALE_VALUE) * percent;
child.setScaleX(scale);
child.setScaleY(scale);
}
}
public void addBigBottleLikeCount() {
if (getChildCount() >= 2) {
BottleLayout bigBottle = (BottleLayout) getChildAt(1);
bigBottle.addLikeCount();
}
}
public void dealBigBottleLimit(boolean isLike) {
if (getChildCount() >= 2) {
BottleLayout bigBottle = (BottleLayout) getChildAt(1);
if (!bigBottle.isCanNext()) {
return;
}
bigBottle.dealWithLimit(isLike);// 点击按钮,受限制情况
}
}
public void dealToNext(boolean isLike) {
if (getChildCount() >= 2) {
BottleLayout bigBottle = (BottleLayout) getChildAt(1);
if (!bigBottle.isCanNext()) {
return;
}
bigBottle.toNext(isLike);// 点击按钮,不受限情况
}
}
public void resetBigBottlePlayStatus() {
if (getChildCount() >= 2) {
BottleLayout bigBottle = (BottleLayout) getChildAt(1);
bigBottle.resetSoundPlayStatus();
}
}
public void onlySetPlayOrStopIconForBigBottle(boolean isPlay) {
if (getChildCount() >= 2) {
BottleLayout bigBottle = (BottleLayout) getChildAt(1);
bigBottle.onlySetPlayOrStopIcon(isPlay);
}
}
public void onDestroy() {
for (int i = 0; i < getChildCount(); i++) {
BottleLayout child = (BottleLayout) getChildAt(i);
if (child.getTag() != null) {
child.getViewTreeObserver().removeOnGlobalLayoutListener(
(ViewTreeObserver.OnGlobalLayoutListener) child.getTag());
child.setTag(null);
}
child.setOnNextPageListener(null);
child.stop();
}
opListener = null;
}
}

View File

@@ -0,0 +1,536 @@
package com.chwl.app.audio.view;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.coorchice.library.SuperTextView;
import com.opensource.svgaplayer.SVGAImageView;
import com.chwl.app.R;
import com.chwl.app.UIHelper;
import com.chwl.app.audio.VoiceMatchActivity;
import com.chwl.app.audio.helper.OnPlayListener;
import com.chwl.app.audio.helper.SvgaCacheManager;
import com.chwl.app.audio.helper.VmSoundManager;
import com.chwl.app.common.widget.CircleImageView;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import com.chwl.core.XConstants;
import com.chwl.core.audio.bean.VoiceMatchInfo;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.utils.SharedPreferenceUtils;
import com.chwl.core.utils.net.DontWarnObserver;
import com.chwl.core.utils.net.RxHelper;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.SingleToastUtil;
import com.chwl.library.utils.TimeUtils;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import lombok.Getter;
import lombok.Setter;
/**
* create by lvzebiao @2019/6/6
*/
public class BottleLayout extends FrameLayout {
public final static float MIN_SCALE_VALUE = 0.0f;
private CircleImageView civAvatarBg;
private CircleImageView civAvatar;
private SVGAImageView svgaVoiceBubble;
private SVGAImageView svgaVoiceBottle;
private TextView tvNick;
private ImageView ivGender;
private SuperTextView stvConstellation;
private SuperTextView stvLocation;
private PlayLoadingImageView plivPlay;
private TextView tvLikeValue;
private ImageView ivReport;
private int lastMoveX = 0;
private int lastMoveY = 0;
int bigBottleWidth;
int bigBottleHeight;
int smallBottleWidth;
int smallBottleHeight;
/**
* 初始化时的左间距
*/
int leftMargin;
int topMargin;
int parentWidth;
@Getter
int initLeft;
@Getter
int initTop;
int minNextOffset;
private boolean canDrag;
private boolean animRun;
private Context context;
private VoiceMatchInfo voiceMatchInfo;
public BottleLayout(@NonNull Context context) {
this(context, false);
}
public BottleLayout(@NonNull Context context, boolean canDrag) {
super(context);
this.context = context;
this.canDrag = canDrag;
inflate(context, R.layout.layout_item_voice_bottle, this);
findView();
bigBottleWidth = UIUtil.dip2px(context, 295);
bigBottleHeight = UIUtil.dip2px(context, 441);
smallBottleWidth = bigBottleWidth / 3;
smallBottleHeight = bigBottleHeight / 3;
parentWidth = UIUtil.getScreenWidth(context);
topMargin = 0;
minNextOffset = UIUtil.dip2px(context, 80);
leftMargin = (parentWidth - bigBottleWidth) / 2;
initLeft = leftMargin;
initTop = topMargin;
resetParams();
}
private void findView() {
civAvatarBg = findViewById(R.id.civ_avatar_bg);
civAvatar = findViewById(R.id.civ_avatar);
svgaVoiceBubble = findViewById(R.id.svga_voice_bubble);
svgaVoiceBottle = findViewById(R.id.svga_voice_bottle);
tvNick = findViewById(R.id.tv_nick);
ivGender = findViewById(R.id.iv_gender);
stvConstellation = findViewById(R.id.stv_constellation);
stvLocation = findViewById(R.id.stv_location);
plivPlay = findViewById(R.id.pliv_play);
tvLikeValue = findViewById(R.id.tv_like_value);
ivReport = findViewById(R.id.iv_report);
}
public void setSvga(boolean isBig) {
if (!SvgaCacheManager.get().isMoreAndroid7_0()) {
svgaVoiceBottle.setImageResource(R.drawable.bg_voice_match_android_6);
return;
}
if (isBig) {
if (SvgaCacheManager.get().getBigBottleSvga() != null) {
svgaVoiceBottle.setLoops(0);
svgaVoiceBottle.setImageDrawable(SvgaCacheManager.get().getBigBottleSvga());
}
if (SvgaCacheManager.get().getBigBubbleSvga() != null) {
svgaVoiceBubble.setLoops(0);
svgaVoiceBubble.setImageDrawable(SvgaCacheManager.get().getBigBubbleSvga());
}
} else {
if (SvgaCacheManager.get().getSmallBottleSvga() != null) {
svgaVoiceBottle.setLoops(0);
svgaVoiceBottle.setImageDrawable(SvgaCacheManager.get().getSmallBottleSvga());
}
if (SvgaCacheManager.get().getSmallBubbleSvga() != null) {
svgaVoiceBubble.setLoops(0);
svgaVoiceBubble.setImageDrawable(SvgaCacheManager.get().getSmallBubbleSvga());
}
}
}
public void play() {
if (!SvgaCacheManager.get().isMoreAndroid7_0()) {
return;
}
if (!svgaVoiceBottle.isAnimating()) {
svgaVoiceBottle.startAnimation();
}
if (!svgaVoiceBubble.isAnimating()) {
svgaVoiceBubble.startAnimation();
}
}
public void stop() {
svgaVoiceBottle.stopAnimation();
svgaVoiceBubble.stopAnimation();
}
public void setCanDrag(boolean canDrag) {
this.canDrag = canDrag;
resetParams();
}
private void resetParams() {
LayoutParams params = new LayoutParams(
bigBottleWidth, bigBottleHeight);
params.leftMargin = initLeft;
params.topMargin = initTop;
setLayoutParams(params);
if (!canDrag) {
setScaleX(MIN_SCALE_VALUE);
setScaleY(MIN_SCALE_VALUE);
} else {
setScaleX(1.0f);
setScaleY(1.0f);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return super.onInterceptTouchEvent(event);
}
@Override
public boolean performClick() {
return super.performClick();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//LogUtil.print(canDrag + "---Bottle---onTouchEvent---" + event.getAction());
if (!canDrag || animRun) {
return super.onTouchEvent(event);
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int downX = (int) event.getRawX();
int downY = (int) event.getRawY();
lastMoveX = downX;
lastMoveY = downY;
break;
case MotionEvent.ACTION_MOVE:
int disX = (int) (event.getRawX() - lastMoveX);
int disY = (int) (event.getRawY() - lastMoveY);
//LogUtil.print("getLeft()=" + getLeft() + ", disX=" + disX);
leftMargin = getLeft() + disX;
topMargin = getTop() + disY;
//LogUtil.print("leftMargin=" + leftMargin + ", topMargin=" + topMargin);
LayoutParams moveParams = new LayoutParams(
bigBottleWidth, bigBottleHeight
);
moveParams.leftMargin = leftMargin;
moveParams.topMargin = topMargin;
setLayoutParams(moveParams);
lastMoveX = (int) event.getRawX();
lastMoveY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:
//手指离开的时候,回弹到初始位置
if (Math.abs(getLeft() - initLeft) <= minNextOffset) {
recoveryToInit();
} else {
boolean isRight = getLeft() > initLeft;
boolean isLimit = (boolean) SharedPreferenceUtils.get(VoiceMatchActivity.KEY_VOICE_MUST_LIMIT + AuthModel.get().getCurrentUid(), true);
if (isLimit) {
dealWithLimit(isRight);// 手势滑动,受限制情况
} else {
toNext(isRight);// 不受限情况,允许左右滑动
}
}
break;
}
return true;
}
public void dealWithLimit(boolean isRight) {
if (isRight) {
recoveryToInit();
toLimit(true);// 限制右滑
} else {
int limitCount = (int) SharedPreferenceUtils.get(VoiceMatchActivity.KEY_VOICE_LIMIT_COUNT + AuthModel.get().getCurrentUid(), 0);
if (limitCount >= 2) {// 0 1 索引为2时即为第三个声音
recoveryToInit();
toLimit(false);// 不喜欢第三个 限制左滑
} else {
toNext(false);// 受限情况 但 左滑未超过三次,允许左滑
limitCount = limitCount + 1;
SharedPreferenceUtils.put(VoiceMatchActivity.KEY_VOICE_LIMIT_COUNT + AuthModel.get().getCurrentUid(), limitCount);
}
}
}
public boolean isCanNext() {
return !animRun;
}
private void toLimit(boolean isRight) {
if (onNextPageListener != null) {
onNextPageListener.onLimit(isRight);
}
}
public void toNext(boolean isRight) {
//如果切换下一页的时候,声音正在播放,则停止播放声音
VmSoundManager.get().getHelper().endPlay();
animRun = true;
int endValue;
if (isRight) {
endValue = parentWidth;
} else {
endValue = -bigBottleWidth;
}
int duration = Math.abs(getLeft() - endValue) / 2;
if (duration < 100) {
duration = 100;
} else if (duration > 300) {
duration = 300;
}
ValueAnimator animator = ValueAnimator.ofInt(getLeft(), endValue);
animator.setDuration(duration);
animator.addUpdateListener(animation -> {
int curr = (int) animation.getAnimatedValue();
LayoutParams params = (LayoutParams) getLayoutParams();
params.leftMargin = curr;
setLayoutParams(params);
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if (onNextPageListener != null) {
onNextPageListener.onNext(isRight);
}
Single.timer(200, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
.subscribe(new DontWarnObserver<Long>() {
@Override
public void accept(Long aLong, String error) {
super.accept(aLong, error);
animRun = false;
}
});
}
});
animator.start();
}
@Setter
private OnNextPageListener onNextPageListener;
public interface OnNextPageListener {
/**
* 受到限制 不给滑动
*
* @param isRight 是否往右滑
*/
void onLimit(boolean isRight);
void onNext(boolean isRight);
}
private void recoveryToInit() {
ValueAnimator xAnimator = ValueAnimator.ofInt(getLeft(), initLeft);
xAnimator.setDuration(150);
xAnimator.addUpdateListener(animation -> {
int currLeft = (int) animation.getAnimatedValue();
LayoutParams params = (LayoutParams) getLayoutParams();
params.leftMargin = currLeft;
setLayoutParams(params);
});
xAnimator.start();
ValueAnimator yAnimator = ValueAnimator.ofInt(getTop(), initTop);
yAnimator.setDuration(150);
yAnimator.addUpdateListener(animation -> {
int currValue = (int) animation.getAnimatedValue();
LayoutParams params = (LayoutParams) getLayoutParams();
params.topMargin = currValue;
setLayoutParams(params);
});
yAnimator.start();
}
public void setData(VoiceMatchInfo info) {
voiceMatchInfo = info;
if (info == null) {
return;
}
ImageLoadUtils.loadAvatarBig(info.getAvatar(), civAvatar);
ImageLoadUtils.loadImageWithBlur(context, ImageLoadUtils.getAvatarSizeUrl(info.getAvatar()), civAvatarBg, 20, 2);
String showNick = info.getNick();
if (showNick == null) {
showNick = "";
}
if (showNick.length() >= 6) {
showNick = showNick.substring(0, 5) + "";
}
tvNick.setText(showNick);
ivGender.setImageResource(info.getGender() == 1 ? R.drawable.ic_gender_male : R.drawable.ic_gender_female);
stvConstellation.setText(TimeUtils.msToConstellation(info.getBirth()));
String location = info.getLocation();
if (TextUtils.isEmpty(location)) {
stvLocation.setVisibility(GONE);
} else {
stvLocation.setVisibility(VISIBLE);
if (location.length() >= 5) {
location = location.substring(0, 4) + "";
}
stvLocation.setText(location);
}
lastClickPlayTime = System.currentTimeMillis();
plivPlay.setOnClickListener(v -> {
//加个容错处理,防止频繁点击播放按钮
long currTime = System.currentTimeMillis();
if (currTime - lastClickPlayTime < 400) {
return;
}
if (isDelaying) {
return;
}
lastClickPlayTime = currTime;
if (VmSoundManager.get().getHelper().isPreparing()) {
VmSoundManager.get().getHelper().endPlay();
resetSoundPlayStatus();
return;
}
if (VmSoundManager.get().getHelper().isPlaying()) {
VmSoundManager.get().getHelper().pausePlay();
plivPlay.setImageResource(R.drawable.icon_voice_to_start);
return;
}
if (VmSoundManager.get().getHelper().isPause()) {
VmSoundManager.get().getHelper().continuePlay();
plivPlay.setImageResource(R.drawable.icon_voice_to_stop);
return;
}
startPlay();
});
ivReport.setOnClickListener(view -> {
// 跳转到举报页面
UIHelper.showReportPage(context, info.getUid(), XConstants.REPORT_TYPE_VOICE);
});
}
public void startPlay() {
if (!canDrag) {
return;
}
if (voiceMatchInfo == null) {
return;
}
tvLikeValue.setTag(voiceMatchInfo.getLikeCount());
tvLikeValue.setText(formatLikeCount(voiceMatchInfo.getLikeCount()));
plivPlay.setImageResource(R.drawable.icon_voice_to_stop);
VmSoundManager.get().getHelper().playInThread(voiceMatchInfo.getVoiceUrl(), true, new OnPlayListener() {
@Override
public void onError(String error) {
resetSoundPlayStatus();
SingleToastUtil.showToast(error);
}
@Override
public void onPrepared() {
duration = VmSoundManager.get().getHelper().getDuration();
plivPlay.setMaxProgress(duration);
}
@Override
public void onPlaying(long currDuration) {
plivPlay.setProgress(currDuration, duration);
}
@Override
public void onCompletion() {
plivPlay.setProgress(duration, duration);
isDelaying = true;
Single.timer(150, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
.compose(RxHelper.bindContext(context))
.subscribe(new DontWarnObserver<Long>() {
@Override
public void acceptThrowable(Long aLong, Throwable throwable) {
super.acceptThrowable(aLong, throwable);
resetSoundPlayStatus();
isDelaying = false;
}
});
}
});
}
public void addLikeCount() {
tvLikeValue.post(() -> {
if (tvLikeValue.getTag() instanceof Integer) {
int tagLikeCount = (Integer) tvLikeValue.getTag();
tvLikeValue.setText(String.valueOf(tagLikeCount + 1));
}
});
}
public void resetSoundPlayStatus() {
plivPlay.setImageResource(R.drawable.icon_voice_to_start);
plivPlay.setProgress(0, 1000);
}
public void onlySetPlayOrStopIcon(boolean isPlay) {
plivPlay.setImageResource(isPlay ? R.drawable.icon_voice_to_start : R.drawable.icon_voice_to_stop);
}
private long duration;
private long lastClickPlayTime = 0;
/**
* 播放结束后,会有延迟让按钮回到最初状态,如果正在延迟中的话,则禁止操作
*/
private boolean isDelaying = false;
private String formatLikeCount(int likeCount) {
String showText;
if (likeCount < 0) {
showText = "0";
} else if (likeCount < 10000) {
showText = String.valueOf(likeCount);
} else {
double likeCountDouble = (double) likeCount;
double num = likeCountDouble / 10000;
DecimalFormat decimalFormat = new DecimalFormat("0.00");// 构造方法的字符格式这里如果小数不足2位,会以0补足.
decimalFormat.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
BigDecimal bigDecimal = new BigDecimal(num);
double likeCountFormat = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
if (likeCountFormat > 9999) {
showText = ResUtil.getString(R.string.audio_view_bottlelayout_05);
} else {
showText = decimalFormat.format(likeCountFormat) + ResUtil.getString(R.string.audio_view_bottlelayout_06);
}
}
return showText;
}
}

View File

@@ -0,0 +1,14 @@
package com.chwl.app.audio.view;
import com.chwl.core.audio.bean.VoiceMatchInfo;
/**
* create by lvzebiao @2019/6/19
*/
public interface IBottleOpListener {
void onLimit(boolean isRight);
void onLikeOrUnLike(VoiceMatchInfo info, boolean isRight, boolean needLoading);
}

View File

@@ -0,0 +1,23 @@
package com.chwl.app.audio.view;
import com.chwl.core.audio.bean.UserVoiceInfo;
import com.chwl.library.base.IMvpBaseView;
import java.util.List;
/**
* 我的声音页面
*/
public interface IMyVoiceView extends IMvpBaseView {
/**
* 显示声音数据消息
*/
void showVoiceInfo(List<UserVoiceInfo> voiceList);
/**
* 请稍后
*/
void showLoadingView();
void hideLoadingView();
}

View File

@@ -0,0 +1,79 @@
package com.chwl.app.audio.view;
import android.content.Intent;
import com.chwl.core.audio.bean.VoiceCardInfo;
import com.chwl.library.base.IMvpBaseView;
import java.util.List;
/**
* 录制声音页面
*/
public interface IRecordingVoiceView extends IMvpBaseView {
/**
* 添加卡片信息
*/
void addCardInfo(List<VoiceCardInfo> cardInfoList);
/**
* 获取当前pia剧本id
*/
Long getCardPiaId();
/**
* 刷新按钮的状态
*/
void refreshButtonView(int state);
/**
* 刷新试听按钮
*/
void refreshListenerButton(boolean isPlaying);
/**
* 开始倒计时
*/
void startChronometer();
/**
* 停止倒计时
*/
void stopChronometer();
/**
* 确认退出页面对话框
*/
void showConfirmDialogWithLeave();
/**
* 退出页面
*/
void finishView(Intent intent);
/**
* 关闭房间再录音
*/
void showConfirmDialogWithExitRoom();
/**
* 请稍后
*/
void showLoadingView();
void hideLoadingView();
/**
* 获取被重新录制的声音的ID打开页面的时候传入可以为空
*/
Long getChangeVoiceId();
void refreshVoiceWave(double db);
void showVoiceWave();
void hideVoiceWave();
void showCountDown(int duration);
}

View File

@@ -0,0 +1,96 @@
package com.chwl.app.audio.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatImageView;
import com.chwl.app.R;
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import lombok.Setter;
/**
* create by lvzebiao @2019/6/12
*/
public class PlayLoadingImageView extends AppCompatImageView {
private long progress;
RectF rectF;
private Paint paint;
private int color_white;
private int color_32ECD9;
private int color_F2F4F4;
private int loading_width;
@Setter
private long maxProgress = 1000;
public PlayLoadingImageView(Context context, AttributeSet attrs) {
super(context, attrs);
loading_width = UIUtil.dip2px(context, 2);
rectF = new RectF();
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(loading_width);
color_white = context.getResources().getColor(R.color.white);
color_32ECD9 = context.getResources().getColor(R.color.color_32ECD9);
color_F2F4F4 = context.getResources().getColor(R.color.color_F2F4F4);
left = (float) loading_width / 2;
top = (float) loading_width / 2;
}
private float left, top, rigth, end;
@Override
protected void onDraw(Canvas canvas) {
rectF.set(left, top, getWidth() - left, getHeight() - top);
paint.setColor(color_F2F4F4);
float radiu = (float) (getWidth() - loading_width) / 2;
canvas.drawCircle((float) getWidth() / 2, (float) getHeight() / 2, radiu, paint);
paint.setColor(color_32ECD9);
int degree;
if (maxProgress > 0) {
degree = (int) (progress * 360 / maxProgress);
} else {
degree = 0;
}
canvas.drawArc(rectF, -90, degree, false, paint);
super.onDraw(canvas);
}
public void setProgress(long progress, long maxProgress) {
if (progress > maxProgress) {
progress = maxProgress;
} else if (progress < 0) {
progress = 0;
}
if (maxProgress - progress <= 500) {
//LogUtil.print(ResUtil.getString(R.string.audio_view_playloadingimageview_01));
progress = maxProgress;
}
if (progress == this.progress && maxProgress == this.maxProgress) {
//加载进度一样,不需要重绘
return;
}
this.progress = progress;
this.maxProgress = maxProgress;
invalidate();
}
}

View File

@@ -0,0 +1,377 @@
package com.chwl.app.audio.viewmodel
import android.content.Intent
import android.util.Log
import androidx.lifecycle.MutableLiveData
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.chwl.app.R
import com.chwl.app.audio.SoundSignatureActivity
import com.chwl.app.audio.helper.AudioPlayerHelper
import com.chwl.app.audio.helper.OnPlayListener
import com.chwl.app.base.BaseViewModel
import com.chwl.core.Constants
import com.chwl.core.audio.AudioPlayAndRecordManager
import com.chwl.core.auth.AuthModel
import com.chwl.core.manager.AudioEngineManager
import com.chwl.core.manager.AvRoomDataManager
import com.chwl.core.sound.model.SoundModel
import com.chwl.core.utils.extension.toast
import com.chwl.library.common.application.BaseApp
import com.chwl.library.utils.ResUtil
import com.chwl.library.utils.SingleToastUtil
import com.chwl.library.utils.log.MLog
import java.io.File
/**
* @author wushaocheng
* 声音签名
*/
class SoundViewModel : BaseViewModel() {
companion object {
const val TAG = "RecordingVoiceActivity"
const val STATE_RECORD_NORMAL = 0//普通状态
const val STATE_RECORD_RECORDING = 1//录音中
const val STATE_RECORD_SUCCESS = 2//录音完成
const val STATE_RECORD_SAVE_SUCCESS = 3//保存成功
const val STATE_RECORD_AUDIT_SUCCESS = 4//审核成功
}
var audioState = STATE_RECORD_NORMAL
private var audioManager: AudioPlayAndRecordManager? = null
private var audioRecorder: AudioRecorder? = null
var audioFile: File? = null
var audioDur = 0
var audioUrl: String? = null
private var isRemoteMute = false //是否静音
private var isMute = true //是否开麦
private val _showConfirmLiveData = MutableLiveData<String?>()
val showConfirmLiveData: MutableLiveData<String?> = _showConfirmLiveData
private val _refreshLiveData = MutableLiveData<Int>()
val refreshLiveData: MutableLiveData<Int> = _refreshLiveData
private val _startChronometerLiveData = MutableLiveData<String?>()
val startChronometerLiveData: MutableLiveData<String?> = _startChronometerLiveData
private val _stopChronometerLiveData = MutableLiveData<String?>()
val stopChronometerLiveData: MutableLiveData<String?> = _stopChronometerLiveData
private val _refreshPlayStatusLiveData = MutableLiveData<Boolean>()
val refreshPlayStatusLiveData: MutableLiveData<Boolean> = _refreshPlayStatusLiveData
private val _resetStatusLiveData = MutableLiveData<String?>()
val resetStatusLiveData: MutableLiveData<String?> = _resetStatusLiveData
private val _showCountDownLiveData = MutableLiveData<Int>()
val showCountDownLiveData: MutableLiveData<Int> = _showCountDownLiveData
private val _finishViewLiveData = MutableLiveData<Intent?>()
val finishViewLiveData: MutableLiveData<Intent?> = _finishViewLiveData
private val _hideLoadLiveData = MutableLiveData<String?>()
val hideLoadLiveData: MutableLiveData<String?> = _hideLoadLiveData
private val _saveRecordLiveData = MutableLiveData<String?>()
val saveRecordLiveData: MutableLiveData<String?> = _saveRecordLiveData
private val _deleteRecordLiveData = MutableLiveData<String?>()
val deleteRecordLiveData: MutableLiveData<String?> = _deleteRecordLiveData
private val _showSaveConfirmDialogLiveData = MutableLiveData<String?>()
val showSaveConfirmDialogLiveData: MutableLiveData<String?> = _showSaveConfirmDialogLiveData
private val _showRecordConfirmDialogLiveData = MutableLiveData<String?>()
val showRecordConfirmDialogLiveData: MutableLiveData<String?> = _showRecordConfirmDialogLiveData
init {
if (AvRoomDataManager.get().mCurrentRoomInfo != null) {
val roomQueueInfo = AvRoomDataManager.get()
.getRoomQueueMemberInfoByAccount(AuthModel.get().currentUid.toString())
if (roomQueueInfo?.mRoomMicInfo != null) {
isMute = AudioEngineManager.get().isMute
}
isRemoteMute = AudioEngineManager.get().isRemoteMute
}
audioManager = AudioPlayAndRecordManager.getInstance()
}
/**
* 中间按钮被点击
*/
fun clickCenterIcon() {
when (audioState) {
STATE_RECORD_NORMAL -> startRecord() // 默认状态,点击了中间按钮:开始录音
STATE_RECORD_RECORDING -> stopRecord() // 录制中状态,点击了中间按钮:停止录音
STATE_RECORD_SUCCESS -> clickAudition() // 试听状态,点击了中间按钮:试听声音
STATE_RECORD_SAVE_SUCCESS -> clickAudition() //保存成功,点击了中间按钮:试听声音
STATE_RECORD_AUDIT_SUCCESS -> clickAudition() //审核成功,点击了中间按钮,试听声音
}
}
/**
* 开始录音
*/
private fun startRecord() {
val current = AvRoomDataManager.get().mCurrentRoomInfo
if (current != null) {
_showConfirmLiveData.value = null
} else {
showRecordingState() // 开始录制,显示录制状态
}
}
/**
* 显示录音中状态
*/
fun showRecordingState() {
audioState = STATE_RECORD_RECORDING
_refreshLiveData.value = audioState
audioRecorder =
audioManager?.getAudioRecorder(BaseApp.getContext(), object : IAudioRecordCallback {
override fun onRecordReady() {
Log.d(TAG, "onRecordReady")
}
override fun onRecordStart(audioFile: File, recordType: RecordType) {
Log.d(TAG, "onRecordStart : " + audioFile.path + "type: " + recordType.name)
_startChronometerLiveData.value = null
}
override fun onRecordSuccess(
file: File,
audioLength: Long,
recordType: RecordType
) {
val dura = audioLength.toDouble() / 1000
audioDur = dura.toInt()
audioFile = file
Log.d(
TAG, "onRecordSuccess : " + file.path
+ " dura:" + dura
+ " length:" + audioDur
+ " type:" + recordType.name
)
if (audioDur < SoundSignatureActivity.MIN_RECORD_VOICE_DURATION) {
recordFailWithDurationShort() // 时长小于1sToast提示录音时间太短
} else {
showRecordSuccessState() // 否则:【跳转到试听状态】
}
}
override fun onRecordFail() {
Log.d(TAG, "onRecordFail")
recordFailWithDurationShort() // 录音结束,出错
}
override fun onRecordCancel() {
Log.d(TAG, "onRecordCancel")
showNormalState() // 录制过程被取消,显示初始状态
}
override fun onRecordReachedMaxTime(maxTime: Int) {
Log.d(TAG, "onRecordReachedMaxTime")
SingleToastUtil.showToast(ResUtil.getString(R.string.audio_presenter_recordingvoicepresenter_04))
}
})
audioManager?.startRecord()
}
/**
* 录音失败因时长太短
*/
private fun recordFailWithDurationShort() {
SingleToastUtil.showToast(ResUtil.getString(R.string.audio_presenter_recordingvoicepresenter_05))
showNormalState() // 录制时长太短,显示初始状态
}
/**
* 显示默认状态,即初始状态
*/
fun showNormalState() {
// 正在播放:停止播放
AudioPlayerHelper.get().endPlay()
openRoomSound()
audioState = STATE_RECORD_NORMAL
audioUrl = null
audioDur = 0
audioFile = null
_refreshLiveData.value = audioState
if (null != audioRecorder) {
audioRecorder?.destroyAudioRecorder()
audioRecorder = null
}
}
/**
* 显示试听状态
*/
private fun showRecordSuccessState() {
audioState = STATE_RECORD_SUCCESS
_refreshLiveData.value = audioState
}
/**
* 停止录音
*/
fun stopRecord() {
audioManager?.stopRecord(false)
openRoomSound()
_stopChronometerLiveData.value = null
}
fun reRecord() {
if (audioState == STATE_RECORD_SUCCESS || audioState == STATE_RECORD_SAVE_SUCCESS || audioState == STATE_RECORD_AUDIT_SUCCESS) {
showNormalState() // 点击重录,回到初始状态
}
}
/**
* onPause()回调
*/
fun pausePage() {
// 正在录制:则停止录制
if (audioRecorder != null && audioRecorder?.isRecording == true) {
stopRecord() // onPause()时,如果正在录制,则停止录制
}
// 正在播放:停止播放
AudioPlayerHelper.get().onPause()
openRoomSound()
if (audioState != STATE_RECORD_NORMAL) {
_refreshPlayStatusLiveData.value = false // onPause() 停止播放并显示停止状态(播放按钮)
}
}
/**
* 释放资源
*/
fun releaseResource() {
audioManager?.release()
AudioPlayerHelper.get().onDestroy()
}
/**
* 离开页面处理
*/
fun leaveThePage() {
if (audioRecorder != null && audioRecorder?.isRecording == true) {
stopRecord() // 录制过程被中断(如点了返回按钮或电话接入等):【自动跳转到试听状态】停止录音
return
}
if (AudioPlayerHelper.get().isPlaying) {
AudioPlayerHelper.get().endPlay()
openRoomSound()
_refreshPlayStatusLiveData.value = false // 返回页面时,此时正在播放声音,则停止播放并显示停止状态(播放按钮)
}
if (audioState == STATE_RECORD_SUCCESS) { // 已经录制未保存:未保存提示(确定则返回页面/取消则保留当前页面)
_showSaveConfirmDialogLiveData.value = null
} else {
_finishViewLiveData.value = null// 退出页面
}
}
/**
* 试听按钮
*/
private fun clickAudition() {
if (audioState == STATE_RECORD_SUCCESS || audioState == STATE_RECORD_SAVE_SUCCESS || audioState == STATE_RECORD_AUDIT_SUCCESS) {
if (AudioPlayerHelper.get().isPlaying) {
AudioPlayerHelper.get().pausePlay()
openRoomSound()
_refreshPlayStatusLiveData.value = false// 点击试听按钮此时正在播放声音,则暂停播放并显示停止状态(播放按钮)
} else if (AudioPlayerHelper.get().isPause) {
AudioPlayerHelper.get().continuePlay()
stopRoomSound()
_refreshPlayStatusLiveData.value = true// 点击试听按钮此时正在暂停声音,则继续播放并显示播放状态(停止按钮)
} else if (AudioPlayerHelper.get().isPreparing) {
AudioPlayerHelper.get().endPlay()
openRoomSound()
_refreshPlayStatusLiveData.value = false// 点击试听按钮此时正在准备状态,则停止播放并显示停止状态(播放按钮)
} else {
if (null != audioFile && audioFile?.exists() == true) {
MLog.debug(TAG, "play audioFilePath: " + audioFile?.path)
playSound(audioFile?.path)
} else if (null != audioUrl && audioUrl?.contains("http") == true) {
MLog.debug(TAG, "play audioUrl: $audioUrl")
playSound(audioUrl)
}
}
}
}
/**
* 播放录音
*/
private fun playSound(path: String?) {
AudioPlayerHelper.get().playInThread(path, object : OnPlayListener {
override fun onError(error: String) {
_refreshPlayStatusLiveData.value = false // 出错:停止状态(播放按钮)
}
override fun onPrepared() {
stopRoomSound()
_refreshPlayStatusLiveData.value = true// 准备完毕要开始播放:播放状态(暂停按钮)
}
override fun onPlaying(currDuration: Long) {
MLog.debug(
TAG,
"duration = $currDuration"
)
_showCountDownLiveData.value = currDuration.toInt()
}
override fun onCompletion() {
openRoomSound()
_refreshPlayStatusLiveData.value = false// 播放完成:停止状态(播放按钮)
_resetStatusLiveData.value = null
}
})
_refreshPlayStatusLiveData.value = true// 点击试听按钮此时并没有正在播放声音,则播放声音并显示正在播放状态(暂停按钮)
}
fun stopRoomSound() {
if (AvRoomDataManager.get().mCurrentRoomInfo != null) {
AudioEngineManager.get().isRemoteMute = true //設置靜音
AudioEngineManager.get().isMute = true //不能説話
AudioEngineManager.get().setRole(Constants.CLIENT_ROLE_AUDIENCE)
}
}
fun openRoomSound() {
if (AvRoomDataManager.get().mCurrentRoomInfo != null) {
AudioEngineManager.get().isRemoteMute = isRemoteMute //非靜音
AudioEngineManager.get().isMute = isMute //能説話
AudioEngineManager.get()
.setRole(if (isMute) Constants.CLIENT_ROLE_AUDIENCE else Constants.CLIENT_ROLE_BROADCASTER)
}
}
fun saveRecord(audioUrl: String, second: Int = audioDur) {
this.audioUrl = audioUrl
safeLaunch(
onError = {
it.message.toast()
_hideLoadLiveData.value = null
},
block = {
_saveRecordLiveData.value = SoundModel.saveRecord(audioUrl, second)
}
)
}
fun deleteRecord() {
safeLaunch(
true,
block = {
_deleteRecordLiveData.value = SoundModel.deleteRecord()
}
)
}
}

View File

@@ -0,0 +1,121 @@
package com.chwl.app.audio.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.util.AttributeSet;
import android.view.View;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
/**
* Created by liruiyuan on 2015/12/21.
*/
public class DynamicWave extends View {
// y = Asin(wx+b)+h
private static final float STRETCH_FACTOR_A = 20;
private static final int OFFSET_Y = -50;
// 第一条水波移动速度
private static final int TRANSLATE_X_SPEED_ONE = 7;
// 第二条水波移动速度
private static final int TRANSLATE_X_SPEED_TWO = 5;
private float mCycleFactorW;
private int mTotalWidth, mTotalHeight;
private float[] mYPositions;
private float[] mResetOneYPositions;
private float[] mResetTwoYPositions;
private int mXOffsetSpeedOne;
private int mXOffsetSpeedTwo;
private int mXOneOffset;
private int mXTwoOffset;
private Paint mWavePaint;
private DrawFilter mDrawFilter;
public DynamicWave(Context context, AttributeSet attrs) {
super(context, attrs);
// 将dp转化为px用于控制不同分辨率上移动速度基本一致
mXOffsetSpeedOne = ScreenUtil.dip2px(TRANSLATE_X_SPEED_ONE);
mXOffsetSpeedTwo = ScreenUtil.dip2px(TRANSLATE_X_SPEED_TWO);
// 初始绘制波纹的画笔
mWavePaint = new Paint();
// 去除画笔锯齿
mWavePaint.setAntiAlias(true);
// 设置风格为实线
mWavePaint.setStyle(Paint.Style.FILL);
// 设置画笔颜色
mWavePaint.setColor(Color.parseColor("#26FFFFFF"));
mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 从canvas层面去除绘制时锯齿
canvas.setDrawFilter(mDrawFilter);
resetPositonY();
for (int i = 0; i < mTotalWidth; i++) {
// 减400只是为了控制波纹绘制的y在屏幕的位置大家可以改成一个变量然后动态改变这个变量从而形成波纹上升下降效果
// 绘制第一条水波纹
canvas.drawLine(i, mTotalHeight - mResetOneYPositions[i] - 200, i, mTotalHeight, mWavePaint);
// 绘制第二条水波纹
canvas.drawLine(i, mTotalHeight - mResetTwoYPositions[i] - 200, i, mTotalHeight, mWavePaint);
}
// 改变两条波纹的移动点
mXOneOffset += mXOffsetSpeedOne;
mXTwoOffset += mXOffsetSpeedTwo;
// 如果已经移动到结尾处,则重头记录
if (mXOneOffset >= mTotalWidth) {
mXOneOffset = 0;
}
if (mXTwoOffset > mTotalWidth) {
mXTwoOffset = 0;
}
// 引发view重绘一般可以考虑延迟20-30ms重绘空出时间片
postInvalidate();
}
private void resetPositonY() {
// mXOneOffset代表当前第一条水波纹要移动的距离
int yOneInterval = mYPositions.length - mXOneOffset;
// 使用System.arraycopy方式重新填充第一条波纹的数据
System.arraycopy(mYPositions, mXOneOffset, mResetOneYPositions, 0, yOneInterval);
System.arraycopy(mYPositions, 0, mResetOneYPositions, yOneInterval, mXOneOffset);
int yTwoInterval = mYPositions.length - mXTwoOffset;
System.arraycopy(mYPositions, mXTwoOffset, mResetTwoYPositions, 0, yTwoInterval);
System.arraycopy(mYPositions, 0, mResetTwoYPositions, yTwoInterval, mXTwoOffset);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 记录下view的宽高
mTotalWidth = w;
mTotalHeight = h;
// 用于保存原始波纹的y值
mYPositions = new float[mTotalWidth];
// 用于保存波纹一的y值
mResetOneYPositions = new float[mTotalWidth];
// 用于保存波纹二的y值
mResetTwoYPositions = new float[mTotalWidth];
// 将周期定为view总宽度
mCycleFactorW = (float) (2 * Math.PI / mTotalWidth);
// 根据view总宽度得出所有对应的y值
for (int i = 0; i < mTotalWidth; i++) {
mYPositions[i] = (float) (STRETCH_FACTOR_A * Math.sin(mCycleFactorW * i) + OFFSET_Y);
}
}
}

View File

@@ -0,0 +1,28 @@
package com.chwl.app.audio.widget;
import androidx.recyclerview.widget.RecyclerView;
/**
* 录制声音页面.声音卡片滑动监听
*/
public interface OnSwipeListener {
/**
* 卡片还在滑动时回调
*
* @param viewHolder 该滑动卡片的viewHolder
* @param ratio 滑动进度的比例
* @param direction 卡片滑动的方向CardConfig.SWIPING_LEFT 为向左滑CardConfig.SWIPING_RIGHT 为向右滑,
* CardConfig.SWIPING_NONE 为不偏左也不偏右
*/
void onSwiping(RecyclerView.ViewHolder viewHolder, float ratio, int direction);
/**
* 卡片完全滑出时回调
*
* @param viewHolder 该滑出卡片的viewHolder
* @param pos 该滑出卡片的索引
* @param direction 卡片滑出的方向CardConfig.SWIPED_LEFT 为左边滑出CardConfig.SWIPED_RIGHT 为右边滑出
*/
void onSwiped(RecyclerView.ViewHolder viewHolder, int pos, int direction);
}

View File

@@ -0,0 +1,115 @@
package com.chwl.app.audio.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.chwl.app.R;
/**
* 录制声音页面的环形进度条
*/
public class RingProgressView extends View {
// 圆环的颜色
private int ringColor = 0x00FFFFFF;
// 圆环进度的颜色
private int ringProgressColor = 0xFFFFFFFF;
// 圆环的宽度
private int ringWidth = ScreenUtil.dip2px(4);
// 当前进度
private int currentProgress = 0;
// 最大进度
private int maxProgress = 100;
// 得到控件的宽度
private int width;
// 画笔对象
private Paint paint;
// 圆弧
private RectF rectF;
// 默认的构造方法一般取这3个就够用了
public RingProgressView(Context context) {
this(context, null);
}
public RingProgressView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public RingProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 得到自定义资源数组
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RingProgressView);
ringColor = typedArray.getColor(R.styleable.RingProgressView_ringColor, ringColor);
ringProgressColor = typedArray.getColor(R.styleable.RingProgressView_ringProgressColor, ringProgressColor);
ringWidth = (int) typedArray.getDimension(R.styleable.RingProgressView_ringWidth, ringWidth);
currentProgress = typedArray.getInt(R.styleable.RingProgressView_currentProgress, currentProgress);
maxProgress = typedArray.getColor(R.styleable.RingProgressView_maxProgress, maxProgress);
typedArray.recycle();
initData();
}
private void initData() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(ringWidth);
paint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = getMeasuredWidth();
rectF = new RectF(ringWidth / 2, ringWidth / 2, width - ringWidth / 2, width - ringWidth / 2);
}
// 绘制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 1. 计算圆心坐标及半径
float centerX = width / 2;
float centerY = width / 2;
float radius = width / 2 - ringWidth / 2;
// 2. 画圆环
paint.setColor(ringColor);
canvas.drawCircle(centerX, centerY, radius, paint);
// 3. 画圆弧
paint.setColor(ringProgressColor);
canvas.drawArc(rectF, -90, currentProgress * 360 / maxProgress, false, paint);
}
public int getCurrentProgress() {
return currentProgress;
}
public void setCurrentProgress(int currentProgress) {
if (currentProgress > maxProgress) {
currentProgress = maxProgress;
}
this.currentProgress = currentProgress;
postInvalidate();
}
public int getMaxProgress() {
return maxProgress;
}
public void setMaxProgress(int maxProgress) {
this.maxProgress = maxProgress;
}
}

View File

@@ -0,0 +1,171 @@
package com.chwl.app.audio.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;
import com.chwl.app.R;
public class RoundProgressView extends View {
// 画实心圆的画笔
private Paint mCirclePaint;
// 画圆环的画笔
private Paint mRingPaint;
// 画圆环的画笔背景色
private Paint mRingPaintBg;
// 画字体的画笔
private Paint mTextPaint;
// 圆形颜色
private int mCircleColor;
// 圆环颜色
private int mRingColor;
// 圆环背景颜色
private int mRingBgColor;
// 半径
private float mRadius;
// 圆环半径
private float mRingRadius;
// 圆环宽度
private float mStrokeWidth;
// 圆心x坐标
private int mXCenter;
// 圆心y坐标
private int mYCenter;
// 字的长度
private float mTxtWidth;
// 字的高度
private float mTxtHeight;
// 总进度
private int mTotalProgress = 60000;
// 当前进度
private int mProgress;
private String string;
public RoundProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
// 获取自定义的属性
initAttrs(context, attrs);
initVariable();
}
//属性
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.RoundProgressView, 0, 0);
mRadius = typeArray.getDimension(R.styleable.RoundProgressView_round_radius, 80);
mStrokeWidth = typeArray.getDimension(R.styleable.RoundProgressView_round_strokeWidth, 10);
mCircleColor = typeArray.getColor(R.styleable.RoundProgressView_round_circleColor, 0xFFFFFFFF);
mRingColor = typeArray.getColor(R.styleable.RoundProgressView_round_ringColor, 0xFFFFFFFF);
mRingBgColor = typeArray.getColor(R.styleable.RoundProgressView_round_ringBgColor, 0xFFFFFFFF);
mRingRadius = mRadius + mStrokeWidth / 2;
}
RectF oval;
//初始化画笔
private void initVariable() {
oval = new RectF();
//内圆
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
mCirclePaint.setColor(mCircleColor);
mCirclePaint.setStyle(Paint.Style.FILL);
mCirclePaint.setStrokeCap(Paint.Cap.ROUND);
//外圆弧背景
mRingPaintBg = new Paint();
mRingPaintBg.setAntiAlias(true);
mRingPaintBg.setColor(mRingBgColor);
mRingPaintBg.setStyle(Paint.Style.STROKE);
mRingPaintBg.setStrokeWidth(mStrokeWidth);
//外圆弧
mRingPaint = new Paint();
mRingPaint.setAntiAlias(true);
//mRingPaint.setColor(mRingColor);
mRingPaint.setStyle(Paint.Style.STROKE);
mRingPaint.setStrokeWidth(mStrokeWidth);
mRingPaint.setStrokeCap(Paint.Cap.ROUND);//设置线冒样式,有圆 有方
//中间字
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaint.setColor(mRingColor);
mTextPaint.setTextSize(mRadius / 2);
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
mTxtHeight = (int) Math.ceil(fm.descent - fm.ascent);
}
SweepGradient sweepGradient;
//画图
@Override
protected void onDraw(Canvas canvas) {
mXCenter = getWidth() / 2;
mYCenter = getHeight() / 2;
//内圆
canvas.drawCircle(mXCenter, mYCenter, mRadius, mCirclePaint);
//外圆弧背景
RectF oval1 = new RectF();
oval1.left = (mXCenter - mRingRadius);
oval1.top = (mYCenter - mRingRadius);
oval1.right = mRingRadius * 2 + (mXCenter - mRingRadius);
oval1.bottom = mRingRadius * 2 + (mYCenter - mRingRadius);
canvas.drawArc(oval1, 0, 360, false, mRingPaintBg); //圆弧所在的椭圆对象、圆弧的起始角度、圆弧的角度、是否显示半径连线
//外圆弧
if (mProgress > 0 ) {
oval.left = (mXCenter - mRingRadius);
oval.top = (mYCenter - mRingRadius);
oval.right = mRingRadius * 2 + (mXCenter - mRingRadius);
oval.bottom = mRingRadius * 2 + (mYCenter - mRingRadius);
if (sweepGradient==null) {
int[] arcColors= new int[]{Color.parseColor("#CC67FF"),
Color.parseColor("#9DB4FF"),
Color.parseColor("#13E2F5"),
Color.parseColor("#CC67FF")};
float[] arcPostion=new float[]{0.0f,0.25f,0.75f,1f};
//sweepGradient = new SweepGradient(mXCenter, mYCenter, mRingColor,Color.parseColor("#b05e39"));
sweepGradient = new SweepGradient(mXCenter, mYCenter, arcColors,arcPostion);
Matrix matrix = new Matrix();
matrix.setRotate(-90,mXCenter,mYCenter);
sweepGradient.setLocalMatrix(matrix);
mRingPaint.setShader(sweepGradient);
}
canvas.drawArc(oval, -90, ((float)mProgress / mTotalProgress) * 360, false, mRingPaint); //
//字体
// String txt = mProgress + "%";
// mTxtWidth = mTextPaint.measureText(txt, 0, txt.length());
// canvas.drawText(txt, mXCenter - mTxtWidth / 2, mYCenter + mTxtHeight / 4, mTextPaint);
}
}
public void setText(String string){
}
//设置进度
public void setProgress(int progress) {
mProgress = progress;
postInvalidate();//重绘
}
//设置总进度
public void setTotalProgress(int totalProgress) {
mTotalProgress = totalProgress;
}
}

View File

@@ -0,0 +1,105 @@
package com.chwl.app.audio.widget;
import android.content.Context;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.chwl.app.R;
/**
* 声音瓶子.筛选性别Dialog
*/
public class VoiceBottleFilterGenderBottomDialog extends BottomSheetDialog {
private RadioGroup rgVoiceFilterGender;
private TextView btnConfirm;
private int currentFilterGender;
private OnVoiceBottleFilterGenderListener onFilterGenderListener;
public VoiceBottleFilterGenderBottomDialog(@NonNull Context context, int currentFilterGender, OnVoiceBottleFilterGenderListener onFilterGenderListener) {
super(context);
this.currentFilterGender = currentFilterGender;
this.onFilterGenderListener = onFilterGenderListener;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewGroup view = (ViewGroup) View.inflate(getContext(), R.layout.layout_voice_bottle_filter_gender_bottom_dialog, null);
RadioButton rbVoiceFilterGenderFemale = view.findViewById(R.id.rb_voice_filter_gender_female);
RadioButton rbVoiceFilterGenderMale = view.findViewById(R.id.rb_voice_filter_gender_male);
RadioButton rbVoiceFilterGenderAll = view.findViewById(R.id.rb_voice_filter_gender_all);
rgVoiceFilterGender = view.findViewById(R.id.rg_voice_filter_gender);
btnConfirm = view.findViewById(R.id.btn_confirm);
if (currentFilterGender == 1) {
rbVoiceFilterGenderFemale.setChecked(false);
rbVoiceFilterGenderMale.setChecked(true);
rbVoiceFilterGenderAll.setChecked(false);
} else if (currentFilterGender == 2) {
rbVoiceFilterGenderFemale.setChecked(true);
rbVoiceFilterGenderMale.setChecked(false);
rbVoiceFilterGenderAll.setChecked(false);
} else {
rbVoiceFilterGenderFemale.setChecked(false);
rbVoiceFilterGenderMale.setChecked(false);
rbVoiceFilterGenderAll.setChecked(true);
}
setContentView(view);
Window window = getWindow();
if (window == null) {
return;
}
WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
if (windowManager == null) {
return;
}
Display display = windowManager.getDefaultDisplay();
WindowManager.LayoutParams params = window.getAttributes();
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
DisplayMetrics realDisplayMetrics = new DisplayMetrics();
display.getRealMetrics(realDisplayMetrics);
window.setAttributes(params);
window.setWindowAnimations(R.style.ErbanCommonWindowAnimationStyle);
window.findViewById(R.id.design_bottom_sheet).setBackgroundResource(android.R.color.transparent);
setCancelable(false);
setListener();
}
private void setListener() {
btnConfirm.setOnClickListener(view -> {
if (onFilterGenderListener != null) {
if (rgVoiceFilterGender.getCheckedRadioButtonId() == R.id.rb_voice_filter_gender_female) {
onFilterGenderListener.onFilterGender(2);
} else if (rgVoiceFilterGender.getCheckedRadioButtonId() == R.id.rb_voice_filter_gender_male) {
onFilterGenderListener.onFilterGender(1);
} else if (rgVoiceFilterGender.getCheckedRadioButtonId() == R.id.rb_voice_filter_gender_all) {
onFilterGenderListener.onFilterGender(0);
}
}
dismiss();
});
}
public interface OnVoiceBottleFilterGenderListener {
/**
* @param gender 0.不限 1.男 2.女
*/
void onFilterGender(int gender);
}
}

View File

@@ -0,0 +1,43 @@
package com.chwl.app.audio.widget;
/**
* 录制声音页面.声音卡片滑动配置
*/
public class VoiceCardConfig {
/**
* 显示可见的卡片数量
*/
public static final int DEFAULT_SHOW_ITEM = 3;
/**
* 默认缩放的比例
*/
public static final float DEFAULT_SCALE = 0.1f;
/**
* 卡片Y轴偏移量时按照14等分计算
*/
public static final int DEFAULT_TRANSLATE_Y = 14;
/**
* 卡片滑动时默认倾斜的角度
*/
public static final float DEFAULT_ROTATE_DEGREE = 15f;
/**
* 卡片滑动时不偏左也不偏右
*/
public static final int SWIPING_NONE = 1;
/**
* 卡片向左滑动时
*/
public static final int SWIPING_LEFT = 1 << 2;
/**
* 卡片向右滑动时
*/
public static final int SWIPING_RIGHT = 1 << 3;
/**
* 卡片从左边滑出
*/
public static final int SWIPED_LEFT = 1;
/**
* 卡片从右边滑出
*/
public static final int SWIPED_RIGHT = 1 << 2;;
}

View File

@@ -0,0 +1,156 @@
package com.chwl.app.audio.widget;
import android.graphics.Canvas;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.library.utils.ResUtil;
/**
* 录制声音页面.声音卡片滑动列表ItemTouchHelperCallback
*/
public class VoiceCardItemTouchHelperCallback extends ItemTouchHelper.Callback {
private OnSwipeListener mListener;
public void setOnSwipedListener(OnSwipeListener mListener) {
this.mListener = mListener;
}
/**
* 让RecyclerView拦截上下左右的滑动
*
* @return 调用makeMovementFlags()
*/
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
int dragFlags = 0;
int swipeFlags = 0;
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof VoiceCardLayoutManager) {
swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
}
return makeMovementFlags(dragFlags, swipeFlags);
}
/**
* 针对drag状态在canDropOver()返回true时会调用该方法
* 可以实现拖动换位置的逻辑(需要自己处理变换位置的逻辑)
*/
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}
/**
* 针对swipe和drag状态当一个item view在swipe、drag状态结束的时候调用
* drag状态当手指释放的时候会调用
* swipe状态当item从RecyclerView中删除的时候调用一般我们会在onSwiped()函数里面删除掉指定的item view
*/
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
Log.e("ItemTouchHelperCallback", "clearView--->");
viewHolder.itemView.setRotation(0f);
viewHolder.itemView.setAlpha(1);
viewHolder.itemView.setScaleY(1);
viewHolder.itemView.setScaleX(1);
}
/**
* 针对swipe和drag状态整个过程中一直会调用这个函数,随手指移动的view就是在super里面做到的(和ItemDecoration里面的onDraw()函数对应)
*/
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder,
float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
Log.e("ItemTouchHelperCallback", "onChildDraw--->"
+ " dX = " + dX
+ " dY = " + dY
+ " actionState = " + actionState
+ " isCurrentlyActive = " + isCurrentlyActive);
View itemView = viewHolder.itemView;
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
float ratio = dX / getThreshold(recyclerView, viewHolder);
// ratio 最大为 1 或 -1
if (ratio > 1) {
ratio = 1;
} else if (ratio < -1) {
ratio = -1;
}
itemView.setRotation(ratio * VoiceCardConfig.DEFAULT_ROTATE_DEGREE);
int childCount = recyclerView.getChildCount();
// 当数据源个数大于最大显示数时
if (childCount > VoiceCardConfig.DEFAULT_SHOW_ITEM) {
for (int position = 1; position < childCount - 1; position++) {
int index = childCount - position - 1;
View view = recyclerView.getChildAt(position);
view.setScaleX(1 - index * VoiceCardConfig.DEFAULT_SCALE + Math.abs(ratio) * VoiceCardConfig.DEFAULT_SCALE);
view.setScaleY(1 - index * VoiceCardConfig.DEFAULT_SCALE + Math.abs(ratio) * VoiceCardConfig.DEFAULT_SCALE);
view.setTranslationY((index - Math.abs(ratio)) * itemView.getMeasuredHeight() / VoiceCardConfig.DEFAULT_TRANSLATE_Y);
}
} else {
// 当数据源个数小于或等于最大显示数时
for (int position = 0; position < childCount - 1; position++) {
int index = childCount - position - 1;
View view = recyclerView.getChildAt(position);
view.setScaleX(1 - index * VoiceCardConfig.DEFAULT_SCALE + Math.abs(ratio) * VoiceCardConfig.DEFAULT_SCALE);
view.setScaleY(1 - index * VoiceCardConfig.DEFAULT_SCALE + Math.abs(ratio) * VoiceCardConfig.DEFAULT_SCALE);
view.setTranslationY((index - Math.abs(ratio)) * itemView.getMeasuredHeight() / VoiceCardConfig.DEFAULT_TRANSLATE_Y);
}
}
if (mListener != null) {
if (ratio != 0) {
mListener.onSwiping(viewHolder, ratio, ratio < 0 ? VoiceCardConfig.SWIPING_LEFT : VoiceCardConfig.SWIPING_RIGHT);
} else {
mListener.onSwiping(viewHolder, ratio, VoiceCardConfig.SWIPING_NONE);
}
}
}
}
/**
* 针对swipe和drag状态当swipe或者drag对应的ViewHolder改变的时候调用可以通过重写这个函数获取到swipe、drag开始和结束时机
* viewHolder 不为空的时候是开始,空的时候是结束
*/
@Override
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
Log.e("ItemTouchHelperCallback", "onSelectedChanged--->" + (viewHolder == null ? ResUtil.getString(R.string.audio_widget_voicecarditemtouchhelpercallback_01) + actionState : ResUtil.getString(R.string.audio_widget_voicecarditemtouchhelpercallback_02) + actionState));
}
/**
* 针对swipe状态是否允许swipe(滑动)操作
*/
@Override
public boolean isItemViewSwipeEnabled() {
Log.e("ItemTouchHelperCallback", "isItemViewSwipeEnabled--->");
return true;
}
/**
* 针对swipe状态swipe 到达滑动消失的距离会回调函数
* 一般在这个函数里面处理删除item的逻辑
* 确切的来讲是swipe item滑出屏幕动画结束的时候调用
*/
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
Log.e("ItemTouchHelperCallback", "onSwiped--->");
// 移除 onTouchListener,否则触摸滑动会乱了
viewHolder.itemView.setOnTouchListener(null);
int layoutPosition = viewHolder.getLayoutPosition();
// 移除完item时回调 mListener
if (mListener != null) {
mListener.onSwiped(viewHolder, layoutPosition, direction == ItemTouchHelper.LEFT ? VoiceCardConfig.SWIPED_LEFT : VoiceCardConfig.SWIPED_RIGHT);
}
}
private float getThreshold(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return recyclerView.getWidth() * getSwipeThreshold(viewHolder);
}
}

View File

@@ -0,0 +1,110 @@
package com.chwl.app.audio.widget;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.core.view.MotionEventCompat;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
/**
* 录制声音页面.声音卡片滑动列表LayoutManager
*/
public class VoiceCardLayoutManager extends RecyclerView.LayoutManager {
private RecyclerView mRecyclerView;
private ItemTouchHelper mItemTouchHelper;
public VoiceCardLayoutManager(@NonNull RecyclerView recyclerView, @NonNull ItemTouchHelper itemTouchHelper) {
this.mRecyclerView = checkIsNull(recyclerView);
this.mItemTouchHelper = checkIsNull(itemTouchHelper);
}
private <T> T checkIsNull(T t) {
if (t == null) {
throw new NullPointerException();
}
return t;
}
/**
* 给RecyclerView的ItemView生成LayoutParams
*/
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
/**
* 布局ItemView
*/
@Override
public void onLayoutChildren(final RecyclerView.Recycler recycler, RecyclerView.State state) {
detachAndScrapAttachedViews(recycler);
int itemCount = getItemCount();
// 当数据源个数大于最大显示数时
if (itemCount > VoiceCardConfig.DEFAULT_SHOW_ITEM) {
for (int position = VoiceCardConfig.DEFAULT_SHOW_ITEM; position >= 0; position--) {
final View view = recycler.getViewForPosition(position);
addView(view);
measureChildWithMargins(view, 0, 0);
int widthSpace = getWidth() - getDecoratedMeasuredWidth(view);
int heightSpace = getHeight() - getDecoratedMeasuredHeight(view);
// recyclerView 布局
layoutDecoratedWithMargins(view, widthSpace / 2, heightSpace / 2,
widthSpace / 2 + getDecoratedMeasuredWidth(view),
heightSpace / 2 + getDecoratedMeasuredHeight(view));
if (position == VoiceCardConfig.DEFAULT_SHOW_ITEM) {
view.setScaleX(1 - (position - 1) * VoiceCardConfig.DEFAULT_SCALE);
view.setScaleY(1 - (position - 1) * VoiceCardConfig.DEFAULT_SCALE);
view.setTranslationY((position - 1) * view.getMeasuredHeight() / VoiceCardConfig.DEFAULT_TRANSLATE_Y);
view.setOnTouchListener(null);
} else if (position > 0) {
view.setScaleX(1 - position * VoiceCardConfig.DEFAULT_SCALE);
view.setScaleY(1 - position * VoiceCardConfig.DEFAULT_SCALE);
view.setTranslationY(position * view.getMeasuredHeight() / VoiceCardConfig.DEFAULT_TRANSLATE_Y);
view.setOnTouchListener(null);
} else {
view.setOnTouchListener(mOnTouchListener);
}
}
} else {
// 当数据源个数小于或等于最大显示数时
for (int position = itemCount - 1; position >= 0; position--) {
final View view = recycler.getViewForPosition(position);
addView(view);
measureChildWithMargins(view, 0, 0);
int widthSpace = getWidth() - getDecoratedMeasuredWidth(view);
int heightSpace = getHeight() - getDecoratedMeasuredHeight(view);
// recyclerView 布局
layoutDecoratedWithMargins(view, widthSpace / 2, heightSpace / 2,
widthSpace / 2 + getDecoratedMeasuredWidth(view),
heightSpace / 2 + getDecoratedMeasuredHeight(view));
if (position > 0) {
view.setScaleX(1 - position * VoiceCardConfig.DEFAULT_SCALE);
view.setScaleY(1 - position * VoiceCardConfig.DEFAULT_SCALE);
view.setTranslationY(position * view.getMeasuredHeight() / VoiceCardConfig.DEFAULT_TRANSLATE_Y);
view.setOnTouchListener(null);
} else {
view.setOnTouchListener(mOnTouchListener);
}
}
}
}
private View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
RecyclerView.ViewHolder childViewHolder = mRecyclerView.getChildViewHolder(v);
if (MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
mItemTouchHelper.startSwipe(childViewHolder);
}
return false;
}
};
}

View File

@@ -0,0 +1,38 @@
package com.chwl.app.audio.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
/**
* 录制声音页面.声音卡片滑动列表
*/
public class VoiceCardRecyclerView extends RecyclerView {
private Canvas canvas;
public VoiceCardRecyclerView(Context context) {
super(context);
}
public VoiceCardRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public VoiceCardRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onDraw(Canvas c) {
canvas = c;
super.onDraw(c);
}
public Canvas getCanvas() {
return canvas;
}
}

View File

@@ -0,0 +1,225 @@
package com.chwl.app.audio.widget;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.chwl.app.R;
import java.util.ArrayList;
import java.util.List;
/**
* 声音播放的波纹
*/
public class VoiceLine extends View {
public static final int VOICE_LINE_STYLE_REGULAR_LINE = 1;// 缺省图的规律的效果
public static final int VOICE_LINE_STYLE_VOICE_CORRUGATED = 2;// 播放声音的动画效果:9个线条
/*画笔*/
private Paint mPaint;
/*lineView*/
private RectF[] lineList;
/*lineView.height*/
private List<Integer> lineHeightList = new ArrayList<>();
/*lineView.Top坐标 Bottom坐标*/
private List<Float> lineTopList = new ArrayList<>();
private List<Float> lineBottomList = new ArrayList<>();
/*属性*/
private int lineStyle = VOICE_LINE_STYLE_REGULAR_LINE;// 展示效果,默认:缺省图的规律的效果
private float lineWidth = ScreenUtil.dip2px(3);// 线条宽度单位PX
private float lineRadius = lineWidth / 2;// 线条圆角,为线条宽度的一半
private float lineSpace = lineWidth;// 线条之间的间隙
private int lineCount = 5;// 线条数量默认5
private float lineHeightMin = ScreenUtil.dip2px(15);// 线条最小高度
private float lineHeightMax = ScreenUtil.dip2px(28);// 线条最大高度
private float lineHeightMiddle = (lineHeightMax - lineHeightMin) / 2 + lineHeightMin;// 线条中界的数值:控制拉伸收缩
/*动画*/
private boolean isPlayingAnim = false;
private ValueAnimator valueAnimator;
private float fraction;
public VoiceLine(Context context) {
this(context, null);
}
public VoiceLine(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public VoiceLine(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(context, attrs);
init();
}
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.VoiceLine);
lineStyle = typedArray.getInt(R.styleable.VoiceLine_voice_line_style, lineStyle);
lineWidth = typedArray.getDimension(R.styleable.VoiceLine_voice_line_width, lineWidth);
lineRadius = lineWidth / 2;
lineSpace = lineWidth;
lineCount = typedArray.getInt(R.styleable.VoiceLine_voice_line_count, lineCount);
if (lineStyle == VOICE_LINE_STYLE_VOICE_CORRUGATED) {// 如果是播放声音的动画效果默认就是9个线条
lineCount = 9;
}
lineList = new RectF[lineCount];
lineHeightMin = typedArray.getDimension(R.styleable.VoiceLine_voice_line_height_min, lineHeightMin);
lineHeightMax = typedArray.getDimension(R.styleable.VoiceLine_voice_line_height_max, lineHeightMax);
/*设置中界的数值:控制拉伸收缩*/
if (lineStyle == VOICE_LINE_STYLE_VOICE_CORRUGATED) {// 如果是播放声音的动画效果默认中界数值为10
lineHeightMiddle = ScreenUtil.dip2px(10);
} else {
lineHeightMiddle = (lineHeightMax - lineHeightMin) / 2 + lineHeightMin;
}
typedArray.recycle();
}
private void init() {
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.FILL);
valueAnimator = ValueAnimator.ofInt(0, 1);
valueAnimator.setDuration(500);
valueAnimator.setRepeatCount(-1);
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
valueAnimator.addUpdateListener(animation -> {
fraction = animation.getAnimatedFraction();
postInvalidate();
});
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// 高度
lineHeightList.clear();
if (lineStyle == VOICE_LINE_STYLE_VOICE_CORRUGATED) {// 如果是播放声音的动画效果:给线条指定高度
lineHeightList.add(ScreenUtil.dip2px(10));
lineHeightList.add(ScreenUtil.dip2px(16));
lineHeightList.add(ScreenUtil.dip2px(10));
lineHeightList.add(ScreenUtil.dip2px(6));
lineHeightList.add(ScreenUtil.dip2px(10));
lineHeightList.add(ScreenUtil.dip2px(12));
lineHeightList.add(ScreenUtil.dip2px(19));
lineHeightList.add(ScreenUtil.dip2px(11));
lineHeightList.add(ScreenUtil.dip2px(7));
lineWidth = ScreenUtil.dip2px(3);
lineRadius = lineWidth / 2;
lineSpace = lineWidth;
} else {
for (int i = 0; i < lineCount; i++) {
if (i == 0) {
lineHeightList.add((int) lineHeightMax);
} else if (i == lineCount - 1) {
lineHeightList.add((int) lineHeightMax);
} else {
lineHeightList.add((int) lineHeightMin);
}
}
lineWidth = ScreenUtil.dip2px(6);
lineRadius = lineWidth / 2;
lineSpace = lineWidth;
}
// 左边的坐标
float[] lineLeftList = new float[lineCount];
for (int i = 0; i < lineCount; i++) {
if (i == 0) {
lineLeftList[i] = 0f;
} else {
lineLeftList[i] = lineLeftList[i - 1] + lineWidth + lineSpace;
}
}
// 右边的坐标
float[] lineRightList = new float[lineCount];
for (int i = 0; i < lineCount; i++) {
lineRightList[i] = lineLeftList[i] + lineSpace;
}
// Top坐标
lineTopList.clear();
float lineMaxHeight = getMeasuredHeight();// 单位PX
for (int i = 0; i < lineCount; i++) {
lineTopList.add((lineMaxHeight - lineHeightList.get(i)) / 2);
}
// Bottom坐标
lineBottomList.clear();
for (int i = 0; i < lineCount; i++) {
lineBottomList.add(lineTopList.get(i) + lineHeightList.get(i));
}
// LineView
for (int i = 0; i < lineCount; i++) {
lineList[i] = new RectF(lineLeftList[i], lineTopList.get(i), lineRightList[i], lineBottomList.get(i));
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isPlayingAnim) {
for (int i = 0; i < lineList.length; i++) {
lineList[i].top = lineTopList.get(i);
lineList[i].bottom = lineBottomList.get(i);
canvas.drawRoundRect(lineList[i], lineRadius, lineRadius, mPaint);
}
} else {
for (int i = 0; i < lineList.length; i++) {
int centerIndex = lineList.length % 2 == 0 ? lineList.length / 2 : lineList.length / 2 + 1;
if (i == centerIndex - 1) {// 中间拉伸并且增加长度
lineList[i].top = lineTopList.get(i) - fraction / 2 * lineHeightList.get(i);
lineList[i].bottom = lineBottomList.get(i) + fraction / 2 * lineHeightList.get(i);
canvas.drawRoundRect(lineList[i], lineRadius, lineRadius, mPaint);
} else {
if (lineHeightList.get(i) <= lineHeightMiddle) {// 拉伸
lineList[i].top = lineTopList.get(i) - fraction / 2 * lineHeightList.get(i) * 0.5f;
lineList[i].bottom = lineBottomList.get(i) + fraction / 2 * lineHeightList.get(i) * 0.5f;
canvas.drawRoundRect(lineList[i], lineRadius, lineRadius, mPaint);
} else {// 收缩
lineList[i].top = lineTopList.get(i) + fraction / 2 * lineHeightList.get(i) * 0.5f;
lineList[i].bottom = lineBottomList.get(i) - fraction / 2 * lineHeightList.get(i) * 0.5f;
canvas.drawRoundRect(lineList[i], lineRadius, lineRadius, mPaint);
}
}
}
}
}
public void startAnim() {
this.isPlayingAnim = true;
valueAnimator.start();
}
public void stopAnim() {
this.isPlayingAnim = false;
if (valueAnimator != null) {
valueAnimator.cancel();
}
postInvalidate();
}
}

View File

@@ -0,0 +1,193 @@
package com.chwl.app.audio.widget;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.chwl.app.R;
import java.util.ArrayList;
import java.util.List;
/**
* 录制声音的波纹
*/
public class VoiceWave extends View {
private Paint paintVoiceLine;
private List<Path> paths = null;
/*属性*/
private int voiceLineColor = Color.WHITE;// 波动的线的颜色
private int lineSpeed = 90;// 波动线的横向移动速度数值越大线移动越慢默认90
private float maxVolume = 100;// 所输入音量的最大值
private int sensibility = 4;// 灵敏度
private int fineness = 1;// 精细度绘制曲线的时候每几个像素绘制一次默认是1值越小曲线越顺滑
// 音量
private float volume = 10;
private float targetVolume = 1;
private long lastTime = 0;// 记录最后绘制的时间
private float translateX = 0;
private boolean isSet = false;
private boolean isClear = true;// 是否清楚为初始状态,清空振幅
private ValueAnimator valueAnimator;
private int viewHeight;
public VoiceWave(Context context) {
super(context);
}
public VoiceWave(Context context, AttributeSet attrs) {
super(context, attrs);
initAttrs(context, attrs);
initData();
}
public VoiceWave(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(context, attrs);
initData();
}
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.VoiceWave);
voiceLineColor = typedArray.getColor(R.styleable.VoiceWave_voice_wave_line_color, voiceLineColor);
lineSpeed = typedArray.getInt(R.styleable.VoiceWave_voice_wave_line_speed, lineSpeed);
maxVolume = typedArray.getFloat(R.styleable.VoiceWave_voice_wave_max_volume, maxVolume);
sensibility = typedArray.getInt(R.styleable.VoiceWave_voice_wave_sensibility, sensibility);
fineness = typedArray.getInt(R.styleable.VoiceWave_voice_wave_fineness, fineness);
typedArray.recycle();
}
private void initData() {
paths = new ArrayList<>(2);
for (int i = 0; i < 2; i++) {
paths.add(new Path());
}
paintVoiceLine = new Paint();
paintVoiceLine.setColor(voiceLineColor);
paintVoiceLine.setAntiAlias(true);
paintVoiceLine.setStyle(Paint.Style.STROKE);
paintVoiceLine.setStrokeWidth(ScreenUtil.dip2px(2));
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewHeight = getHeight();
}
@Override
protected void onDraw(Canvas canvas) {
lineChange();
canvas.save();
int moveY = viewHeight / 2;
for (int i = 0; i < paths.size(); i++) {
paths.get(i).reset();
paths.get(i).moveTo(getWidth(), viewHeight / 2);
}
for (float i = getWidth() - 1; i >= 0; i -= fineness) {
// 振幅
float amplitude;
if (isClear) {
amplitude = 1;
} else {
amplitude = volume * i / getWidth() - volume * i * i / getWidth() / getWidth();
}
// Log.e("VoiceWave", ResUtil.getString(R.string.audio_widget_voicewave_01) + isClear + ResUtil.getString(R.string.audio_widget_voicewave_02) + amplitude);
for (int n = 1; n <= paths.size(); n++) {
float sin = amplitude * (float) Math.sin((i - Math.pow(1.22, n)) * Math.PI / 180 - translateX);
float lineToY;
if (n == 1) {
lineToY = 10 * sin / paths.size() + moveY;
} else {
lineToY = 25 * sin / paths.size() + moveY;
}
// float lineToY = 2 * n * sin / paths.size() - 15 * sin / paths.size() + moveY;
paths.get(n - 1).lineTo(i, lineToY);
}
}
for (int n = 0; n < paths.size(); n++) {
if (n == 0) {
paintVoiceLine.setAlpha(255);
} else {
paintVoiceLine.setAlpha(200);
}
if (paintVoiceLine.getAlpha() > 0) {
canvas.drawPath(paths.get(n), paintVoiceLine);
}
}
canvas.restore();
}
private void lineChange() {
if (lastTime == 0) {
lastTime = System.currentTimeMillis();
translateX += 1.5;
} else {
if (System.currentTimeMillis() - lastTime > lineSpeed) {
lastTime = System.currentTimeMillis();
translateX += 1.5;
} else {
return;
}
}
if (volume < targetVolume && isSet) {
volume += viewHeight / 30;
} else {
isSet = false;
if (volume <= 10) {
volume = 10;
} else {
if (volume < viewHeight / 30) {
volume -= viewHeight / 60;
} else {
volume -= viewHeight / 30;
}
}
}
}
public void setVolume(int volume) {
if (volume > maxVolume * sensibility / 25) {
isSet = true;
targetVolume = viewHeight * volume / 2 / maxVolume;
}
}
public void startAnim() {
isClear = false;
if (valueAnimator == null) {
valueAnimator = ValueAnimator.ofInt(0, 1);
valueAnimator.setDuration(500);
valueAnimator.setRepeatCount(-1);
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
valueAnimator.addUpdateListener(valueAnimator -> invalidate());
}
if (!valueAnimator.isRunning()) {
valueAnimator.start();
}
}
public void stopAnim() {
isClear = true;
postInvalidate();
if (valueAnimator != null) {
valueAnimator.cancel();
valueAnimator = null;
}
}
}

View File

@@ -0,0 +1,53 @@
package com.chwl.app.avroom;
/**
* Created by chenran on 2017/11/21.
*/
public abstract class BottomViewListenerWrapper {
public BottomViewListenerWrapper() {
}
public void onOpenMicBtnClick(int type) {
}
public void onSendMsgBtnClick() {
}
public void onSendFaceBtnClick() {
}
public void onSendGiftBtnClick() {
}
public void onRemoteMuteBtnClick() {
}
public void onMoreBtnClick() {
}
/**
* 点击排麦按钮
*/
public void onMicQueueClick() {
}
/**
* 房间内私聊
*/
public void onRoomMessageClick() {
}
public void onRoomGameplayClick(boolean isOnlyPK){
}
}

View File

@@ -0,0 +1,529 @@
package com.chwl.app.avroom;
import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;
import com.chwl.app.R;
import com.chwl.app.UIHelper;
import com.chwl.app.avroom.widget.ViewItem;
import com.chwl.app.common.util.DialogCommonUtil;
import com.chwl.app.common.widget.dialog.DialogManager;
import com.chwl.app.room_chat.fragment.RoomMsgTabFragment;
import com.chwl.app.ui.im.avtivity.NimFriendModel;
import com.chwl.app.ui.im.avtivity.NimP2PMessageActivity;
import com.chwl.app.ui.widget.ButtonItem;
import com.chwl.app.ui.widget.GiftDialog;
import com.chwl.app.vip.util.VipHelper;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.bean.RoomQueueInfo;
import com.chwl.core.bean.response.ServiceResult;
import com.chwl.core.initial.InitialModel;
import com.chwl.core.initial.bean.InitInfo;
import com.chwl.core.kick.KickModel;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.manager.IMNetEaseManager;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.core.room.model.AvRoomModel;
import com.chwl.core.statistic.StatLogKey;
import com.chwl.core.super_admin.bean.KickOutExtBean;
import com.chwl.core.super_admin.model.SuperAdminModel;
import com.chwl.core.super_admin.util.SAdminOptUtil;
import com.chwl.core.super_admin.util.SaAttachmentFactory;
import com.chwl.core.super_admin.util.SuperAdminUtil;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.library.common.util.OtherExtKt;
import com.chwl.library.net.rxnet.callback.CallBack;
import com.chwl.library.utils.JavaUtil;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.SingleToastUtil;
import com.chwl.library.utils.config.BasicConfig;
import com.example.lib_utils.ktx.ResourcesKtxKt;
import com.hjq.toast.ToastUtils;
import com.netease.nim.uikit.business.uinfo.UserInfoHelper;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage;
import com.orhanobut.logger.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.functions.Function;
/**
* @author chenran
* @date 2017/10/11
*/
public class ButtonItemFactory {
/**
* 创建相关的buttons 添加到资料卡片
*
* @param context context
* @param uid uid or 云信account
* @param isNeedGiftItem ture能送礼物
* @param isNeedRoomItem ture表示房间相关的操作比如踢出房间外部调用一般置为false
* @param isInRoom ture表现在房间内giftdialog在不在房间有不同的ui
* @param listener dialog的监听回调
* @return List<ViewItem>
*/
public static List<ViewItem> createCommonButtonItems(
Context context,
UserInfo userInfo,
long uid,
boolean isNeedGiftItem,
boolean isNeedRoomItem,
boolean isInRoom,
GiftDialog.OnGiftDialogBtnClickListener listener) {
if (uid <= 0) return null;
String account = String.valueOf(uid);
// 判断在不在麦上
RoomQueueInfo roomQueueInfo = AvRoomDataManager.get().getRoomQueueMemberInfoByAccount(account);
// 麦上的人员信息,麦上的坑位信息
ChatRoomMember chatRoomMember = null;
String currentUid = String.valueOf(AuthModel.get().getCurrentUid());
//null表示不在麦位比如点击公屏的用户时
if (roomQueueInfo != null && roomQueueInfo.mChatRoomMember != null) {
chatRoomMember = new ChatRoomMember();
chatRoomMember.setAccount(roomQueueInfo.mChatRoomMember.getAccount());
chatRoomMember.setNick(roomQueueInfo.mChatRoomMember.getNick());
chatRoomMember.setAvatar(roomQueueInfo.mChatRoomMember.getAvatar());
}
if (chatRoomMember == null) {
chatRoomMember = AvRoomDataManager.get().getChatRoomMember(account);
}
//account和chatRoomMember 不会同时为空,如果同时为空,则是前面传参出错
boolean isMySelf = Objects.equals(currentUid, account);
if (isMySelf) {
return null;
}
String nick = getNick(chatRoomMember, account);
List<ViewItem> buttonItems = new ArrayList<>();
//ture则表示需要传入此类型button
boolean gift = false;
if (isNeedGiftItem) {
gift = true;
}
//提出房间
boolean kickOutRoom = false;
//设置管理员
boolean mark_manager = false;
//取消管理员
boolean no_mark_manager = false;
//黑名单
boolean mart_black = false;
boolean isTargetRoomAdmin = AvRoomDataManager.get().isRoomAdmin(account);
boolean isTargetRoomOwner = AvRoomDataManager.get().isRoomOwner(account);
boolean isTargetSuperAdmin = AvRoomDataManager.get().isSuperAdmin(account);
//资料卡片需要房间操作的按钮,不去判断是否在房间内
if (AvRoomDataManager.get().isRoomOwner() || AvRoomDataManager.get().isSuperAdmin()) {
//房主操作
//点击不是自己
if (isNeedRoomItem && !isTargetSuperAdmin) {
//提出房间
kickOutRoom = true;
//管理员
if (!isTargetRoomAdmin) {
mark_manager = true;
} else {
no_mark_manager = true;
}
//黑名单
mart_black = true;
}
} else if (AvRoomDataManager.get().isRoomAdmin()) {
//管理员操作
//不是自己
if (!isTargetRoomAdmin && !isTargetRoomOwner && !isTargetSuperAdmin) {
//非房主或管理员
if (isNeedRoomItem) {
//踢出房间
kickOutRoom = true;
//加入黑名单
mart_black = true;
}
}
}
// if (gift) {
// if (!SuperAdminUtil.isSuperAdmin()) {
// buttonItems.add(createSendGiftItem(context, uid, isInRoom, listener));
// }
// }
// 私聊
// buttonItems.add(createPrivateChatItem(context, account, isInRoom));
//关注
// buttonItems.add(createAttentItem());
//aite @
// buttonItems.add(createAtItem());
final RoomInfo currentRoom = AvRoomDataManager.get().mCurrentRoomInfo;
if (currentRoom == null) return buttonItems;
//超管能踢人拉黑用户,房主除外
if (!isTargetRoomOwner && SuperAdminUtil.isSuperAdmin()) {
kickOutRoom = true;
mart_black = true;
}
if (kickOutRoom) {
buttonItems.add(createKickOutRoomItem(context, userInfo, String.valueOf(currentRoom.getRoomId()),
account, nick));
}
if (mark_manager) {
buttonItems.add(createMarkManagerListItem(context,String.valueOf(currentRoom.getRoomId()), account, nick,true));
}
if (no_mark_manager) {
buttonItems.add(createMarkManagerListItem(context,String.valueOf(currentRoom.getRoomId()), account, nick,false));
}
if (mart_black) {
buttonItems.add(createMarkBlackListItem(
context,
userInfo,
String.valueOf(currentRoom.getRoomId()),
account,
nick)
);
}
return buttonItems;
}
/**
* 根据account获取昵称
*/
private static String getNick(ChatRoomMember member, String account) {
String nick = null;
if (member != null) {
nick = member.getNick();
} else {
nick = UserInfoHelper.getUserDisplayName(account);
}
if (TextUtils.isEmpty(nick)) {
nick = "";
}
return nick;
}
/**
* 踩TA当该人再房间中的时候进入他所在的房间
*
* @return
*/
private static ViewItem createFindMeItem() {
ViewItem viewItem = new ViewItem(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_01), R.drawable.icon_dialog_find_ta, null);
viewItem.isFindTa = true;
return viewItem;
}
/**
* 私聊
*/
public static ViewItem createPrivateChatItem(final Context context, String account, boolean isInRoom) {
return new ViewItem(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_02), R.mipmap.ic_private_chat, () -> {
if (isInRoom) {
RoomMsgTabFragment.Companion.newInstance(account).show(context);
} else {
NimP2PMessageActivity.start(context, account);
}
});
}
/**
* 关注or取消
*/
public static ViewItem createAttentItem() {
ViewItem viewItem = new ViewItem(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_04), R.drawable.icon_dialog_attent, null);
viewItem.isAttent = true;
return viewItem;
}
/**
* @Ta
*/
public static ViewItem createAtItem() {
ViewItem viewItem = new ViewItem("@Ta", R.drawable.icon_dialog_ait, null);
viewItem.isAt = true;
return viewItem;
}
/**
* 踢出房间: 先强制下麦,再踢出房间 todo do
*/
public static ViewItem createKickOutRoomItem(Context context, UserInfo userInfo, final String roomId,
final String account, String nick) {
return new ViewItem(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_05), R.drawable.icon_dialog_kickout_room, new ViewItem.OnClickListener() {
@Override
public void onClick() {
if (VipHelper.notKick(userInfo)) {
ToastUtils.show(ResUtil.getString(R.string.vipPower,userInfo.getUserVipInfoVO().getVipLevel()));
return;
}
String tips = (AvRoomDataManager.get().isGamePlaying(Long.parseLong(account)) ? ResUtil.getString(R.string.erban_avroom_buttonitemfactory_07) : "") + ResUtil.getString(R.string.erban_avroom_buttonitemfactory_08);
if (VipHelper.notKick(userInfo)) {
if (AvRoomDataManager.get().isRoomOwner()) {
tips = ResUtil.getString(R.string.erban_avroom_buttonitemfactory_09) + VipHelper.getVipName(userInfo) + ResUtil.getString(R.string.erban_avroom_buttonitemfactory_010);
} else {
SingleToastUtil.showToast(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_011) + VipHelper.getVipName(userInfo) + ResUtil.getString(R.string.erban_avroom_buttonitemfactory_012));
return;
}
}
new DialogManager(context).showOkCancelDialog(tips,
true, new DialogManager.AbsOkDialogListener() {
@SuppressLint("CheckResult")
@Override
public void onOk() {
final Map<String, Object> reason = new HashMap<>();
reason.put("reason", "kick");
if (AvRoomDataManager.get().isOnMic(JavaUtil.str2long(account))) {
int micPosition = AvRoomDataManager.get().getMicPosition(JavaUtil.str2long(account));
reason.put("micPosition", micPosition);
reason.put("account", account);
IMNetEaseManager.get().downMicroPhoneBySdk(micPosition, null);
}
reason.put(StatLogKey.USER_ID_KICK, String.valueOf(AuthModel.get().getCurrentUid()));
int role = SuperAdminUtil.isSuperAdmin() ? 1 : 2;
reason.put(KickOutExtBean.KEY_ROLE, role);
//如果是超管踢人
//超管踢普通人的话, 先将自己升级为管理员,再踢人
if (SAdminOptUtil.kickOutNormalUser(account, nick, reason)) {
LogUtil.print("super admin kick out normal user");
SuperAdminModel superAdminModel = new SuperAdminModel();
superAdminModel.roomOperate(SuperAdminModel.KICK_OUT_ROOM, JavaUtil.str2long(account)).subscribe();
return;
}
//踢房间管理员
//通过超管发消息管理员,管理员退出房间的方式踢人
if (SAdminOptUtil.kickOutRoomAdmin(account, nick)) {
LogUtil.print("super admin kick out room admin");
return;
}
IMNetEaseManager.get().kickMemberFromRoomBySdk(JavaUtil.str2long(roomId),
JavaUtil.str2long(account), reason)
.subscribe((s, throwable) -> {
if (throwable != null) {
if (throwable.getMessage().contains("404")) {
SingleToastUtil.showToast(BasicConfig.INSTANCE.getAppContext(), ResUtil.getString(R.string.erban_avroom_buttonitemfactory_013));
} else {
SingleToastUtil.showToast(BasicConfig.INSTANCE.getAppContext(), throwable.getMessage());
}
} else {
IMNetEaseManager.get().kickMemberFromRoomBySdk(Long.valueOf(roomId),
Long.valueOf(account), nick)
.subscribe(chatRoomMessage ->
KickModel.get().sendMessage(chatRoomMessage));
Logger.e("kick out mic and room: " + s);
IMNetEaseManager.get().noticeKickOutChatMember(null, account);
}
});
}
});
}
});
}
//设置管理员
public static ViewItem createMarkManagerListItem(final Context context,final String roomId, final String account, final String nick, final boolean mark) {
String title = BasicConfig.INSTANCE.getAppContext().getString(mark ? R.string.set_manager : R.string.remove_manager);
int icon = mark ? R.drawable.icon_dialog_set_manager_ture : R.drawable.icon_dialog_set_manager_false;
return new ViewItem(title, icon, () -> {
//xxx 设置管理员
if (AvRoomDataManager.get().isSuperAdmin()) {
AvRoomModel.get().markManager(Long.parseLong(account), mark).subscribe();
} else {
IMNetEaseManager.get().markManagerListBySdk(roomId, account, mark, new CallBack<ChatRoomMember>() {
@Override
public void onSuccess(ChatRoomMember data) {
if (mark) {
OtherExtKt.doToast(ResourcesKtxKt.getString(R.string._ver_23_setManagerAddSuccess, nick));
} else {
OtherExtKt.doToast(ResourcesKtxKt.getString(R.string._ver_23_setManagerRemoveSuccess, nick));
}
AvRoomModel.get().manageOpt(Long.parseLong(account),mark).subscribe();
}
@Override
public void onFail(int code, String error) {
if (code == ServiceResult.CODE_ROOM_MANAGER_LIMIT) {
DialogCommonUtil.showManagerLimit(context);
} else {
OtherExtKt.doToast(error);
}
}
});
}
});
}
//加入黑名单 todo do
public static ViewItem createMarkBlackListItem(final Context context,
UserInfo userInfo,
final String roomId,
final String account,
String nick) {
return new ViewItem(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_015), R.drawable.icon_dialog_mark_black_list, () -> {
if (VipHelper.notKick(userInfo)) {
ToastUtils.show(ResUtil.getString(R.string.vipPower,userInfo.getUserVipInfoVO().getVipLevel()));
return;
}
int roomBlackListSize = 200;
InitInfo initInfo = InitialModel.get().getCacheInitInfo();
if (initInfo != null && initInfo.getRoomBlackListSize() != 0) {
roomBlackListSize = initInfo.getRoomBlackListSize();
}
if (AvRoomDataManager.get().mRoomLimitMemberList.size() >= roomBlackListSize) {
new DialogManager(context).showOkDialog(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_017) + roomBlackListSize + ResUtil.getString(R.string.erban_avroom_buttonitemfactory_018));
return;
}
String tips = ResUtil.getString(R.string.erban_avroom_buttonitemfactory_019) + nick + ResUtil.getString(R.string.erban_avroom_buttonitemfactory_020) +
(AvRoomDataManager.get().mCurrentRoomInfo != null && AvRoomDataManager.get().isGamePlaying(Long.parseLong(account)) ? ResUtil.getString(R.string.erban_avroom_buttonitemfactory_021) : "");
if (VipHelper.notKick(userInfo)) {
if (AvRoomDataManager.get().isRoomOwner()) {
tips = ResUtil.getString(R.string.erban_avroom_buttonitemfactory_022) + VipHelper.getVipName(userInfo) + ResUtil.getString(R.string.erban_avroom_buttonitemfactory_023);
} else {
SingleToastUtil.showToast(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_024) + VipHelper.getVipName(userInfo) + ResUtil.getString(R.string.erban_avroom_buttonitemfactory_025));
return;
}
}
new DialogManager(context).showOkCancelDialog(tips, true,
() -> {
Single<String> single;
if (SuperAdminUtil.isSuperAdmin() || AvRoomDataManager.get().isSuperAdmin()) {
//超管拉黑
single = AvRoomModel.get().markBlack(JavaUtil.str2long(account));
SuperAdminModel superAdminModel = new SuperAdminModel();
superAdminModel.roomOperate(SuperAdminModel.ADD_BLACK_LIST, JavaUtil.str2long(account)).subscribe();
} else {
single = IMNetEaseManager.get().markBlackListBySdk(roomId, account, true);
}
//拉黑后,下麦和管理操作保持一致
single
//发公屏
.flatMap((Function<String, SingleSource<ChatRoomMessage>>) s -> {
if (SuperAdminUtil.isSuperAdmin()) {
ChatRoomMessage chatRoomMessage = SaAttachmentFactory
.createBlackOrKickOutChatRoomMsg(account, nick, 1);
return IMNetEaseManager.get().sendChatRoomMessage(chatRoomMessage, false);
}
return IMNetEaseManager.get().markBlackListBySdk(roomId, account, true, nick);
})
.doOnSuccess(chatRoomMessage ->
KickModel.get().onSendRoomMessageSuccess(chatRoomMessage))
.flatMap(s -> {
int micPosition = AvRoomDataManager.get().getMicPosition(account);
return IMNetEaseManager.get().downMicroPhoneBySdk(micPosition);
})
.subscribe();
});
});
}
//发送礼物
/**
* @param isInRoom true 在房间内弹起
* @param isHideMagicTab true 隐藏魔法
* @return ViewItem
*/
public static ViewItem createSendGiftItem(final Context context, long otherUid, boolean isInRoom, boolean isHideMagicTab,
final GiftDialog.OnGiftDialogBtnClickListener giftDialogBtnClickListener) {
return new ViewItem(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_026), R.drawable.icon_send_gift_ture, () -> {
GiftDialog dialog = new GiftDialog(context, otherUid, isInRoom, false, isHideMagicTab);
if (giftDialogBtnClickListener != null) {
dialog.setGiftDialogBtnClickListener(giftDialogBtnClickListener);
}
dialog.show();
});
}
/**
* @param isInRoom true 在房间内弹起
* @return ViewItem
*/
public static ViewItem createSendGiftItem(final Context context, long otherUid, boolean isInRoom,
final GiftDialog.OnGiftDialogBtnClickListener giftDialogBtnClickListener) {
return createSendGiftItem(context, otherUid, isInRoom, true, giftDialogBtnClickListener);
}
/**
* 拉黑 todo do
*/
public static ButtonItem createAddToBlackListItem(DialogManager dialogManager, String account) {
return new ButtonItem(ResUtil.getString(R.string.me_block), () -> {
dialogManager.showOkCancelDialog(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_031), true,
new DialogManager.AbsOkDialogListener() {
@Override
public void onOk() {
NimFriendModel.get().addToBlackList(account)
.subscribe((aBoolean, throwable) -> {
SingleToastUtil.showToastShort((throwable == null) ? ResUtil.getString(R.string.erban_avroom_buttonitemfactory_034) : ResUtil.getString(R.string.erban_avroom_buttonitemfactory_035));
});
}
});
});
}
/**
* 举报
*/
public static ButtonItem createReportItem(Context context, long uid, String reportType) {
return new ButtonItem(ResUtil.getString(R.string.erban_avroom_buttonitemfactory_036), () -> UIHelper.showReportPage(context, uid, reportType));
}
// public static List<ViewItem> createMiniWorldGroupButtonItems(
// Context context,
// long uid,
// boolean isInRoom,
// GiftDialog.OnGiftDialogBtnClickListener listener) {
// if (uid <= 0) return null;
// String currentUid = String.valueOf(AuthModel.get().getCurrentUid());
// String account = String.valueOf(uid);
// //account和chatRoomMember 不会同时为空,如果同时为空,则是前面传参出错
// boolean isMySelf = Objects.equals(currentUid, account);
// if (isMySelf) {
// return null;
// }
// List<ViewItem> buttonItems = new ArrayList<>();
// //不在房间内,也不需要魔法
// buttonItems.add(createSendGiftItem(context, uid, true, true, listener));
// // 私聊
// buttonItems.add(createPrivateChatItem(context, account, isInRoom));
// //装扮和关注目前是都有的操作
// // buttonItems.add(createSendDecorationItem(context, uid));
// buttonItems.add(createAttentItem());
// buttonItems.add(createFindMeItem());
// return buttonItems;
// }
}

View File

@@ -0,0 +1,44 @@
package com.chwl.app.avroom;
import androidx.recyclerview.widget.DiffUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import java.util.List;
import java.util.Objects;
/**
* @author Administrator
*/
public class ChatMemberDiffUtilCallback extends DiffUtil.Callback {
private List<ChatRoomMember> mOldMemberList, mNewMemberList;
public ChatMemberDiffUtilCallback(List<ChatRoomMember> oldMemberList, List<ChatRoomMember> newMemberList) {
mOldMemberList = oldMemberList;
mNewMemberList = newMemberList;
}
@Override
public int getOldListSize() {
return mOldMemberList == null ? 0 : mOldMemberList.size();
}
@Override
public int getNewListSize() {
return mNewMemberList == null ? 0 : mNewMemberList.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return Objects.equals(mOldMemberList.get(oldItemPosition).getAccount(),
mNewMemberList.get(newItemPosition).getAccount());
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
ChatRoomMember oldItem = mOldMemberList.get(oldItemPosition);
ChatRoomMember newItem = mNewMemberList.get(newItemPosition);
return Objects.equals(oldItem.getAccount(), newItem.getAccount())
&& Objects.equals(oldItem.getNick(), newItem.getNick());
}
}

View File

@@ -0,0 +1,81 @@
package com.chwl.app.avroom;
import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import java.lang.ref.WeakReference;
/**
* 该类用于监听软键盘是否显示并获取其高度
* <p>
* Success is the sum of small efforts, repeated day in and day out.
* 成功就是日复一日那一点点小小努力的积累。
* AndroidGroup158423375
* AuthorJohnny
* AuthorQQ956595454
* AuthorWXQiang_it
* AuthorPhonenothing
* Created by 2016/9/22.
*/
public class SoftKeyBoardListener {
private View rootView;/*activity的根视图*/
private int rootViewVisibleHeight;/*纪录根视图的显示高度*/
private WeakReference<OnSoftKeyBoardChangeListener> mReference;
// private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener;
public SoftKeyBoardListener(Activity activity) {
/*获取activity的根视图*/
rootView = activity.getWindow().getDecorView();
/*监听视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变*/
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener = mReference.get();
if (onSoftKeyBoardChangeListener == null) return;
/*获取当前根视图在屏幕上显示的大小*/
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int visibleHeight = r.height();
if (rootViewVisibleHeight == 0) {
rootViewVisibleHeight = visibleHeight;
return;
}
/*根视图显示高度没有变化,可以看作软键盘显示/隐藏状态没有改变*/
if (rootViewVisibleHeight == visibleHeight) {
return;
}
/*根视图显示高度变小超过200可以看作软键盘显示了*/
if (rootViewVisibleHeight - visibleHeight > 200) {
onSoftKeyBoardChangeListener.keyBoardShow(rootViewVisibleHeight - visibleHeight);
rootViewVisibleHeight = visibleHeight;
return;
}
/*根视图显示高度变大超过200可以看作软键盘隐藏了*/
if (visibleHeight - rootViewVisibleHeight > 200) {
onSoftKeyBoardChangeListener.keyBoardHide(visibleHeight - rootViewVisibleHeight);
rootViewVisibleHeight = visibleHeight;
}
}
});
}
private void setOnSoftKeyBoardChangeListener(OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
mReference = new WeakReference<>(onSoftKeyBoardChangeListener);
// this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener;
}
public interface OnSoftKeyBoardChangeListener {
void keyBoardShow(int height);
void keyBoardHide(int height);
}
public static void setListener(Activity activity, OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
if (activity == null) return;
SoftKeyBoardListener softKeyBoardListener = new SoftKeyBoardListener(activity);
softKeyBoardListener.setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener);
}
}

View File

@@ -0,0 +1,12 @@
package com.chwl.app.avroom;
/**
* 用户卡片的管理
* Created by lvzebiao on 2018/11/12.
*/
public class UserCardButtonManager {
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,446 @@
package com.chwl.app.avroom.activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.TextView;
import androidx.gridlayout.widget.GridLayout;
import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nim.uikit.support.glide.GlideApp;
import com.chwl.app.R;
import com.chwl.app.avroom.dialog.PKSelectPeopleDialog;
import com.chwl.app.avroom.dialog.PKTimePickerDialog;
import com.chwl.app.avroom.presenter.CreatePKPresenter;
import com.chwl.app.avroom.view.ICreatePKView;
import com.chwl.app.base.BaseMvpActivity;
import com.chwl.app.base.TitleBar;
import com.chwl.app.common.widget.dialog.DialogManager;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.room.pk.bean.PKMemberInfo;
import com.chwl.core.room.pk.bean.PKTeamInfo;
import com.chwl.core.room.pk.model.PkModel;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.library.base.factory.CreatePresenter;
import com.chwl.library.utils.ResUtil;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.SingleObserver;
import io.reactivex.disposables.Disposable;
/**
* @author jack
* @Description
* @Date 2018/12/28
*/
@CreatePresenter(CreatePKPresenter.class)
public class CreatePKActivity extends BaseMvpActivity<ICreatePKView, CreatePKPresenter>
implements ICreatePKView {
private GridLayout glRedTeam;
private GridLayout glBlueTeam;
private ImageView ivRedAvatar1;
private TextView tvRedName1;
private ImageView ivRedAvatar2;
private TextView tvRedName2;
private ImageView ivRedAvatar3;
private TextView tvRedName3;
private ImageView ivRedAvatar4;
private TextView tvRedName4;
private ImageView ivBlueAvatar1;
private TextView tvBlueName1;
private ImageView ivBlueAvatar2;
private TextView tvBlueName2;
private ImageView ivBlueAvatar3;
private TextView tvBlueName3;
private ImageView ivBlueAvatar4;
private TextView tvBlueName4;
private RadioButton rbVoteTypeGiftValue;
private RadioButton rbVoteTypeGiftMember;
private LinearLayout llSelectTime;
private TextView tvPkTime;
private TextView okBtn;
private LinearLayout llInPk;
private TextView tvRecreateBtn;
private TextView tvClosePkMode;
private final List<ImageView> redTeamAvatar = new ArrayList<>();
private final List<TextView> redTeamName = new ArrayList<>();
private final List<ImageView> blueTeamAvatar = new ArrayList<>();
private final List<TextView> blueTeamName = new ArrayList<>();
private List<UserInfo> redTeamMember = new ArrayList<>();
private List<UserInfo> blueTeamMember = new ArrayList<>();
public static void start(Context context) {
Intent intent = new Intent(context, CreatePKActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_pk);
glRedTeam = findViewById(R.id.gl_red_team);
glBlueTeam = findViewById(R.id.gl_blue_team);
ivRedAvatar1 = findViewById(R.id.iv_red_avatar_1);
tvRedName1 = findViewById(R.id.tv_red_name_1);
ivRedAvatar2 = findViewById(R.id.iv_red_avatar_2);
tvRedName2 = findViewById(R.id.tv_red_name_2);
ivRedAvatar3 = findViewById(R.id.iv_red_avatar_3);
tvRedName3 = findViewById(R.id.tv_red_name_3);
ivRedAvatar4 = findViewById(R.id.iv_red_avatar_4);
tvRedName4 = findViewById(R.id.tv_red_name_4);
ivBlueAvatar1 = findViewById(R.id.iv_blue_avatar_1);
tvBlueName1 = findViewById(R.id.tv_blue_name_1);
ivBlueAvatar2 = findViewById(R.id.iv_blue_avatar_2);
tvBlueName2 = findViewById(R.id.tv_blue_name_2);
ivBlueAvatar3 = findViewById(R.id.iv_blue_avatar_3);
tvBlueName3 = findViewById(R.id.tv_blue_name_3);
ivBlueAvatar4 = findViewById(R.id.iv_blue_avatar_4);
tvBlueName4 = findViewById(R.id.tv_blue_name_4);
rbVoteTypeGiftValue = findViewById(R.id.rb_vote_type_gift_value);
rbVoteTypeGiftMember = findViewById(R.id.rb_vote_type_gift_member);
llSelectTime = findViewById(R.id.ll_select_time);
tvPkTime = findViewById(R.id.tv_pk_time);
okBtn = findViewById(R.id.ok_btn);
llInPk = findViewById(R.id.ll_in_pk);
tvRecreateBtn = findViewById(R.id.tv_recreate_btn);
tvClosePkMode = findViewById(R.id.tv_close_pk_mode);
redTeamAvatar.add(ivRedAvatar1);
redTeamAvatar.add(ivRedAvatar2);
redTeamAvatar.add(ivRedAvatar3);
redTeamAvatar.add(ivRedAvatar4);
redTeamName.add(tvRedName1);
redTeamName.add(tvRedName2);
redTeamName.add(tvRedName3);
redTeamName.add(tvRedName4);
blueTeamAvatar.add(ivBlueAvatar1);
blueTeamAvatar.add(ivBlueAvatar2);
blueTeamAvatar.add(ivBlueAvatar3);
blueTeamAvatar.add(ivBlueAvatar4);
blueTeamName.add(tvBlueName1);
blueTeamName.add(tvBlueName2);
blueTeamName.add(tvBlueName3);
blueTeamName.add(tvBlueName4);
rbVoteTypeGiftValue.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
getMvpPresenter().setPkVoteMode(PkModel.PK_VOTE_MODE_GIFT_VALUE);
}
}
});
rbVoteTypeGiftMember.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
getMvpPresenter().setPkVoteMode(PkModel.PK_VOTE_MODE_PEOPLE_COUNT);
}
}
});
llSelectTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showSelectTimeDialog();
}
});
okBtn.setOnClickListener(v -> {
//提交pk
if (AvRoomDataManager.get().isQueuingMicro()) {
getDialogManager().showOkCancelDialog(ResUtil.getString(R.string.avroom_activity_createpkactivity_01),
true,
new DialogManager.OkCancelDialogListener() {
@Override
public void onCancel() {
}
@Override
public void onOk() {
createPk();
}
});
return;
}
createPk();
});
glRedTeam.setOnClickListener(v -> {
PKSelectPeopleDialog dialog = new PKSelectPeopleDialog(this, PKTeamInfo.TEAM_RED, getPKMemberList());
dialog.setOnSelectPeopleListener(new PKSelectPeopleDialog.OnSelectPeopleListener() {
@Override
public void onSelectPeople(List<PKSelectPeopleDialog.MicEntity> micEntityList) {
List<UserInfo> userInfoList = new ArrayList<>();
for (PKSelectPeopleDialog.MicEntity micEntity : micEntityList) {
if (micEntity.isSelect) {
UserInfo userInfo = new UserInfo();
userInfo.setUid(Long.parseLong(micEntity.uid));
userInfo.setAvatar(micEntity.avatar);
userInfo.setNick(micEntity.nick);
userInfo.setGender(micEntity.gender);
userInfo.setGroupType(PKTeamInfo.TEAM_RED);
userInfoList.add(userInfo);
}
}
redTeamMember = userInfoList;
for (int i = 0; i < redTeamAvatar.size(); i++) {
if (i < userInfoList.size()) {
GlideApp.with(CreatePKActivity.this)
.load(userInfoList.get(i).getAvatar())
.placeholder(R.drawable.default_avatar)
.dontAnimate()
.into(redTeamAvatar.get(i));
redTeamName.get(i).setText(userInfoList.get(i).getNick());
} else {
redTeamAvatar.get(i).setImageResource(R.mipmap.ic_red_seat);
redTeamName.get(i).setText(String.valueOf(i+1));
}
}
}
});
dialog.show();
});
glBlueTeam.setOnClickListener(v -> {
PKSelectPeopleDialog dialog = new PKSelectPeopleDialog(this, PKTeamInfo.TEAM_BLUE, getPKMemberList());
dialog.setOnSelectPeopleListener(new PKSelectPeopleDialog.OnSelectPeopleListener() {
@Override
public void onSelectPeople(List<PKSelectPeopleDialog.MicEntity> micEntityList) {
List<UserInfo> userInfoList = new ArrayList<>();
for (PKSelectPeopleDialog.MicEntity micEntity : micEntityList) {
if (micEntity.isSelect) {
UserInfo userInfo = new UserInfo();
userInfo.setUid(Long.parseLong(micEntity.uid));
userInfo.setAvatar(micEntity.avatar);
userInfo.setNick(micEntity.nick);
userInfo.setGender(micEntity.gender);
userInfo.setGroupType(PKTeamInfo.TEAM_BLUE);
userInfoList.add(userInfo);
}
}
blueTeamMember = userInfoList;
for (int i = 0; i < blueTeamAvatar.size(); i++) {
if (i < userInfoList.size()) {
GlideApp.with(CreatePKActivity.this)
.load(userInfoList.get(i).getAvatar())
.placeholder(R.drawable.default_avatar)
.dontAnimate()
.into(blueTeamAvatar.get(i));
blueTeamName.get(i).setText(userInfoList.get(i).getNick());
} else {
blueTeamAvatar.get(i).setImageResource(R.mipmap.ic_blue_seat);
blueTeamName.get(i).setText(String.valueOf(i+1));
}
}
}
});
dialog.show();
});
if (AvRoomDataManager.get().isOpenPKMode()) {
llInPk.setVisibility(View.VISIBLE);
tvRecreateBtn.setOnClickListener(v -> {
getDialogManager().showOkCancelDialog(
ResUtil.getString(R.string.avroom_activity_createpkactivity_02),
true,
new DialogManager.OkCancelDialogListener() {
@Override
public void onCancel() {
}
@Override
public void onOk() {
getDialogManager().showProgressDialog(CreatePKActivity.this);
getMvpPresenter().createPKAgain(
redTeamMember,
blueTeamMember
)
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(Disposable d) {
mCompositeDisposable.add(d);
}
@Override
public void onSuccess(String s) {
toast(s);
getDialogManager().dismissDialog();
finish();
}
@Override
public void onError(Throwable e) {
getDialogManager().dismissDialog();
toast(e.getMessage());
}
});
}
});
});
tvClosePkMode.setOnClickListener(v -> {
//关闭pk 模式
getDialogManager().showOkCancelDialog(ResUtil.getString(R.string.avroom_activity_createpkactivity_04),
true,
new DialogManager.OkCancelDialogListener() {
@Override
public void onCancel() {
}
@Override
public void onOk() {
getDialogManager().showProgressDialog(CreatePKActivity.this);
getMvpPresenter().closePkMode()
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(Disposable d) {
mCompositeDisposable.add(d);
}
@Override
public void onSuccess(String s) {
toast(s);
getDialogManager().dismissDialog();
finish();
}
@Override
public void onError(Throwable e) {
toast(e.getMessage());
getDialogManager().dismissDialog();
}
});
}
});
});
} else {
llInPk.setVisibility(View.GONE);
}
}
private void createPk() {
getDialogManager().showProgressDialog(CreatePKActivity.this);
getMvpPresenter().createPK(
redTeamMember,
blueTeamMember
)
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(Disposable d) {
mCompositeDisposable.add(d);
}
@Override
public void onSuccess(String s) {
toast(s);
getDialogManager().dismissDialog();
finish();
}
@Override
public void onError(Throwable e) {
getDialogManager().dismissDialog();
toast(e.getMessage());
}
});
}
private List<PKMemberInfo> getPKMemberList() {
List<PKMemberInfo> pkMemberInfoList = new ArrayList<>();
for (UserInfo userInfo : redTeamMember) {
PKMemberInfo pkMemberInfo = new PKMemberInfo();
pkMemberInfo.setTeamId(PKTeamInfo.TEAM_RED);
pkMemberInfo.setUserInfo(userInfo);
pkMemberInfoList.add(pkMemberInfo);
}
for (UserInfo userInfo : blueTeamMember) {
PKMemberInfo pkMemberInfo = new PKMemberInfo();
pkMemberInfo.setTeamId(PKTeamInfo.TEAM_BLUE);
pkMemberInfo.setUserInfo(userInfo);
pkMemberInfoList.add(pkMemberInfo);
}
return pkMemberInfoList;
}
@Override
protected void onResume() {
super.onResume();
if (getMvpPresenter().getPkMode() == -1) {
getMvpPresenter().setPkMode(PkModel.PK_MODE_TEAM);
}
if (getMvpPresenter().getPkVoteMode() == -1) {
getMvpPresenter().setPkVoteMode(PkModel.PK_VOTE_MODE_GIFT_VALUE);
rbVoteTypeGiftValue.setChecked(true);
}
if (getMvpPresenter().getPkDuration() == -1) {
getMvpPresenter().setPkDuration(30);
tvPkTime.setText(30 + ResUtil.getString(R.string.avroom_activity_createpkactivity_06));
}
}
private void showSelectTimeDialog() {
PKTimePickerDialog pkTimePickerDialog = new PKTimePickerDialog(this);
pkTimePickerDialog.setOnSelectTime(new PKTimePickerDialog.OnSelectTime() {
@Override
public void selectTime(long timeSecond) {
if (timeSecond < 30 || timeSecond > 1800) {
toast(ResUtil.getString(R.string.avroom_activity_createpkactivity_07));
return;
}
tvPkTime.setText((timeSecond / 60) + ResUtil.getString(R.string.avroom_activity_createpkactivity_08) + (timeSecond % 60) + ResUtil.getString(R.string.avroom_activity_createpkactivity_09));
getMvpPresenter().setPkDuration(timeSecond);
}
});
pkTimePickerDialog.show();
}
@Override
public void initTitleBar() {
initWhiteTitleBar(getString(R.string.create_PK));
mTitleBar.addAction(new TitleBar.TextAction(getString(R.string.PK_record),
getResources().getColor(R.color.text_normal_c6c6e9)) {
@Override
public void performAction(View view) {
RecordForPKActivity.start(CreatePKActivity.this);
}
});
}
@Override
protected boolean needSteepStateBar() {
return true;
}
@Override
protected void setStatusBar() {
StatusBarUtil.transparencyBar(this);
StatusBarUtil.StatusBarLightMode(this);
}
}

View File

@@ -0,0 +1,151 @@
package com.chwl.app.avroom.activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.netease.nim.uikit.StatusBarUtil;
import com.trello.rxlifecycle3.android.ActivityEvent;
import com.chwl.app.R;
import com.chwl.app.avroom.adapter.RecordForPKAdapter;
import com.chwl.app.avroom.presenter.RecordForPKPresenter;
import com.chwl.app.avroom.view.IRecordForPKView;
import com.chwl.app.base.BaseMvpActivity;
import com.chwl.library.common.util.Utils;
import com.chwl.app.ui.widget.recyclerview.decoration.ColorDecoration;
import com.chwl.core.room.pk.bean.PKRecordInfo;
import com.chwl.library.base.factory.CreatePresenter;
import com.chwl.library.utils.ListUtils;
import com.chwl.library.utils.ResUtil;
import java.util.List;
import io.reactivex.SingleObserver;
import io.reactivex.disposables.Disposable;
/**
* @author jack
* @Description
* @Date 2018/12/29
*/
@CreatePresenter(RecordForPKPresenter.class)
public class RecordForPKActivity extends BaseMvpActivity<IRecordForPKView, RecordForPKPresenter>
implements IRecordForPKView {
private SwipeRefreshLayout srlRefreshContainer;
private RecyclerView rvList;
private RecordForPKAdapter adapter;
public static void start(Context context) {
Intent intent = new Intent(context, RecordForPKActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_record_for_pk);
srlRefreshContainer = (SwipeRefreshLayout) findViewById(R.id.srl_refresh_container);
rvList = (RecyclerView) findViewById(R.id.rv_list);
srlRefreshContainer.setOnRefreshListener(this::refreshData);
rvList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
rvList.addItemDecoration(new ColorDecoration(Color.TRANSPARENT, 0, Utils.dip2px(this, 10), true));
adapter = new RecordForPKAdapter(this, null);
adapter.setEnableLoadMore(true);
adapter.setOnLoadMoreListener(this::loadMoreData, rvList);
rvList.setAdapter(adapter);
srlRefreshContainer.setRefreshing(true);
refreshData();
}
@Override
public void onReloadDate() {
super.onReloadDate();
refreshData();
}
@Override
public void initTitleBar() {
super.initWhiteTitleBar(getString(R.string.PK_record));
}
public void refreshData() {
getMvpPresenter().refreshData()
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new SingleObserver<List<PKRecordInfo>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(List<PKRecordInfo> pkRecordInfos) {
srlRefreshContainer.setRefreshing(false);
if (ListUtils.isListEmpty(pkRecordInfos)) {
showNoData(R.drawable.icon_common_failure, ResUtil.getString(R.string.avroom_activity_recordforpkactivity_01));
return;
}
adapter.setNewData(pkRecordInfos);
}
@Override
public void onError(Throwable e) {
srlRefreshContainer.setRefreshing(false);
showNetworkErr();
toast(e.getMessage());
}
});
}
private void loadMoreData() {
getMvpPresenter().loadMoreData()
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new SingleObserver<List<PKRecordInfo>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(List<PKRecordInfo> pkRecordInfos) {
adapter.loadMoreComplete();
if (!ListUtils.isListEmpty(pkRecordInfos)) {
adapter.addData(pkRecordInfos);
} else {
adapter.loadMoreEnd(true);
}
}
@Override
public void onError(Throwable e) {
adapter.loadMoreComplete();
toast(e.getMessage());
}
});
}
@Override
protected boolean needSteepStateBar() {
return true;
}
@Override
protected void setStatusBar() {
StatusBarUtil.transparencyBar(this);
StatusBarUtil.StatusBarLightMode(this);
}
}

View File

@@ -0,0 +1,77 @@
package com.chwl.app.avroom.activity
import android.annotation.SuppressLint
import androidx.core.view.WindowCompat
import com.chwl.app.R
import com.chwl.app.avroom.adapter.RoomBgAdapter
import com.chwl.app.base.BaseViewBindingActivity
import com.chwl.app.databinding.RoomBgSettingActivityBinding
import com.chwl.core.auth.AuthModel
import com.chwl.core.manager.AvRoomDataManager
import com.chwl.core.room.model.RoomSettingModel
import com.chwl.library.utils.ResUtil
import com.netease.nim.uikit.StatusBarUtil
class RoomBgSettingActivity : BaseViewBindingActivity<RoomBgSettingActivityBinding>() {
private val adapter = RoomBgAdapter()
private val model = RoomSettingModel()
override fun init() {
initWhiteTitleBar(ResUtil.getString(R.string.room_theme))
mTitleBar.setTitleColor(resources.getColor(R.color.white))
mTitleBar.setLeftImageResource(R.drawable.arrow_left_white)
binding.recyclerView.adapter = adapter
adapter.selectItem(AvRoomDataManager.get().mCurrentRoomInfo?.backPic)
adapter.setOnItemClickListener { _, view, position ->
adapter.getItem(position)?.let {
if (adapter.getSelectItem() != it) {
showUpdateRoomBackgroundTips(it)
}
}
}
val list = listOf(
"https://image.molistar.xyz/BG_0.webp",
"https://image.molistar.xyz/BG_1.webp",
"https://image.molistar.xyz/BG_2.webp",
"https://image.molistar.xyz/BG_3.webp",
"https://image.molistar.xyz/BG_4.webp",
"https://image.molistar.xyz/BG_5.webp"
)
adapter.setNewData(list)
}
private fun showUpdateRoomBackgroundTips(url: String) {
dialogManager.showOkCancelDialog(
getString(R.string.room_theme_changed_tips),
getString(R.string.btn_text_confirm_select_team_member)
) {
updateRoomBackground(url)
}
}
@SuppressLint("CheckResult")
private fun updateRoomBackground(url: String) {
dialogManager.showProgressDialog(this)
model.updateRoomBackground(AuthModel.get().currentUid, url)
.compose(bindToLifecycle()).subscribe({
dialogManager.dismissDialog()
toast(R.string.avroom_dialog_roomimposedialog_04)
adapter.selectItem(url)
}, {
dialogManager.dismissDialog()
toast(it.message)
})
}
override fun needSteepStateBar(): Boolean {
return true
}
override fun setStatusBar() {
StatusBarUtil.transparencyBar(this)
StatusBarUtil.StatusBarLightMode(this)
WindowCompat.getInsetsController(window, window.decorView).let {
it.isAppearanceLightStatusBars = false
}
}
}

View File

@@ -0,0 +1,201 @@
package com.chwl.app.avroom.activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.app.avroom.adapter.RoomNormalListAdapter;
import com.chwl.app.avroom.presenter.RoomBlackPresenter;
import com.chwl.app.avroom.view.IRoomBlackView;
import com.chwl.app.base.BaseMvpActivity;
import com.chwl.app.common.widget.dialog.DialogManager;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.im.room.IIMRoomCoreClient;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.core.room.model.AvRoomModel;
import com.chwl.core.super_admin.model.SuperAdminModel;
import com.chwl.core.super_admin.util.SuperAdminUtil;
import com.chwl.core.utils.net.DontWarnObserver;
import com.chwl.library.base.factory.CreatePresenter;
import com.chwl.library.coremanager.CoreEvent;
import com.chwl.library.utils.JavaUtil;
import com.chwl.library.utils.ListUtils;
import com.chwl.library.utils.ResUtil;
import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import com.trello.rxlifecycle3.android.ActivityEvent;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
/**
* 黑名单
*
* @author chenran
* @date 2017/10/11
*/
@CreatePresenter(RoomBlackPresenter.class)
public class RoomBlackListActivity extends BaseMvpActivity<IRoomBlackView, RoomBlackPresenter>
implements RoomNormalListAdapter.OnRoomNormalListOperationClickListener, IRoomBlackView {
private RecyclerView recyclerView;
private RoomNormalListAdapter normalListAdapter;
private SuperAdminModel mSuperAdminModel;
public static void start(Context context) {
Intent intent = new Intent(context, RoomBlackListActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_room_black_list);
initWhiteTitleBar(ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_01));
initView();
mSuperAdminModel = new SuperAdminModel();
loadData();
}
private void loadData() {
queryBlackListSuccess(AvRoomDataManager.get().mRoomLimitMemberList);
}
private void initView() {
recyclerView = findViewById(R.id.recycler_view);
normalListAdapter = new RoomNormalListAdapter(this);
normalListAdapter.setListOperationClickListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(normalListAdapter);
}
@Override
public void onRemoveOperationClick(final ChatRoomMember chatRoomMember) {
getDialogManager().showOkCancelDialog(
ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_02) + chatRoomMember.getNick() + ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_03),
true,
new DialogManager.OkCancelDialogListener() {
@Override
public void onCancel() {
}
@Override
public void onOk() {
//如果登录用户是超管
if (SuperAdminUtil.isSuperAdmin()) {
//使用接口移除
AvRoomModel.get().removeBlack(JavaUtil.str2long(chatRoomMember.getAccount()))
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new DontWarnObserver<String>() {
@Override
public void accept(String s, String error) {
super.accept(s, error);
if (error == null) {
toast(ResUtil.getString(R.string.doSuccess));
loadData();
} else {
toast(error);
}
}
});
mSuperAdminModel.roomOperate(SuperAdminModel.REMOVE_BLACK_LIST, JavaUtil.str2long(chatRoomMember.getAccount())).subscribe();
return;
}
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo != null) {
getMvpPresenter().markBlackList(roomInfo.getRoomId(),
chatRoomMember.getAccount(), false);
}
}
});
}
@Override
public View.OnClickListener getLoadListener() {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
showLoading();
loadData();
}
};
}
@CoreEvent(coreClientClass = IIMRoomCoreClient.class)
public void onMemberBeRemoveManager(String account) {
long uid = AuthModel.get().getCurrentUid();
if (uid == Long.valueOf(account)) {
finish();
toast(R.string.remove_room_manager);
}
}
@Override
public void queryBlackListSuccess(List<ChatRoomMember> chatRoomMemberList) {
hideStatus();
if (chatRoomMemberList != null && chatRoomMemberList.size() > 0) {
normalListAdapter.setNormalList(chatRoomMemberList);
normalListAdapter.notifyDataSetChanged();
mTitleBar.setTitle(ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_05) + chatRoomMemberList.size() + ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_06));
} else {
showNoData(ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_07));
mTitleBar.setTitle(ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_08));
}
}
@Override
public void queryBlackListFail() {
showNetworkErr();
}
@Override
public void makeBlackListSuccess(ChatRoomMember chatRoomMember, boolean mark) {
if (chatRoomMember == null) return;
List<ChatRoomMember> normalList = normalListAdapter.getNormalList();
if (!ListUtils.isListEmpty(normalList)) {
hideStatus();
ListIterator<ChatRoomMember> iterator = normalList.listIterator();
while (iterator.hasNext()) {
if (Objects.equals(iterator.next().getAccount(), chatRoomMember.getAccount())) {
iterator.remove();
}
}
mTitleBar.setTitle(ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_09) + normalList.size() + ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_010));
if (normalList.size() == 0) {
showNoData(ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_011));
}
} else {
showNoData(ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_012));
mTitleBar.setTitle(ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_013));
}
normalListAdapter.notifyDataSetChanged();
toast(ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_014));
}
@Override
public void makeBlackListFail(int code, String error, boolean mark) {
// toast(ResUtil.getString(R.string.avroom_activity_roomblacklistactivity_015));
}
@Override
protected boolean needSteepStateBar() {
return true;
}
@Override
protected void setStatusBar() {
StatusBarUtil.transparencyBar(this);
StatusBarUtil.StatusBarLightMode(this);
}
}

View File

@@ -0,0 +1,237 @@
package com.chwl.app.avroom.activity;
import static com.chwl.core.noble.NobleResourceType.KEY_ENTER_HIDE;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.app.avroom.adapter.RoomInviteAdapter;
import com.chwl.app.avroom.presenter.RoomInvitePresenter;
import com.chwl.app.avroom.view.IRoomInviteView;
import com.chwl.app.base.BaseMvpActivity;
import com.chwl.core.Constants;
import com.chwl.core.noble.NobleResourceType;
import com.chwl.core.room.bean.RoomOnlineUserBean;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.library.base.factory.CreatePresenter;
import com.chwl.library.utils.ListUtils;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.SingleToastUtil;
import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nim.uikit.common.util.sys.NetworkUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
;
;
/**
* <p> 抱人上麦 </p>
*
* @author jiahui
* @date 2017/12/21
*/
@CreatePresenter(RoomInvitePresenter.class)
public class RoomInviteActivity extends BaseMvpActivity<IRoomInviteView, RoomInvitePresenter>
implements IRoomInviteView, RoomInviteAdapter.OnItemClickListener, RoomInviteAdapter.OnRoomOnlineNumberChangeListener {
private RoomInviteAdapter mRoomInviteAdapter;
private SmartRefreshLayout mRefreshLayout;
private RecyclerView mRecyclerView;
private int mPage = Constants.PAGE_START;
private int micPosition;
private boolean onlyManager;
public static void openActivity(FragmentActivity fragmentActivity, int micPosition,boolean onlyManager) {
Intent intent = new Intent(fragmentActivity, RoomInviteActivity.class);
intent.putExtra(Constants.KEY_POSITION, micPosition);
intent.putExtra("only_manager", onlyManager);
fragmentActivity.startActivityForResult(intent, 200);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_room_invite);
mRecyclerView = findViewById(R.id.recycler_view);
mRefreshLayout = findViewById(R.id.refresh_layout);
onlyManager = getIntent().getBooleanExtra("only_manager", false);
initWhiteTitleBar(onlyManager ? ResUtil.getString(R.string.avroom_activity_roominviteactivity_01) : getString(R.string.title_online));
Intent intent = getIntent();
if (intent != null)
micPosition = intent.getIntExtra(Constants.KEY_POSITION, Integer.MIN_VALUE);
mRoomInviteAdapter = new RoomInviteAdapter(this, this);
mRecyclerView.setAdapter(mRoomInviteAdapter);
mRoomInviteAdapter.setOnRoomOnlineNumberChangeListener(this);
mRefreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() {
@Override
public void onLoadMore(RefreshLayout refreshLayout) {
if (!NetworkUtil.isNetAvailable(RoomInviteActivity.this)) {
mRefreshLayout.finishLoadMore();
return;
}
List<ChatRoomMember> data = mRoomInviteAdapter.getChatRoomMemberList();
if (ListUtils.isListEmpty(data)) {
mRefreshLayout.finishLoadMore();
return;
}
loadData(data.get(data.size() - 1).getEnterTime());
}
@Override
public void onRefresh(RefreshLayout refreshLayout) {
if (!NetworkUtil.isNetAvailable(RoomInviteActivity.this)) {
mRefreshLayout.finishRefresh();
return;
}
firstLoad();
}
});
showLoading();
firstLoad();
}
public void firstLoad() {
mPage = Constants.PAGE_START;
loadData(0);
}
private void loadData(long time) {
getMvpPresenter().requestChatMemberByPage(mPage, time, onlyManager);
}
@Override
public void onRequestRoomOnlineListSuccess(List<RoomOnlineUserBean> memberList) {
}
@Override
public void onRequestChatMemberByPageFail(String errorStr, int page) {
mPage = page;
if (mPage == Constants.PAGE_START) {
mRefreshLayout.finishRefresh(0);
showNoData(getString(R.string.data_error));
} else {
mRefreshLayout.finishLoadMore(0);
}
}
@Override
public void onMemberInRefresh() {
}
@Override
public void onRequestMemberByPageSuccess(List<ChatRoomMember> memberList, int page) {
Iterator<ChatRoomMember> iterator = memberList.iterator();
while (iterator.hasNext()) {
ChatRoomMember next = iterator.next();
if (next.getExtension() != null) {
Map<String, Object> map = (Map<String, Object>) next.getExtension().get(next.getAccount());
if (map != null && map.containsKey(KEY_ENTER_HIDE)) {
if (Boolean.TRUE.equals(map.get(KEY_ENTER_HIDE))){
iterator.remove();
}
}
}
}
mPage = page;
if (mPage == Constants.PAGE_START) {
List<ChatRoomMember> chatRoomMemberList = mRoomInviteAdapter.getChatRoomMemberList();
if (!ListUtils.isListEmpty(chatRoomMemberList)) chatRoomMemberList.clear();
mRefreshLayout.finishRefresh(0);
if (ListUtils.isListEmpty(memberList)) {
showNoData(ResUtil.getString(R.string.avroom_activity_roominviteactivity_02));
} else {
hideStatus();
mRoomInviteAdapter.addChatRoomMemberList(memberList);
}
} else {
mRefreshLayout.finishLoadMore(0);
if (!ListUtils.isListEmpty(memberList)) {
mRoomInviteAdapter.addChatRoomMemberList(memberList);
}
}
}
@Override
public void onClick(ChatRoomMember chatRoomMember) {
if (chatRoomMember == null) return;
boolean isRobot = true;
Map<String, Object> extension = chatRoomMember.getExtension();
if (extension != null) {
Map<String, Object> map = (Map<String, Object>) extension.get(chatRoomMember.getAccount());
if (map != null) {
String defUser = map.get(UserInfo.DEF_USER) == null ? null : map.get(UserInfo.DEF_USER) + "";
String resource = map.get(NobleResourceType.KEY_LEVEL) == null ? null : map.get(NobleResourceType.KEY_LEVEL) + "";
if ((!TextUtils.isEmpty(defUser) && Integer.parseInt(defUser) != UserInfo.USER_TYPE_ROBOT)
|| (!TextUtils.isEmpty(resource) && Integer.parseInt(resource) > 0)) {
isRobot = false;
}
}
}
if (isRobot) {
// Toast.makeText(context, context.getResources().getString(R.string.unable_to_up_mic_by_level), Toast.LENGTH_SHORT).show();
SingleToastUtil.showToastShort(R.string.unable_to_up_mic_by_level);
return;
}
Intent intent = new Intent();
intent.putExtra("account", chatRoomMember.getAccount());
String nick = chatRoomMember.getNick();
intent.putExtra("nick", nick == null ? "" : nick);
intent.putExtra(Constants.KEY_POSITION, micPosition);
setResult(100, intent);
finish();
}
@Override
public void onReloadDate() {
super.onReloadDate();
showLoading();
firstLoad();
}
@Override
public void onRoomOnlineNumberChange(int number) {
if (number == 0) {
showNoData();
}
}
@Override
protected void onDestroy() {
if (mRoomInviteAdapter != null)
mRoomInviteAdapter.onRelease();
super.onDestroy();
}
@Override
protected boolean needSteepStateBar() {
return true;
}
@Override
protected void setStatusBar() {
StatusBarUtil.transparencyBar(this);
StatusBarUtil.StatusBarLightMode(this);
}
}

View File

@@ -0,0 +1,160 @@
package com.chwl.app.avroom.activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.app.avroom.adapter.RoomNormalListAdapter;
import com.chwl.app.avroom.presenter.RoomManagerPresenter;
import com.chwl.app.avroom.view.IRoomManagerView;
import com.chwl.app.base.BaseMvpActivity;
import com.chwl.app.common.util.DialogCommonUtil;
import com.chwl.app.common.widget.dialog.DialogManager;
import com.chwl.core.bean.response.ServiceResult;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.library.base.factory.CreatePresenter;
import com.chwl.library.utils.ListUtils;
import com.chwl.library.utils.ResUtil;
import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
/**
* 房间管理员列表
*
* @author chenran
* @date 2017/10/11
*/
@CreatePresenter(RoomManagerPresenter.class)
public class RoomManagerListActivity extends BaseMvpActivity<IRoomManagerView, RoomManagerPresenter>
implements RoomNormalListAdapter.OnRoomNormalListOperationClickListener, IRoomManagerView {
private RecyclerView recyclerView;
private RoomNormalListAdapter normalListAdapter;
public static void start(Context context) {
Intent intent = new Intent(context, RoomManagerListActivity.class);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_room_manager_list);
initWhiteTitleBar(ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_01));
initView();
showLoading();
loadData();
}
private void loadData() {
getMvpPresenter().queryManagerList(500);
}
private void initView() {
recyclerView = findViewById(R.id.recycler_view);
normalListAdapter = new RoomNormalListAdapter(this);
normalListAdapter.setListOperationClickListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(normalListAdapter);
}
@Override
public void onRemoveOperationClick(final ChatRoomMember chatRoomMember) {
getDialogManager().showOkCancelDialog(ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_02) + chatRoomMember.getNick() + ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_03),
true, new DialogManager.OkCancelDialogListener() {
@Override
public void onCancel() {
}
@Override
public void onOk() {
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo != null) {
getMvpPresenter().removeManagerList(roomInfo.getRoomId(), chatRoomMember.getAccount());
}
}
});
}
@Override
public View.OnClickListener getLoadListener() {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
showLoading();
loadData();
}
};
}
@Override
public void queryManagerListSuccess(List<ChatRoomMember> chatRoomMemberList) {
hideStatus();
if (chatRoomMemberList != null && chatRoomMemberList.size() > 0) {
normalListAdapter.setNormalList(chatRoomMemberList);
normalListAdapter.notifyDataSetChanged();
mTitleBar.setTitle(ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_04) + chatRoomMemberList.size() + ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_05));
} else {
showNoData(ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_06));
mTitleBar.setTitle(ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_07));
}
}
@Override
public void queryManagerListFail() {
showNetworkErr();
}
@Override
public void markManagerListSuccess(ChatRoomMember chatRoomMember) {
if (chatRoomMember == null) return;
List<ChatRoomMember> list = normalListAdapter.getNormalList();
if (!ListUtils.isListEmpty(list)) {
hideStatus();
ListIterator<ChatRoomMember> iterator = list.listIterator();
while (iterator.hasNext()) {
if (Objects.equals(iterator.next().getAccount(), chatRoomMember.getAccount())) {
iterator.remove();
}
}
mTitleBar.setTitle(ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_08) + list.size() + ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_09));
if (list.size() == 0) {
showNoData(ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_010));
}
} else {
showNoData(ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_011));
mTitleBar.setTitle(ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_012));
}
normalListAdapter.notifyDataSetChanged();
toast(ResUtil.getString(R.string.avroom_activity_roommanagerlistactivity_013));
}
@Override
public void markManagerListFail(int code, String error) {
if (code == ServiceResult.CODE_ROOM_MANAGER_LIMIT) {
DialogCommonUtil.showManagerLimit(context);
}
}
@Override
protected boolean needSteepStateBar() {
return true;
}
@Override
protected void setStatusBar() {
StatusBarUtil.transparencyBar(this);
StatusBarUtil.StatusBarLightMode(this);
}
}

View File

@@ -0,0 +1,69 @@
package com.chwl.app.avroom.activity;
import android.content.Context;
import android.content.Intent;
import com.netease.nim.uikit.StatusBarUtil;
import com.chwl.app.R;
import com.chwl.app.avroom.fragment.OnlineUserFragment;
import com.chwl.app.base.BaseBindingActivity;
import com.chwl.app.databinding.ActivityRoomOnlineUserBinding;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.library.annatation.ActLayoutRes;
import com.chwl.library.utils.ResUtil;
@ActLayoutRes(R.layout.activity_room_online_user)
public class RoomOnlineUserActivity extends BaseBindingActivity<ActivityRoomOnlineUserBinding> {
private String[] bgPicture = new String[]{""};
public static void start(Context context) {
Intent intent = new Intent(context, RoomOnlineUserActivity.class);
context.startActivity(intent);
}
@Override
protected void init() {
initWhiteTitleBar(ResUtil.getString(R.string.avroom_activity_roomonlineuseractivity_01));
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
AVRoomActivity.setBackBg(this, roomInfo, mBinding.svgaImageViewBg, bgPicture);
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container,
new OnlineUserFragment(),
OnlineUserFragment.class.getSimpleName())
.commitAllowingStateLoss();
}
@Override
public void initWhiteTitleBar(String title) {
mTitleBar = findViewById(R.id.title_bar);
if (mTitleBar != null) {
mTitleBar.setTitle(title);
mTitleBar.setImmersive(false);
mTitleBar.setTitleColor(getResources().getColor(R.color.white));
mTitleBar.setLeftImageResource(R.drawable.arrow_left_white);
mTitleBar.setBackgroundResource(R.color.transparent);
mTitleBar.setLeftClickListener(v -> onLeftClickListener()
);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mBinding.svgaImageViewBg.isAnimating()) {
mBinding.svgaImageViewBg.clearAnimation();
}
}
@Override
protected boolean needSteepStateBar() {
return true;
}
@Override
protected void setStatusBar() {
StatusBarUtil.transparencyBar(this);
}
}

View File

@@ -0,0 +1,87 @@
package com.chwl.app.avroom.activity;
import android.content.Context;
import android.content.Intent;
import android.view.View;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import androidx.viewpager2.widget.ViewPager2;
import com.chwl.app.R;
import com.chwl.app.avroom.adapter.CommonVPAdapter;
import com.chwl.app.avroom.fragment.RoomCharmListFragment;
import com.chwl.app.avroom.fragment.RoomContributeListFragment;
import com.chwl.app.base.BaseBindingActivity;
import com.chwl.app.databinding.ActivityRoomRankListBinding;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.library.annatation.ActLayoutRes;
import java.util.ArrayList;
import java.util.List;
/**
* 房间排行榜,(魅力榜+贡献榜)
*/
@ActLayoutRes(R.layout.activity_room_rank_list)
public class RoomRankListActivity extends BaseBindingActivity<ActivityRoomRankListBinding> {
public static void start(Context context) {
Intent intent = new Intent(context, RoomRankListActivity.class);
context.startActivity(intent);
}
private String [] bgPicture = new String[]{""};
@Override
protected void init() {
mBinding.setClick(this);
List<Fragment> list = new ArrayList<>();
list.add(RoomCharmListFragment.newInstance());
list.add(new RoomContributeListFragment());
mBinding.viewPager.setAdapter(new CommonVPAdapter(getSupportFragmentManager(),getLifecycle(),list));
mBinding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback(){
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
mBinding.setPosition(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
AVRoomActivity.setBackBg(this, AvRoomDataManager.get().mCurrentRoomInfo, mBinding.svgaImageViewBg, bgPicture);
}
@Override
public void onClick(View v) {
super.onClick(v);
switch (v.getId()) {
case R.id.iv_back:
finish();
break;
case R.id.tv_charm_tab:
mBinding.viewPager.setCurrentItem(0);
break;
case R.id.tv_contribute_tab:
mBinding.viewPager.setCurrentItem(1);
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mBinding.svgaImageViewBg.isAnimating()) {
mBinding.svgaImageViewBg.clearAnimation();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,191 @@
package com.chwl.app.avroom.activity;
import android.app.Activity;
import android.content.Intent;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import com.chwl.app.R;
import com.chwl.app.base.BaseBindingActivity;
import com.chwl.app.common.widget.dialog.DialogManager;
import com.chwl.app.databinding.ActivityRoomTitleEditBinding;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.core.room.model.RoomSettingModel;
import com.chwl.library.annatation.ActLayoutRes;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.SingleToastUtil;
import com.netease.nim.uikit.StatusBarUtil;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.BiConsumer;
@ActLayoutRes(R.layout.activity_room_title_edit)
public class RoomTitleEditActivity extends BaseBindingActivity<ActivityRoomTitleEditBinding> implements BiConsumer<RoomInfo, Throwable> {
public static final int ROOM_TITLE_EDIT_REQUEST_CODE = 9999;
public static final String ROOM_TITLE_EDIT_REQUEST_RESULT = "room_info";
private CompositeDisposable mDisposable;
private DialogManager mDialogManager;
public static void startForResult(Activity context, String title, String desc) {
Intent intent = new Intent(context, RoomTitleEditActivity.class);
intent.putExtra("title", title);
intent.putExtra("desc", desc);
context.startActivityForResult(intent, ROOM_TITLE_EDIT_REQUEST_CODE);
}
private TextWatcher mTitleWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
mBinding.tvTitleCount.setText(s.length() + "/15");
}
};
private TextWatcher mDescWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
mBinding.tvDescCount.setText(s.length() + "/300");
}
};
@Override
protected void init() {
initWhiteTitleBar(getResources().getString(R.string.title_room_title_edit));
mBinding.setClick(this);
mBinding.etTitle.addTextChangedListener(mTitleWatcher);
mBinding.etDesc.addTextChangedListener(mDescWatcher);
Intent intent = getIntent();
String title = intent.getStringExtra("title");
String desc = intent.getStringExtra("desc");
mBinding.etTitle.setText(title);
mBinding.etDesc.setText(desc);
mDisposable = new CompositeDisposable();
mDialogManager = new DialogManager(this);
mBinding.tvConfirm.setOnClickListener(this);
}
private void commit(String desc, String introduction) {
if (TextUtils.isEmpty(desc)) {
// Toast.makeText(this, ResUtil.getString(R.string.avroom_activity_roomtitleeditactivity_01), Toast.LENGTH_SHORT).show();
SingleToastUtil.showToastShort(ResUtil.getString(R.string.avroom_activity_roomtitleeditactivity_02));
return;
}
if (TextUtils.isEmpty(introduction)) {
introduction = "";
}
// if (TextUtils.isEmpty(introduction)) {
// Toast.makeText(this, ResUtil.getString(R.string.avroom_activity_roomtitleeditactivity_03), Toast.LENGTH_SHORT).show();
// return;
// }
RoomInfo info = AvRoomDataManager.get().mCurrentRoomInfo;
if (info == null) return;
RoomSettingModel roomSettingModel = new RoomSettingModel();
long currentUid = AuthModel.get().getCurrentUid();
String ticket = AuthModel.get().getTicket();
if (AvRoomDataManager.get().isRoomOwner()) {
mDialogManager.showProgressDialog(this);
Disposable disposable = roomSettingModel.updateRoomInfo(info.title,null,desc, introduction, info.roomPwd, info.getRoomTag(), info.tagId, currentUid,
ticket, info.isHasAnimationEffect(), info.getAudioQuality(), info.getLimitType(),info.isPureMode(), info.getType(),
info.getMgId())
.subscribe(this);
mDisposable.add(disposable);
} else if (AvRoomDataManager.get().isRoomAdmin()) {
mDialogManager.showProgressDialog(this);
Disposable disposable = roomSettingModel.updateByAdmin(info.getUid(), info.title,null, desc, introduction, info.roomPwd, info.getRoomTag(), info.tagId, currentUid,
ticket, info.isHasAnimationEffect(), info.getAudioQuality(),info.isPureMode())
.subscribe((s, throwable) -> {
if (throwable != null) {
SingleToastUtil.showToastShort(ResUtil.getString(R.string.avroom_activity_roomtitleeditactivity_05));
} else {
finish();
}
});
mDisposable.add(disposable);
}
}
@Override
public void onClick(View v) {
super.onClick(v);
switch (v.getId()) {
case R.id.tv_confirm:
commit(mBinding.etTitle.getText().toString().trim(),
mBinding.etDesc.getText().toString().trim());
break;
}
}
@Override
public void accept(RoomInfo roomInfo, Throwable throwable) throws Exception {
mDialogManager.dismissDialog();
if (throwable != null) {
// Toast.makeText(this, ResUtil.getString(R.string.avroom_activity_roomtitleeditactivity_04), Toast.LENGTH_SHORT).show();
SingleToastUtil.showToastShort(ResUtil.getString(R.string.avroom_activity_roomtitleeditactivity_05));
} else {
// Intent intent = new Intent();
// Bundle bundle = new Bundle();
// bundle.putSerializable(ROOM_TITLE_EDIT_REQUEST_RESULT, roomInfo);
// intent.putExtras(bundle);
// setResult(RESULT_OK, intent);
finish();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mDialogManager.dismissDialog();
mDisposable.clear();
}
@Override
protected boolean needSteepStateBar() {
return true;
}
@Override
protected void setStatusBar() {
StatusBarUtil.transparencyBar(this);
StatusBarUtil.StatusBarLightMode(this);
}
}

View File

@@ -0,0 +1,396 @@
package com.chwl.app.avroom.activity
import android.content.Context
import android.content.Intent
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chwl.app.R
import com.chwl.app.base.BaseViewBindingActivity
import com.chwl.app.bindadapter.BaseBindingAdapter
import com.chwl.app.bindadapter.BaseBindingViewHolder
import com.chwl.app.databinding.ItemRoomModeBinding
import com.chwl.app.databinding.RoomTypeSwitchActivityBinding
import com.chwl.app.home.helper.OpenRoomHelper
import com.chwl.app.ui.utils.load
import com.chwl.app.ui.utils.loadFromUrl
import com.chwl.app.ui.webview.CommonWebViewActivity
import com.chwl.app.utils.NumberUtils
import com.chwl.core.UriProvider
import com.chwl.core.bean.response.ServiceResult
import com.chwl.core.gift.bean.RoomLevelInfo
import com.chwl.core.gift.bean.RoomMicDress
import com.chwl.core.manager.AvRoomDataManager
import com.chwl.core.room.bean.RoomInfo
import com.chwl.core.super_admin.util.SuperAdminUtil
import com.chwl.core.utils.net.RxHelper
import com.chwl.library.common.util.ClickUtils.click
import com.chwl.library.common.util.doToast
import com.chwl.library.common.util.isVerify
import com.chwl.library.common.util.setVis
import com.chwl.library.common.util.toColor
import com.chwl.library.net.rxnet.RxNet
import com.chwl.library.utils.ResUtil
import com.chwl.library.utils.SingleToastUtil
import com.example.lib_utils.ktx.getString
import io.reactivex.Single
import retrofit2.http.GET
import retrofit2.http.Query
//切换麦位页面
class RoomTypeSwitchActivity : BaseViewBindingActivity<RoomTypeSwitchActivityBinding>() {
companion object {
fun isCanSwitch(): Boolean {
if (SuperAdminUtil.isSuperAdmin()) {
return false
}
if (AvRoomDataManager.get().roomType != RoomInfo.ROOMTYPE_HOME_PARTY
&& AvRoomDataManager.get().roomType != RoomInfo.ROOMTYPE_PARTY
&& AvRoomDataManager.get().roomType != RoomInfo.ROOMTYPE_REVELRY
&& AvRoomDataManager.get().roomType != RoomInfo.ROOMTYPE_19_ROOM
&& AvRoomDataManager.get().roomType != RoomInfo.ROOMTYPE_20_ROOM
) {
return false
}
if (AvRoomDataManager.get().isDatingMode) {
return false
}
val roomInfo = AvRoomDataManager.get().mCurrentRoomInfo
if (roomInfo == null || roomInfo.isPermitRoom == 1) {
return false
}
return AvRoomDataManager.get().isManager
}
fun start(context: Context) {
context.startActivity(Intent(context, RoomTypeSwitchActivity::class.java))
}
}
private var mCurrentMicType: Int? = null
private var mCurrentMicSkins: Int? = null
private var mCurrentMicEffects: Int? = null
private var mCurrentLevel = 0
private val mMicTypeAdapter = RoomModeAdapter()
private val mMicSkinsAdapter = RoomModeAdapter()
private val mMicEffectsAdapter = RoomModeAdapter()
private var mTypeSet = true
private var micSkinsEffectsSet = true
override fun init() {
initView()
initListener()
initData()
}
private fun initView() {
initDarkTitleBar(R.string.Room_Mode.getString())
setListView(binding.rvListType, mMicTypeAdapter)
setListView(binding.rvListSkins, mMicSkinsAdapter)
setListView(binding.rvListEffects, mMicEffectsAdapter)
}
private fun initListener() {
binding.btnConfirm.click {
switchRoomMicType()
}
binding.btnMore.click {
CommonWebViewActivity.start(this, UriProvider.getRoomLevelRule())
}
}
private fun initData() {
val mCurrentRoomInfo = AvRoomDataManager.get().mCurrentRoomInfo
mCurrentMicType = mCurrentRoomInfo?.type
getBoomLevelInfo(AvRoomDataManager.get().roomUid).compose(bindToLifecycle())
.doOnSuccess {
if (it != null) {
val levelExp = it.nextLevelExp - it.currentLevelExp
val proExp = it.roomVal - it.currentLevelExp
val nexExp = levelExp - proExp
binding.proExp.max = levelExp.toInt()
binding.proExp.progress = proExp.toInt()
binding.avatar.load(mCurrentRoomInfo?.avatar)
binding.nick.text = mCurrentRoomInfo?.title
binding.levelIcon.load(it.getCurrentLevelIcon())
binding.roomValue.text = R.string.Room_Value_s.getString(it.roomVal.toLong().toString())
binding.roomAdmin.text = R.string.Room_Admin_s.getString(it.currentManagerNum,it.managerLimitNum)
binding.currentLevel.text = R.string.LV_s.getString(it.currentLevel)
binding.nextLevel.text = R.string.LV_s.getString(it.nextLevel)
binding.nextExp.text = R.string.Next_LV_EXP_s.getString(NumberUtils.format(nexExp))
if (it.nextLevel == 0) {
binding.nextExp.setVis(false,true)
binding.proExp.max = 1
binding.proExp.progress = 1
binding.nextLevel.text = R.string.LV_s.getString(it.currentLevel)
binding.currentLevel.text = R.string.LV_s.getString(it.currentLevel-1)
}
mCurrentMicSkins = it.usedMicSkinId
mCurrentMicEffects = it.usedMicEffectId
mCurrentLevel = it.currentLevel
val typeArr = mutableListOf(
RoomInfo.ROOMTYPE_HOME_PARTY,
RoomInfo.ROOMTYPE_PARTY,
RoomInfo.ROOMTYPE_REVELRY,
RoomInfo.ROOMTYPE_20_ROOM,
RoomInfo.ROOMTYPE_19_ROOM,
)
val typeNArr = arrayOf(
R.drawable.ic_room_mic_type_9_n,
R.drawable.ic_room_mic_type_10_n,
R.drawable.ic_room_mic_type_15_n,
R.drawable.ic_room_mic_type_20_n,
R.drawable.ic_room_mic_type_19_n,
)
val typeSArr = arrayOf(
R.drawable.ic_room_mic_type_9_s,
R.drawable.ic_room_mic_type_10_s,
R.drawable.ic_room_mic_type_15_s,
R.drawable.ic_room_mic_type_20_s,
R.drawable.ic_room_mic_type_19_s,
)
val nameArr = arrayOf(
R.string.Classic,
R.string.Party,
R.string.Carnival,
R.string.Celebration,
R.string.Unique,
)
if (!it.isHasUnique) {
typeArr.remove(RoomInfo.ROOMTYPE_19_ROOM)
typeArr.remove(RoomInfo.ROOMTYPE_20_ROOM)
}
val typeData = mutableListOf<RoomMicDress>()
typeArr.filterIndexed { index, micType ->
typeData.add(RoomMicDress().apply {
id = micType
dressType = RoomMicDress.RoomDressType.T_Type
isSelect = micType == mCurrentMicType
normalRes = typeNArr[index]
selectRes = typeSArr[index]
name = nameArr[index].getString()
})
}
mMicTypeAdapter.setNewData(typeData as List<RoomMicDress>?)
if (it.getMicSkins().isVerify()) {
val micSkins = it.getMicSkins()
micSkins.add(0, RoomMicDress().apply {
id = 0
normalRes = R.drawable.icon_room_up_micro
})
micSkins.forEach { it.isSelect = (it.id == mCurrentMicSkins) }
mMicSkinsAdapter.setNewData(micSkins)
}
if (it.getMicEffects().isVerify()) {
val micEffects = it.getMicEffects()
micEffects.add(0, RoomMicDress().apply {
id = 0
normalRes = R.drawable.shape_463a26_circle
})
micEffects.forEach { it.isSelect = (it.id == mCurrentMicEffects) }
mMicEffectsAdapter.setNewData(it.getMicEffects())
}
}
}.doOnError { it?.message?.doToast() }.subscribe()
}
private fun setListView(rvList: RecyclerView, adapter: RoomModeAdapter) {
adapter.setOnItemClickListener { adapter, view, position ->
val clickData = adapter?.data?.get(position)
if (clickData != null && clickData is RoomMicDress){
if (mCurrentLevel < clickData.reachLevel) {
R.string.roomLevelErrorTips.doToast()
return@setOnItemClickListener
}
}
adapter?.data?.forEachIndexed { index, feData ->
if (feData is RoomMicDress) {
feData.isSelect = index == position
}
}
adapter?.notifyDataSetChanged()
}
rvList.layoutManager = GridLayoutManager(context, 3, RecyclerView.VERTICAL, false)
rvList.adapter = adapter
}
private fun switchRoomMicType() {
var typeId = -1
var skinsId = -1
var effectId = -1
var isLevelError = false
mMicTypeAdapter.data?.forEach {
if (it.isSelect) {
typeId = it.id
}
}
mMicSkinsAdapter.data?.forEach {
if (it.isSelect) {
if (it.id > 0) {
skinsId = it.id
}
if (mCurrentLevel < it.reachLevel) {
isLevelError = true
}
}
}
mMicEffectsAdapter.data?.forEach {
if (it.isSelect) {
if (it.id > 0) {
effectId = it.id
}
if (mCurrentLevel < it.reachLevel) {
isLevelError = true
}
}
}
if (isLevelError) {
R.string.roomLevelErrorTips.doToast()
} else {
if ((typeId != -1 && typeId != mCurrentMicType) || (effectId != mCurrentMicEffects) || (skinsId != mCurrentMicSkins)) {
dialogManager.showOkCancelDialog(
ResUtil.getString(R.string.switch_room_type_tips),
ResUtil.getString(R.string.login_fragment_adduserinfofragment_04)
) {
binding.btnConfirm.post {
mTypeSet = false
dialogManager.showProgressDialog(context)
val newRoomInfo = RoomInfo()
newRoomInfo.uid = AvRoomDataManager.get().roomUid
newRoomInfo.type = typeId
newRoomInfo.usedMicSkinId = skinsId
newRoomInfo.usedMicEffectId = effectId
OpenRoomHelper.updateRoomInfoEx(newRoomInfo)
.compose(bindToLifecycle())
.doOnSuccess {
mTypeSet = true
dialogManager.dismissDialog()
// val mCurrentRoomInfo = AvRoomDataManager.get().mCurrentRoomInfo
// mCurrentRoomInfo?.type = typeId
// mCurrentRoomInfo?.usedMicSkinId = skinsId
// mCurrentRoomInfo?.usedMicEffectId = effectId
finish()
}
.doOnError {
SingleToastUtil.showToast(it.message)
dialogManager.dismissDialog()
}
.subscribe()
}
}
} else {
finish()
}
}
}
override fun needSteepStateBar(): Boolean {
return true
}
override fun transparencyBar() = true
class RoomModeAdapter : BaseBindingAdapter<ItemRoomModeBinding, RoomMicDress>() {
override fun convert(
helper: BaseBindingViewHolder<ItemRoomModeBinding>,
item: RoomMicDress
) {
helper?.binding?.let { binding ->
binding.bg.changeStrikeColor(if (item.isSelect) "#ff8c03".toColor() else "#1b1b1d".toColor())
binding.bg.changeSoildColor(if (item.isSelect) "#261800".toColor() else "#1b1b1d".toColor())
binding.tvName.alpha = (if (item.isSelect) 1f else 0.5f)
binding.tvName.setVis(item.dressType == RoomMicDress.RoomDressType.T_Type)
binding.tvName.text = item.name
binding.ivType.setVis(false)
binding.ivSkins.setVis(false)
binding.ivEffect.setVis(false)
if (item.id == 0) {
binding.ivSkins.setImageResource(item.normalRes)
binding.ivSkins.setVis(true)
} else {
if (item.dressType == RoomMicDress.RoomDressType.T_Type) {
binding.ivType.setImageResource(if (item.isSelect) item.selectRes else item.normalRes)
binding.ivType.setVis(true)
} else if (item.dressType == RoomMicDress.RoomDressType.T_Skin) {
binding.ivSkins.load(item.normalMicUrl)
binding.ivSkins.setVis(true)
} else if (item.dressType == RoomMicDress.RoomDressType.T_Effects) {
binding.ivEffect.setVis(true)
binding.ivEffect.loadFromUrl(item.normalMicUrl)
}
}
}
}
}
private fun getBoomLevelInfo(roomUid: Long): Single<RoomLevelInfo> {
return api.getBoomLevelInfo(roomUid)
.compose(RxHelper.handleBeanData())
.compose(RxHelper.handleSchedulers())
}
private val api: Api = RxNet.create(Api::class.java);
interface Api {
//房间 等级信息
@GET("/room/level/info")
fun getBoomLevelInfo(@Query("roomUid") roomUid: Long): Single<ServiceResult<RoomLevelInfo>>
}
}

View File

@@ -0,0 +1,36 @@
package com.chwl.app.avroom.adapter;
import com.chwl.library.list.ArrayListAdapter;
import com.chwl.library.list.ListItem;
import java.util.List;
/**
* Created by chenran on 2017/8/9.
*/
public class AuctionListAdapter extends ArrayListAdapter{
public static final int VIEW_TYPE_COUNT = 5;//列表有4种类型
public static final int VIEW_TYPE_WEEK_ITEM = 0;//周榜
public static final int VIEW_TYPE_TOTAL_ITEM = 1;//总榜
public static final int VIEW_TYPE_EMPTY = 2;//空内容
public static final int VIEW_TYPE_WEEK_HEADER = 3;//周榜header
public static final int VIEW_TYPE_TOTAL_HEADER = 4;//总榜header
private List<ListItem> items = getItems();
public void clear(int except) {
if (except >= 0 && except < items.size()) {
ListItem item = items.get(except);
items.clear();
items.add(item);
}
}
@Override
public int getViewTypeCount() {
return VIEW_TYPE_COUNT;
}
}

View File

@@ -0,0 +1,42 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.chwl.app.R;
import com.chwl.library.list.BaseGroupItem;
import com.chwl.library.list.ViewHolder;
/**
* Created by chenran on 2017/8/9.
*/
public class AuctionListEmptyItem extends BaseGroupItem{
public AuctionListEmptyItem(Context context, int viewType) {
super(context, viewType);
}
@Override
public ViewHolder createViewHolder(ViewGroup group) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.list_item_auction_empty, null);
AuctionListEmptyItem.AuctionListEmptyHolder holder = new AuctionListEmptyItem.AuctionListEmptyHolder(view);
return holder;
}
@Override
public void updateHolder(ViewHolder holder, int groupPos, int childPos) {
}
private static class AuctionListEmptyHolder extends ViewHolder {
private TextView textView;
public AuctionListEmptyHolder(View itemView) {
super(itemView);
}
}
}

View File

@@ -0,0 +1,48 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.chwl.app.R;
import com.chwl.library.list.BaseGroupItem;
import com.chwl.library.list.ViewHolder;
/**
* Created by chenran on 2017/8/9.
*/
public class AuctionListHeaderItem extends BaseGroupItem{
public AuctionListHeaderItem(Context context, int viewType) {
super(context, viewType);
}
@Override
public ViewHolder createViewHolder(ViewGroup group) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.list_item_auction_header, null);
AuctionListHeaderItem.AuctionListHeaderHolder holder = new AuctionListHeaderItem.AuctionListHeaderHolder(view);
return holder;
}
@Override
public void updateHolder(ViewHolder holder, int groupPos, int childPos) {
AuctionListHeaderItem.AuctionListHeaderHolder auctionListHolder = (AuctionListHeaderItem.AuctionListHeaderHolder) holder;
if (auctionListHolder != null) {
if (getViewType() == AuctionListAdapter.VIEW_TYPE_WEEK_HEADER) {
auctionListHolder.image.setImageResource(R.drawable.icon_week_auction_list);
} else {
auctionListHolder.image.setImageResource(R.drawable.icon_total_auction_list);
}
}
}
private static class AuctionListHeaderHolder extends ViewHolder {
private ImageView image;
public AuctionListHeaderHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.auction_list_header);
}
}
}

View File

@@ -0,0 +1,123 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.chwl.app.R;
import com.chwl.app.common.widget.CircleImageView;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.core.room.auction.bean.AuctionListUserInfo;
import com.chwl.library.list.BaseGroupItem;
import com.chwl.library.list.ViewHolder;
/**
* Created by chenran on 2017/8/9.
*/
public class AuctionListItem extends BaseGroupItem implements View.OnClickListener{
private AuctionListUserInfo auctionListUserInfo;
private OnAuctionListItemClick onAuctionListItemClick;
private int position;
public AuctionListItem(Context context, int viewType, AuctionListUserInfo auctionListUserInfo, int position) {
super(context, viewType);
this.auctionListUserInfo = auctionListUserInfo;
this.position = position;
}
public void setOnAuctionListItemClick(OnAuctionListItemClick onAuctionListItemClick) {
this.onAuctionListItemClick = onAuctionListItemClick;
}
@Override
public ViewHolder createViewHolder(ViewGroup group) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.list_item_auction_list, null);
AuctionListHolder holder = new AuctionListHolder(view);
return holder;
}
@Override
public void updateHolder(ViewHolder holder, int groupPos, int childPos) {
AuctionListHolder auctionListHolder = (AuctionListHolder) holder;
if (auctionListHolder != null) {
auctionListHolder.nick.setText(auctionListUserInfo.getNick());
auctionListHolder.coinText.setText(auctionListUserInfo.getPrice() + "");
auctionListHolder.avatar.setOnClickListener(this);
ImageLoadUtils.loadAvatar(getContext(), auctionListUserInfo.getAvatar(), auctionListHolder.avatar);
Drawable drawable;
if (auctionListUserInfo.getGender() == 1) {
Drawable drawMan = getContext().getResources().getDrawable(R.drawable.ic_gender_male);
drawable = drawMan;
} else {
Drawable drawFemale = getContext().getResources().getDrawable(R.drawable.ic_gender_female);
drawable = drawFemale;
}
auctionListHolder.nick.setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null);
if (getViewType() == AuctionListAdapter.VIEW_TYPE_WEEK_ITEM) {
if (position <= 2) {
auctionListHolder.numberText.setVisibility(View.GONE);
auctionListHolder.numberImage.setVisibility(View.VISIBLE);
if (position == 0) {
auctionListHolder.numberImage.setImageResource(R.drawable.icon_auction_week_list_first);
} else if (position == 1) {
auctionListHolder.numberImage.setImageResource(R.drawable.icon_auction_week_list_second);
} else {
auctionListHolder.numberImage.setImageResource(R.drawable.icon_auction_week_list_third);
}
} else {
auctionListHolder.numberText.setVisibility(View.VISIBLE);
auctionListHolder.numberImage.setVisibility(View.GONE);
auctionListHolder.numberText.setText("NO."+(position+1));
}
} else {
auctionListHolder.numberText.setVisibility(View.VISIBLE);
auctionListHolder.numberImage.setVisibility(View.GONE);
auctionListHolder.numberText.setText("NO."+(position + 1));
if (position <= 2) {
auctionListHolder.numberText.setTextColor(0xffeecb7f);
} else {
auctionListHolder.numberText.setTextColor(Color.WHITE);
}
}
}
}
@Override
public boolean isEnabled() {
return false;
}
@Override
public void onClick(View v) {
if(onAuctionListItemClick != null) {
onAuctionListItemClick.onAuctionListItemClick(auctionListUserInfo);
}
}
private static class AuctionListHolder extends ViewHolder {
private ImageView numberImage;
private TextView numberText;
private TextView nick;
private TextView coinText;
private CircleImageView avatar;
public AuctionListHolder(View itemView) {
super(itemView);
numberImage = (ImageView) itemView.findViewById(R.id.auction_number_image);
numberText = (TextView) itemView.findViewById(R.id.auction_number_text);
nick = (TextView) itemView.findViewById(R.id.nick);
avatar = (CircleImageView) itemView.findViewById(R.id.avatar);
coinText = (TextView) itemView.findViewById(R.id.coin_text);
}
}
public interface OnAuctionListItemClick {
void onAuctionListItemClick(AuctionListUserInfo auctionListUserInfo);
}
}

View File

@@ -0,0 +1,691 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.app.avroom.activity.AVRoomActivity;
import com.chwl.app.avroom.widget.BravoCoinView;
import com.chwl.app.common.widget.CircleImageView;
import com.chwl.app.ui.utils.ImageLoadKt;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.app.ui.webview.DialogWebViewActivity;
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import com.chwl.app.utils.AvatarHelper;
import com.chwl.app.utils.RegexUtil;
import com.chwl.app.utils.ResourceManager;
import com.chwl.core.UriProvider;
import com.chwl.core.bean.RoomMicInfo;
import com.chwl.core.bean.RoomQueueInfo;
import com.chwl.core.decoration.headwear.bean.HeadWearInfo;
import com.chwl.core.gift.bean.RoomMicDress;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.noble.NobleResourceType;
import com.chwl.core.noble.NobleUtil;
import com.chwl.core.room.bean.RoomInfo;
import com.chwl.core.room.giftvalue.bean.GiftValueData;
import com.chwl.core.room.giftvalue.helper.GiftValueFormat;
import com.chwl.core.room.pk.bean.PKTeamInfo;
import com.chwl.core.room.queue.bean.MicMemberInfo;
import com.chwl.core.user.UserModel;
import com.chwl.core.utils.ActivityUtil;
import com.chwl.core.utils.extension.StringExtensionKt;
import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.config.BasicConfig;
import com.chwl.library.widget.SVGAView;
import com.coorchice.library.SuperTextView;
import com.example.lib_utils.StringUtils2;
import com.netease.nim.uikit.common.util.string.StringUtil;
import com.opensource.svgaplayer.SVGAImageView;
/**
* @author xiaoyu
* @date 2017/12/18
*/
public abstract class BaseMicroViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
// 麦位类型用于左右滑动切换房间时判断是否需要更换麦位adapter
public static final String MICRO_TYPE_NULL = "null";
public static final String MICRO_TYPE_CP = "cp";
public static final String MICRO_TYPE_KTV = "ktv";
public static final String MICRO_TYPE_NORMAL = "normal";
public static final String MICRO_TYPE_DATING = "dating";
public static final String MICRO_TYPE_DATING_VIP = "dating_vip";
public static final String MICRO_TYPE_SINGLE = "single";
public static final String MICRO_TYPE_PARTY = "party";
public static final String MICRO_TYPE_REVELRY = "revelry";
public static final String MICRO_TYPE_REVELRY_19 = "revelry_19";
public static final String MICRO_TYPE_REVELRY_20 = "revelry_20";
protected static final int TYPE_KING = 2;
protected static final int TYPE_BOSS = 1;
protected static final int TYPE_NORMAL = 0;
protected static final int TYPE_INVALID = -2;
protected OnMicroItemClickListener onMicroItemClickListener = null;
protected Context context;
public BaseMicroViewAdapter(Context context) {
this.context = context;
setHasStableIds(true);
}
public void setOnMicroItemClickListener(OnMicroItemClickListener onMicroItemClickListener) {
this.onMicroItemClickListener = onMicroItemClickListener;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int position) {
RoomQueueInfo roomQueueInfo = AvRoomDataManager.get().getRoomQueueMemberInfoByMicPosition(position - 1);
if (roomQueueInfo == null) return;
NormalMicroViewHolder holder = (NormalMicroViewHolder) viewHolder;
holder.micPositionNameOffset = getMicPositionNameOffset();
holder.bind(roomQueueInfo, position - 1);
}
public abstract String microType();
protected int getMicPositionNameOffset() {
return 2;
}
@Override
public int getItemCount() {
return 9;
}
@Override
public int getItemViewType(int position) {
return (position == 0) ? TYPE_BOSS : TYPE_NORMAL;
}
@Override
public long getItemId(int position) {
return position;
}
public void clear(NormalMicroViewHolder holder) {
holder.clear();
}
public abstract void bindToRecyclerView(RecyclerView recyclerView);
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
onMicroItemClickListener = null;
super.onDetachedFromRecyclerView(recyclerView);
}
public void setBossViewGender(TextView tvNick, boolean isMale) {
tvNick.setCompoundDrawablePadding(4);
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
// if (AvRoomDataManager.get().isOpenPKMode()) { // pk模式不加性别背景
// tvNick.setCompoundDrawablePadding(4);
// tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
// } else {
// if (isMale) {
// tvNick.setCompoundDrawablePadding(4);
// tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_gender_male, 0);
// } else {
// tvNick.setCompoundDrawablePadding(4);
// tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_gender_female, 0);
// }
// }
}
public class NormalMicroViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
View rootView;
LinearLayout llNick;
View microLayout;
TextView tvNick;
ImageView ivUpImage;
ImageView ivLockImage;
ImageView ivMuteImage;
ImageView ivAvatar;
SVGAImageView ivHalo;
@Nullable
SVGAView ivHeadWear;
@Nullable
ImageView ivCharmLevelTag;
@Nullable
ImageView ivKickGuard;
BravoCoinView coinAnim;
RoomQueueInfo info;
int position = TYPE_INVALID;
int micPositionNameOffset = 2;
int micType = 0; //特殊麦位type , 麦位图片特殊处理
NormalMicroViewHolder(View itemView) {
super(itemView);
rootView = itemView.findViewById(R.id.rootView);
microLayout = itemView.findViewById(R.id.micro_layout);
ivHalo = itemView.findViewById(R.id.iv_halo);
ivUpImage = itemView.findViewById(R.id.up_image);
ivLockImage = itemView.findViewById(R.id.lock_image);
ivMuteImage = itemView.findViewById(R.id.mute_image);
ivAvatar = itemView.findViewById(R.id.avatar);
ivHeadWear = itemView.findViewById(R.id.iv_head_wear);
tvNick = itemView.findViewById(R.id.nick);
llNick = itemView.findViewById(R.id.ll_nick);
ivCharmLevelTag = itemView.findViewById(R.id.iv_charm_level_tag);
ivKickGuard = itemView.findViewById(R.id.iv_kick_guard);
coinAnim = itemView.findViewById(R.id.coinAnim);
ivUpImage.setOnClickListener(this);
ivLockImage.setOnClickListener(this);
ivAvatar.setOnClickListener(this);
if (ivHeadWear != null) {
ivHeadWear.bindCache(AVRoomActivity.getSvgaCache());
}
}
public void clear() {
info = null;
position = TYPE_INVALID;
ivHalo.setBackground(null);
ivHalo.clearAnimation();
ivHalo.clear();
clearHeadWear();
ivUpImage.setVisibility(View.VISIBLE);
ivLockImage.setVisibility(View.GONE);
ivMuteImage.setVisibility(View.GONE);
ivAvatar.setVisibility(View.GONE);
if (coinAnim != null) {
coinAnim.setVisibility(View.GONE);
}
tvNick.setVisibility(View.INVISIBLE);
if (ivCharmLevelTag != null) {
ivCharmLevelTag.setVisibility(View.GONE);
}
}
void bind(@NonNull RoomQueueInfo info, int position) {
this.info = info;
this.position = position;
RoomMicInfo roomMicInfo = info.mRoomMicInfo;
MicMemberInfo chatRoomMember = info.mChatRoomMember;
if (ivCharmLevelTag != null) {
ivCharmLevelTag.setVisibility(View.GONE);
}
if (micType == 0) {
// 麦位皮肤
// ivUpImage = up_image = icon_room_up_micro - 可上麦
// ivLockImage = lock_image = icon_room_lock_micro - 锁麦
RoomMicDress roomMicSkins = ResourceManager.INSTANCE.getRoomMicSkins();
if (roomMicSkins != null) {
ImageLoadKt.loadImage(ivUpImage,roomMicSkins.normalMicUrl);
ImageLoadKt.loadImage(ivLockImage,roomMicSkins.normalMicLockUrl);
}else {
ivUpImage.setImageResource(R.drawable.icon_room_up_micro);
ivLockImage.setImageResource(R.drawable.icon_room_lock_micro);
}
}
if (roomMicInfo == null) {
ivUpImage.setVisibility(View.VISIBLE);
ivLockImage.setVisibility(View.GONE);
ivMuteImage.setVisibility(View.GONE);
ivAvatar.setVisibility(View.GONE);
if (ivCharmLevelTag != null) {
ivCharmLevelTag.setVisibility(View.GONE);
}
if (ivKickGuard != null) {
ivKickGuard.setVisibility(View.GONE);
}
setDefalutText(position);
return;
}
//显示,先展示人,无视坑的锁
if (chatRoomMember != null) {
ivLockImage.setVisibility(View.GONE);
ivMuteImage.setVisibility(roomMicInfo.isMicMute() ? View.VISIBLE : View.GONE);
if (!TextUtils.isEmpty(chatRoomMember.getAccount()) && Long.valueOf(chatRoomMember.getAccount()) > 0) {
ivUpImage.setVisibility(View.GONE);
ivAvatar.setVisibility(View.VISIBLE);
setSelectText(position, chatRoomMember.getNick(), chatRoomMember.getGender());
ImageLoadUtils.loadAvatar(chatRoomMember.getAvatar(), ivAvatar);
// 加载贵族
updateNobleView(chatRoomMember);
//增加贵族昵称颜色
tvNick.setTextColor(StringExtensionKt.toColorInt(chatRoomMember.getMicNickColor(), "#FFFFFF"));
if (ivKickGuard != null) {
ivKickGuard.setVisibility(chatRoomMember.isPreventKick() ? View.VISIBLE : View.GONE);
}
if (coinAnim != null) {
coinAnim.setData(chatRoomMember.getAccount());
}
} else {
clearHeadWear();
ivUpImage.setVisibility(View.VISIBLE);
ivAvatar.setVisibility(View.GONE);
if (ivCharmLevelTag != null) {
ivCharmLevelTag.setVisibility(View.GONE);
}
if (ivKickGuard != null) {
ivKickGuard.setVisibility(View.GONE);
}
setDefalutText(position);
if (coinAnim != null) {
coinAnim.setData(null);
}
}
} else {
// 清除动画
ivHalo.setBackground(null);
ivHalo.clearAnimation();
ivHalo.clear();
// 清除头饰
clearHeadWear();
//锁坑
ivMuteImage.setVisibility(roomMicInfo.isMicMute() ? View.VISIBLE : View.GONE);
if (roomMicInfo.isMicLock()) {
ivUpImage.setVisibility(View.GONE);
ivLockImage.setVisibility(View.VISIBLE);
ivAvatar.setVisibility(View.GONE);
} else {
ivUpImage.setVisibility(View.VISIBLE);
ivAvatar.setVisibility(View.GONE);
ivLockImage.setVisibility(View.GONE);
}
if (ivCharmLevelTag != null) {
ivCharmLevelTag.setVisibility(View.GONE);
}
if (ivKickGuard != null) {
ivKickGuard.setVisibility(View.GONE);
}
setDefalutText(position);
if (coinAnim != null) {
coinAnim.setData(null);
}
}
}
private void clearHeadWear() {
if (ivHeadWear == null) return;
ivHeadWear.clearAnimation();
ivHeadWear.stopAnimation();
ivHeadWear.setImageDrawable(null);
ivHeadWear.setTag(R.id.mic_item_head_wear, null);
ivHeadWear.setVisibility(View.GONE);
}
protected void setDefalutText(int index) {
tvNick.setTextColor(Color.WHITE);
tvNick.setText(getMicPositionName(index));
}
protected String getMicPositionName(int index) {
return "NO." + (index + micPositionNameOffset);
}
protected void setSelectText(int index, String nick, int gender) {
tvNick.setText(StringExtensionKt.subAndReplaceDot(StringUtil.removeBlanks(nick), 7));
tvNick.setTextColor(context.getResources().getColor(R.color.white));
}
//优先使用MicMemberInfo里面的头饰
private void updateNobleView(MicMemberInfo chatRoomMember) {
if (ivHeadWear == null) return;
String headWear = chatRoomMember.getHeadWearUrl();
int headWearType = chatRoomMember.getHeadWearType();
if (TextUtils.isEmpty(headWear)) {
headWear = NobleUtil.getHeadResource(HeadWearInfo.EFFECT, chatRoomMember) != null ?
NobleUtil.getHeadResource(HeadWearInfo.EFFECT, chatRoomMember) :
NobleUtil.getHeadResource(HeadWearInfo.PIC, chatRoomMember);
String type = NobleUtil.getHeadResource(HeadWearInfo.TYPE, chatRoomMember);
headWearType = StringUtils2.INSTANCE.toInt(type);
}
String nobleHeadWear = (String) NobleUtil.getResource(NobleResourceType.KEY_HEAD_WEAR, chatRoomMember);
if (!TextUtils.isEmpty(headWear)) {
ivHeadWear.setVisibility(View.VISIBLE);
//只有头饰发生改变才更新,防止闪烁
if (!headWear.equals(ivHeadWear.getTag(R.id.mic_item_head_wear))) {
ivHeadWear.setTag(R.id.mic_item_head_wear, headWear);
AvatarHelper.loadAvatarFrame(ivHeadWear, headWear, headWearType);
}
} else if (!TextUtils.isEmpty(nobleHeadWear)) {
// 头饰
ivHeadWear.setVisibility(View.VISIBLE);
NobleUtil.loadResource(nobleHeadWear, ivHeadWear);
} else {
clearHeadWear();
}
}
@Override
public void onClick(View v) {
if (info == null || position == TYPE_INVALID ||
onMicroItemClickListener == null) return;
if (v.getId() == R.id.up_image || v.getId() == R.id.lock_image) {
onMicroItemClickListener.onUpMicBtnClick(position, info.mChatRoomMember);
} else if (v.getId() == R.id.lock_image) {
onMicroItemClickListener.onLockBtnClick(position);
} else if (v.getId() == R.id.avatar) {
onMicroItemClickListener.onAvatarBtnClick(position);
} else if (v.getId() == R.id.tv_room_desc || v.getId() == R.id.fr_title) {
onMicroItemClickListener.onRoomSettingsClick();
}
}
}
public class BasicMicroViewHolder extends NormalMicroViewHolder {
TextView tvPkMark;
public BasicMicroViewHolder(View itemView) {
super(itemView);
tvPkMark = (TextView) itemView.findViewById(R.id.tv_pk_mark);
}
@Override
public void clear() {
super.clear();
if (tvPkMark != null) {
tvPkMark.setVisibility(View.GONE);
}
}
@Override
void bind(RoomQueueInfo info, int position) {
super.bind(info, position);
if (tvPkMark == null) {
return;
}
MicMemberInfo micMemberInfo = info.mChatRoomMember;
if (micMemberInfo != null) {
if (micMemberInfo.getGroupType() == PKTeamInfo.TEAM_RED) {
tvPkMark.setVisibility(View.VISIBLE);
tvPkMark.setBackgroundResource(R.drawable.shape_pk_mic_queue_mark_red);
tvPkMark.setText(ResUtil.getString(R.string.avroom_adapter_basemicroviewadapter_02));
} else if (micMemberInfo.getGroupType() == PKTeamInfo.TEAM_BLUE) {
tvPkMark.setVisibility(View.VISIBLE);
tvPkMark.setBackgroundResource(R.drawable.shape_pk_mic_queue_mark_blue);
tvPkMark.setText(ResUtil.getString(R.string.avroom_adapter_basemicroviewadapter_03));
} else {
tvPkMark.setVisibility(View.GONE);
}
} else {
tvPkMark.setVisibility(View.GONE);
}
}
}
/**
* 增加礼物值展示
*/
public class GiftValueViewHolder extends MicroViewAdapter.BasicMicroViewHolder {
TextView tvCharmValue;
View llCharmClick;
GiftValueViewHolder(View itemView) {
super(itemView);
tvCharmValue = itemView.findViewById(R.id.tv_charm_value);
llCharmClick = itemView.findViewById(R.id.ll_charm_click);
}
@Override
void bind(RoomQueueInfo info, int position) {
super.bind(info, position);
//增加非空判断,防止被非法继承
if (isNpe()) {
return;
}
if (info == null) {
return;
}
GiftValueData charmData = info.giftValueData;
if (charmData == null) {
return;
}
charmData.removeObserver();
//控制是否展示礼物值
Observer<Boolean> showObserver = showValue ->
llCharmClick.setVisibility(showValue != null && showValue ? View.VISIBLE : View.GONE);
charmData.getLdShow().observeForever(showObserver);
charmData.setShowObserver(showObserver);
//礼物值的增加显示
Observer<Long> valueObserver = longValue -> {
if (longValue == null) {
return;
}
if (isNpe()) {
return;
}
tvCharmValue.setText(GiftValueFormat.longToString(longValue));
llCharmClick.setOnClickListener(v -> {
if (info.mChatRoomMember != null) {
DialogWebViewActivity.start(context,
UriProvider.getPersonalCharismaRank() + "?uid=" + info.mChatRoomMember.getAccount());
}
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null)
return;
if (roomInfo.isLeaveMode() && position == -1) {
DialogWebViewActivity.start(context,
UriProvider.getPersonalCharismaRank() + "?uid=" + roomInfo.getUid());
}
});
llCharmClick.setOnLongClickListener(v -> {
if (longValue < 100 * 10000L) {
//小于100万不需要长按弹框
return false;
}
View contentView = View.inflate(context, R.layout.popwindow_mic_charm_value, null);
SuperTextView stv_mic_charm_value = contentView.findViewById(R.id.stv_mic_charm_value);
String gvString;
if (longValue >= 10000 * 10000L) {
gvString = "99999999+";
} else {
gvString = String.valueOf(longValue);
}
stv_mic_charm_value.setText(gvString);
PopupWindow window = new PopupWindow(contentView, ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, true);
//设置透明度
ActivityUtil.addAlpha(context, 0.7f);
window.getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
window.setOutsideTouchable(true);
window.setFocusable(true);
window.setBackgroundDrawable(new BitmapDrawable());
int width = window.getContentView().getMeasuredWidth();
int[] location = new int[2];
llCharmClick.getLocationOnScreen(location);
int showWidth = UIUtil.getScreenWidth(context) - location[0] - UIUtil.dip2px(context, 1);
int offsetX = width / 2;
//以下的处理就是当popWindow靠近屏幕右边的时候要计算箭头的位置
if (showWidth < offsetX) {
View iv_center_arrow = contentView.findViewById(R.id.iv_center_arrow);
View iv_move_arrow = contentView.findViewById(R.id.iv_move_arrow);
iv_center_arrow.setVisibility(View.GONE);
iv_move_arrow.setVisibility(View.VISIBLE);
if (iv_move_arrow.getLayoutParams() instanceof RelativeLayout.LayoutParams) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) iv_move_arrow.getLayoutParams();
params.leftMargin = width / 2 + offsetX - showWidth - UIUtil.dip2px(context, 6.5f);
}
offsetX = offsetX + offsetX - showWidth + UIUtil.dip2px(context, 2);
}
int offsetY = UIUtil.dip2px(context, 19.5f + 39f);
window.showAsDropDown(llCharmClick,
-offsetX, -offsetY);
window.setOnDismissListener(() -> ActivityUtil.removeAlpha(context));
return true;
});
};
charmData.getLdValue().observeForever(valueObserver);
charmData.setValueObserver(valueObserver);
//控制最高最低头饰
Observer<Integer> headWearObserver = headWearValue -> {
if (ivCharmLevelTag == null) return;
if (headWearValue == 1) {
ivCharmLevelTag.setVisibility(View.GONE);
// ivCharmLevelTag.setVisibility(View.VISIBLE);
// ivCharmLevelTag.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_charm_level_min));
} else if (headWearValue == 2) {
ivCharmLevelTag.setVisibility(View.VISIBLE);
ivCharmLevelTag.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_charm_level_max));
} else {
ivCharmLevelTag.setVisibility(View.GONE);
}
};
charmData.getLdHeadWear().observeForever(headWearObserver);
charmData.setHeadWearObserver(headWearObserver);
}
private boolean isNpe() {
return tvCharmValue == null || llCharmClick == null;
}
}
public class BossMicroViewHolder extends MicroViewAdapter.GiftValueViewHolder {
/**
* 主席位特有
*/
View frTitle;
TextView tvRoomDesc;
ImageView ivTag;
TextView tvLabelLeaveMode;
CircleImageView ivLeaveMode;
BossMicroViewHolder(View itemView) {
super(itemView);
frTitle = itemView.findViewById(R.id.fr_title);
tvRoomDesc = itemView.findViewById(R.id.tv_room_desc);
ivTag = itemView.findViewById(R.id.iv_tag);
tvLabelLeaveMode = itemView.findViewById(R.id.tv_label_leave_mode);
ivLeaveMode = itemView.findViewById(R.id.iv_bg_leave_mode);
frTitle.setOnClickListener(this);
tvRoomDesc.setOnClickListener(this);
}
@Override
void bind(RoomQueueInfo info, int position) {
super.bind(info, position);
onRoomInfoUpdate();
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null)
return;
// 新版房主位优先判断麦序是否有人,麦序没人再判断是否是离开模式(防止新版展示离开模式,实际麦位有人)
MicMemberInfo chatRoomMember = info.mChatRoomMember;
if (chatRoomMember == null) {
if (roomInfo.isLeaveMode() || AvRoomDataManager.get().isSingleRoom()) {
tvLabelLeaveMode.setVisibility(View.VISIBLE);
ivLeaveMode.setVisibility(View.VISIBLE);
ImageLoadUtils.loadDefaultImage(BasicConfig.INSTANCE.getAppContext(), ivLeaveMode, R.drawable.bg_leave_mode);
ivAvatar.setVisibility(View.VISIBLE);
ivLockImage.setVisibility(View.INVISIBLE);
ivUpImage.setVisibility(View.INVISIBLE);
AvRoomDataManager avRoomDataManager = AvRoomDataManager.get();
ImageLoadUtils.loadAvatar(BasicConfig.INSTANCE.getAppContext(), avRoomDataManager.avatar, ivAvatar);
setSelectText(-1, avRoomDataManager.nick, avRoomDataManager.gender);
} else {
ivLeaveMode.setVisibility(View.GONE);
tvLabelLeaveMode.setVisibility(View.GONE);
}
} else {
ivLeaveMode.setVisibility(View.GONE);
tvLabelLeaveMode.setVisibility(View.GONE);
}
tvNick.setBackgroundColor(context.getResources().getColor(R.color.transparent));
}
@Override
protected void setDefalutText(int index) {
//重新覆盖掉用户名的逻辑
tvNick.setText("");
tvNick.setVisibility(View.GONE);
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
ivTag.setVisibility(View.GONE);
}
@Override
protected void setSelectText(int index, String nick, int gender) {
super.setSelectText(index, nick, gender);
tvNick.setVisibility(View.VISIBLE);
if (UserModel.get().getCacheLoginUserInfo() != null &&
UserModel.get().getCacheLoginUserInfo().getUserInfoSkillVo() != null) {
if (AvRoomDataManager.get().isRoomOwner() && !TextUtils.isEmpty(UserModel.get().getCacheLoginUserInfo().getUserInfoSkillVo().getSkillTag())) {
// ImageLoadUtils.loadImage(context, UserModel.get().getCacheLoginUserInfo().getUserInfoSkillVo().getSkillTag(), ivTag);
ivTag.setVisibility(View.GONE);
tvNick.setCompoundDrawablePadding(4);
tvNick.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
} else {
setBossViewGender(tvNick, gender == 1);
ivTag.setVisibility(View.GONE);
}
}
}
void onRoomInfoUpdate() {
RoomInfo roomInfo = AvRoomDataManager.get().mCurrentRoomInfo;
if (roomInfo == null) return;
if (!TextUtils.isEmpty(roomInfo.getRoomDesc())) {
tvRoomDesc.setText(RegexUtil.getPrintableString(roomInfo.getRoomDesc()));
} else {
if (AvRoomDataManager.get().isManager()) {
tvRoomDesc.setText(BasicConfig.INSTANCE.getAppContext().getString(R.string.room_manager_edit_desc));
} else {
tvRoomDesc.setText(BasicConfig.INSTANCE.getAppContext().getString(R.string.room_no_desc));
}
}
}
@Override
public void clear() {
super.clear();
tvRoomDesc.setText(BasicConfig.INSTANCE.getAppContext().getString(R.string.room_no_desc));
ivTag.setVisibility(View.GONE);
}
@Override
public void onClick(View v) {
super.onClick(v);
}
}
}

View File

@@ -0,0 +1,25 @@
package com.chwl.app.avroom.adapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter
/**
* ViewPager2适配器
* Created by wushaocheng on 2022/12/07.
*/
class CommonVPAdapter(
fm: FragmentManager,
lifecycle: Lifecycle,
private val fragmentList: List<Fragment>
) : FragmentStateAdapter(fm, lifecycle) {
override fun getItemCount(): Int {
return fragmentList.size
}
override fun createFragment(position: Int): Fragment {
return fragmentList[position]
}
}

View File

@@ -0,0 +1,140 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.core.bean.RoomQueueInfo;
import com.chwl.library.utils.ResUtil;
public class CpMicroViewAdapter extends BaseMicroViewAdapter {
public CpMicroViewAdapter(Context context) {
super(context);
}
@Override
public String microType() {
return BaseMicroViewAdapter.MICRO_TYPE_CP;
}
@Override
protected int getMicPositionNameOffset() {
return 1;
}
@Override
public void bindToRecyclerView(RecyclerView recyclerView) {
GridLayoutManager layoutManager = new GridLayoutManager(context, 3);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (position == 0) {
return 2;
} else {
return 1;
}
}
});
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(this);
}
@Override
public int getItemCount() {
return 2;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View item;
if (viewType == TYPE_BOSS) {
item = LayoutInflater.from(parent.getContext()).
inflate(R.layout.item_cp_boss_micro, parent, false);
return new CpBossMicroViewHolder(item);
} else {
item = LayoutInflater.from(parent.getContext()).
inflate(R.layout.list_item_micro_cp, parent, false);
return new CpMicroViewHolder(item);
}
}
public class CpMicroViewHolder extends NormalMicroViewHolder {
CpMicroViewHolder(View itemView) {
super(itemView);
}
@Override
void bind(RoomQueueInfo info, int position) {
super.bind(info, position);
// ViewAdapter.setViewBackground(
// tvNick, context.getResources().getColor(R.color.black_transparent_20), 50, 0, 0);
}
@Override
protected void setDefalutText(int index) {
super.setDefalutText(index);
tvNick.setText(ResUtil.getString(R.string.avroom_adapter_cpmicroviewadapter_01));
}
}
public class CpBossMicroViewHolder extends NormalMicroViewHolder {
/**
* 主席位特有
*/
TextView tvRoomType;
TextView tvRoomDesc;
View ivRoomCanEdit;
CpBossMicroViewHolder(View itemView) {
super(itemView);
// tvRoomType = itemView.findViewById(R.id.tv_room_type);
// tvRoomDesc = itemView.findViewById(R.id.tv_room_desc);
// ivRoomCanEdit = itemView.findViewById(R.id.iv_room_can_edit);
// tvRoomDesc.setOnClickListener(this);
// tvRoomType.setOnClickListener(this);
// ivRoomCanEdit.setOnClickListener(this);
}
@Override
void bind(RoomQueueInfo info, int position) {
super.bind(info, position);
// ViewAdapter.setViewBackground(
// tvNick, context.getResources().getColor(R.color.black_transparent_20), 50, 0, 0);
// onRoomInfoUpdate();
// tvNick.setBackgroundColor(context.getResources().getColor(R.color.transparent));
// tvNick.setTextColor(context.getResources().getColor(R.color.white));
// if (AvRoomDataManager.get().isManager()) {
// ivRoomCanEdit.setVisibility(View.VISIBLE);
// } else {
// ivRoomCanEdit.setVisibility(View.GONE);
// }
}
@Override
protected void setDefalutText(int index) {
super.setDefalutText(index);
tvNick.setText(ResUtil.getString(R.string.avroom_adapter_cpmicroviewadapter_02));
}
@Override
public void clear() {
super.clear();
}
@Override
public void onClick(View v) {
super.onClick(v);
}
}
}

View File

@@ -0,0 +1,18 @@
package com.chwl.app.avroom.adapter
import android.widget.ImageView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.chwl.app.R
import com.chwl.app.ui.utils.load
import com.chwl.core.room.game.bean.GameInfo
class CreateRoomGameAdapter :
BaseQuickAdapter<GameInfo, BaseViewHolder>(R.layout.item_room_create_game) {
override fun convert(helper: BaseViewHolder, item: GameInfo) {
helper.getView<ImageView>(R.id.iv_cover).load(item.pic?:"",12f)
helper.itemView.isSelected = item.isSelect
}
}

View File

@@ -0,0 +1,16 @@
package com.chwl.app.avroom.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.chwl.app.R
import com.chwl.library.common.glide.GlideUtils
import com.chwl.core.room.game.bean.GameInfo
class CreateRoomGameGuideAdapter :
BaseQuickAdapter<GameInfo, BaseViewHolder>(R.layout.item_room_create_game_guide) {
override fun convert(helper: BaseViewHolder, item: GameInfo) {
GlideUtils.instance().load(item.pic?:"",R.drawable.default_cover,helper.getView(R.id.iv_cover))
}
}

View File

@@ -0,0 +1,235 @@
package com.chwl.app.avroom.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.util.forEach
import androidx.core.view.isVisible
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chwl.app.R
import com.chwl.app.ui.utils.load
import com.chwl.app.utils.UserUtils
import com.chwl.core.Constants
import com.chwl.core.bean.RoomQueueInfo
import com.chwl.core.manager.AvRoomDataManager
import com.chwl.core.room.bean.RoomInfo
import com.chwl.library.utils.ResUtil
/**
* @author xiaoyu
* @date 2017/12/18
*/
class DatingMicroViewAdapter(context: Context?) : BaseMicroViewAdapter(context) {
override fun getMicPositionNameOffset(): Int {
return 1
}
/**
* Set LayoutManager and bind this to RecyclerView
*/
override fun bindToRecyclerView(recyclerView: RecyclerView) {
val layoutManager = GridLayoutManager(context, 4)
layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return if (position == 0) 4 else 1
}
}
layoutManager.orientation = LinearLayoutManager.VERTICAL
recyclerView.layoutManager = layoutManager
recyclerView.adapter = this
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == TYPE_BOSS) {
DatingBossMicroViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_micro_dating_boss, parent, false)
)
} else {
DatingMicroViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_micro_dating, parent, false)
)
}
}
override fun getItemViewType(position: Int) = if (position == 0) TYPE_BOSS else TYPE_NORMAL
override fun microType() = MICRO_TYPE_DATING
open inner class DatingMicroViewHolder constructor(itemView: View) :
GiftValueViewHolder(itemView) {
private val viewGenderBg: View = itemView.findViewById(R.id.view_gender_bg)
private val tvSelectedStatus: TextView = itemView.findViewById(R.id.tv_selected_status)
private val ivCap: ImageView = itemView.findViewById(R.id.iv_cap)
protected val ivVipWear: ImageView = itemView.findViewById(R.id.iv_vip_wear)
@SuppressLint("SetTextI18n")
public override fun bind(info: RoomQueueInfo, position: Int) {
super.bind(info, position)
val roomInfo = AvRoomDataManager.get().mCurrentRoomInfo ?: return
val roomMicInfo = info.mRoomMicInfo
val manMicro = Constants.maleIndex.contains(position)
val uid = UserUtils.getUserUid()
if (roomMicInfo != null) {
viewGenderBg.setBackgroundResource(if (manMicro) R.drawable.shape_circle_micro_man_bg else R.drawable.shape_circle_micro_woman_bg)
tvSelectedStatus.setBackgroundResource(if (manMicro) R.drawable.selector_dating_select_man_bg else R.drawable.selector_dating_select_woman_bg)
}
ivVipWear.setImageResource(R.drawable.icon_room_dating_vip)
info.mChatRoomMember?.let {
if (roomInfo.blindDateState == RoomInfo.DATING_STATE_FLOW) {
tvSelectedStatus.isVisible = false
} else {
tvSelectedStatus.isVisible = true
if (it.isVipMic) {
tvSelectedStatus.background = null
ivVipWear.setImageResource(R.drawable.icon_room_dating_vip_have_present)
}
if (it.isHasSelectUser) {
tvSelectedStatus.isSelected = true
if (roomInfo.blindDateState == RoomInfo.DATING_STATE_PUBLISH ||
uid == it.account.toLong() ||
AvRoomDataManager.get().isPreside(uid)
) {
tvSelectedStatus.text =
if (AvRoomDataManager.get().isDatingVipMic(it.selectMicPosition)
) ResUtil.getString(R.string.avroom_adapter_datingmicroviewadapter_01) else "${it.selectMicPosition + 1}"
} else {
tvSelectedStatus.text = "已選擇"
}
} else {
tvSelectedStatus.isSelected = false
tvSelectedStatus.text = "未選擇"
}
}
if (!it.capUrl.isNullOrEmpty()) {
ivCap.load(it.capUrl, 0f, 0)
ivCap.visibility = View.VISIBLE
} else {
ivCap.visibility = View.GONE
}
ivVipWear.isVisible = it.isVipMic
if (it.isVipMic) {
ivHeadWear?.isVisible = false
}
} ?: run {
tvSelectedStatus.isVisible = false
ivCap.isVisible = false
ivVipWear.isVisible = false
if (AvRoomDataManager.POSITION_VIP_MIC == position) {
tvNick.text = ""
} else if (position != -1) {
tvNick.text = "${if (manMicro) "男神" else "女神"}"
}
}
}
}
inner class DatingBossMicroViewHolder internal constructor(itemView: View) :
BossMicroViewHolder(itemView) {
private val rvVip: RecyclerView = itemView.findViewById(R.id.rv_vip)
private val ivVipWear: ImageView = itemView.findViewById(R.id.iv_vip_wear)
public override fun bind(info: RoomQueueInfo, position: Int) {
super.bind(info, position)
if (info.mChatRoomMember == null) {
tvNick.alpha = 1f
tvNick.text = "主持人"
tvNick.isVisible = true
ivVipWear.isVisible = false
} else {
if (info.mChatRoomMember.isVipMic) {
ivHeadWear?.isVisible = false
ivVipWear.isVisible = true
} else {
ivVipWear.isVisible = false
}
}
val mMicQueueMemberMap = AvRoomDataManager.get().mMicQueueMemberMap
var showVipMicro = true
mMicQueueMemberMap.forEach { key, value ->
value?.mChatRoomMember?.let {
if (it.isVipMic && AvRoomDataManager.POSITION_VIP_MIC != key) {
showVipMicro = false
}
}
}
rvVip.isVisible = showVipMicro
if (showVipMicro) {
var adapter: VipMicroViewAdapter? = rvVip.adapter as? VipMicroViewAdapter
if (adapter == null) {
adapter = VipMicroViewAdapter(context)
adapter.bindToRecyclerView(rvVip)
adapter.setOnMicroItemClickListener(onMicroItemClickListener)
}
adapter.notifyDataSetChanged()
}
}
}
inner class VipMicroViewAdapter(context: Context?) : BaseMicroViewAdapter(context) {
/**
* Set LayoutManager and bind this to RecyclerView
*/
override fun bindToRecyclerView(recyclerView: RecyclerView) {
val layoutManager = LinearLayoutManager(context)
layoutManager.orientation = LinearLayoutManager.VERTICAL
recyclerView.layoutManager = layoutManager
recyclerView.adapter = this
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return VipMicroViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_micro_dating, parent, false)
)
}
override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {
val roomQueueInfo =
AvRoomDataManager.get()
.getRoomQueueMemberInfoByMicPosition(AvRoomDataManager.POSITION_VIP_MIC)
?: return
(viewHolder as NormalMicroViewHolder).bind(
roomQueueInfo,
AvRoomDataManager.POSITION_VIP_MIC
)
}
override fun microType() = MICRO_TYPE_DATING_VIP
override fun getItemCount() = 1
inner class VipMicroViewHolder constructor(itemView: View) :
DatingMicroViewHolder(itemView) {
override fun bind(info: RoomQueueInfo, position: Int) {
super.bind(info, position)
ivVipWear.isVisible = true
ivHeadWear?.isVisible = false
}
}
}
}

View File

@@ -0,0 +1,22 @@
package com.chwl.app.avroom.adapter
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.chwl.app.R
import com.chwl.app.ui.utils.ImageLoadUtils
import com.chwl.core.home.bean.HomeRoomInfo
import com.chwl.core.utils.extension.subAndReplaceDot
import com.chwl.library.common.util.isVerify
class ExitRoomAdapter :
BaseQuickAdapter<HomeRoomInfo, BaseViewHolder>(R.layout.item_exit_room) {
override fun convert(helper: BaseViewHolder, item: HomeRoomInfo) {
ImageLoadUtils.loadImage(mContext, item.avatar, helper.getView(R.id.iv_avatar))
ImageLoadUtils.loadImage(mContext, item.tagPict, helper.getView(R.id.iv_tag))
helper.setText(R.id.tv_online_num, item.onlineNum.toString())
.setText(R.id.tv_title, item.title.subAndReplaceDot(8))
helper.setVisible(R.id.iv_tag, item.tagPict.isVerify())
}
}

View File

@@ -0,0 +1,98 @@
package com.chwl.app.avroom.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.netease.nim.uikit.common.util.sys.ScreenUtil
import com.chwl.app.R
import com.chwl.core.bean.RoomQueueInfo
import com.chwl.core.manager.AvRoomDataManager
import com.chwl.library.utils.ResUtil
/**
* @author xiaoyu
* @date 2017/12/18
*/
class GameMicroViewAdapter(context: Context?) : BaseMicroViewAdapter(context) {
/**
* Set LayoutManager and bind this to RecyclerView
*/
override fun bindToRecyclerView(recyclerView: RecyclerView) {
val layoutManager = LinearLayoutManager(context)
layoutManager.orientation = LinearLayoutManager.HORIZONTAL
recyclerView.layoutManager = layoutManager
recyclerView.adapter = this
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return GameMicroViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_micro_game, parent, false)
)
}
override fun microType() = MICRO_TYPE_DATING
inner class GameMicroViewHolder constructor(itemView: View) :
GiftValueViewHolder(itemView) {
private val tvGameStatus: TextView = itemView.findViewById(R.id.tv_game_status)
@SuppressLint("SetTextI18n")
public override fun bind(info: RoomQueueInfo, position: Int) {
itemView.updateLayoutParams<RecyclerView.LayoutParams> {
width = when (itemCount) {
6 -> ScreenUtil.screenWidth / 6
7 -> ScreenUtil.screenWidth / 7
else -> (ScreenUtil.screenWidth / 6f).toInt()
}
}
super.bind(info, position)
info.mChatRoomMember?.let {
if (it.gameStatus == 0 && !AvRoomDataManager.get().isRoomOwner(it.account)) {
tvGameStatus.isVisible = false
} else {
tvGameStatus.isVisible = true
val bgRes = when {
AvRoomDataManager.get().isRoomOwner(it.account) -> {
tvGameStatus.text = ResUtil.getString(R.string.avroom_adapter_gamemicroviewadapter_01)
R.drawable.bg_game_status_owner
}
it.gameStatus == 2 -> {
tvGameStatus.text = ResUtil.getString(R.string.avroom_adapter_gamemicroviewadapter_02)
R.drawable.bg_game_status_ready
}
it.gameStatus == 3 -> {
tvGameStatus.text = ResUtil.getString(R.string.avroom_adapter_gamemicroviewadapter_03)
R.drawable.bg_game_status_playing
}
else -> {
tvGameStatus.text = ResUtil.getString(R.string.avroom_adapter_gamemicroviewadapter_04)
R.drawable.bg_game_status_not_ready
}
}
tvGameStatus.setBackgroundResource(bgRes)
}
} ?: run {
tvGameStatus.isVisible = false
}
}
}
override fun getItemCount(): Int {
return AvRoomDataManager.get().mgMicNum
}
}

View File

@@ -0,0 +1,68 @@
package com.chwl.app.avroom.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chwl.app.R
import com.chwl.core.bean.RoomQueueInfo
import com.chwl.core.manager.AvRoomDataManager
/**
* @author xiaoyu
* @date 2017/12/18
*/
class GameMiniMicroViewAdapter(context: Context?) : BaseMicroViewAdapter(context) {
private var onClick: (() -> Unit)? = null
/**
* Set LayoutManager and bind this to RecyclerView
*/
override fun bindToRecyclerView(recyclerView: RecyclerView) {
val layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = this
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return GameMicroViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_micro_game_mini, parent, false)
)
}
fun setOnClick(onClick: () -> Unit) {
this.onClick = onClick
}
override fun microType() = ""
inner class GameMicroViewHolder constructor(itemView: View) :
NormalMicroViewHolder(itemView) {
@SuppressLint("SetTextI18n")
public override fun bind(info: RoomQueueInfo, position: Int) {
super.bind(info, position)
itemView.setOnClickListener {
onClick?.invoke()
}
}
override fun onClick(v: View?) {
onClick?.invoke()
}
}
override fun getItemCount(): Int {
return AvRoomDataManager.get().mgMicNum
}
}

View File

@@ -0,0 +1,33 @@
package com.chwl.app.avroom.adapter;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import java.util.List;
/**
* <p> </p>
*
* @author jiahui
* @date 2017/12/8
*/
public class HomePartyPageAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragmentList;
public HomePartyPageAdapter(FragmentManager fm, List<Fragment> fragmentList) {
super(fm);
mFragmentList = fragmentList;
}
@Override
public Fragment getItem(int position) {
return (mFragmentList == null || mFragmentList.size() == 0 ? null : mFragmentList.get(position));
}
@Override
public int getCount() {
return mFragmentList == null ? 0 : mFragmentList.size();
}
}

View File

@@ -0,0 +1,144 @@
package com.chwl.app.avroom.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.app.ui.utils.ImageLoadKt;
import com.chwl.app.ui.widget.recyclerview.layoutmanager.BoosRoomLayoutManager;
import com.chwl.app.utils.ResourceManager;
import com.chwl.core.bean.RoomQueueInfo;
import com.chwl.core.gift.bean.RoomMicDress;
import com.chwl.library.common.util.OtherExtKt;
import com.chwl.library.widget.SVGAView;
import com.example.lib_utils.ktx.ResourcesKtxKt;
import com.opensource.svgaplayer.SVGAImageView;
public class Mic19ViewAdapter extends BaseMicroViewAdapter {
//麦位 从-1 开始的 , 所以 8好麦的pos是6
int BossPos = 7;
public Mic19ViewAdapter(Context context) {
super(context);
}
/**
* Set LayoutManager and bind this to RecyclerView
*/
@Override
public void bindToRecyclerView(RecyclerView recyclerView) {
recyclerView.setLayoutManager(new BoosRoomLayoutManager(5));
recyclerView.setAdapter(this);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
OtherExtKt.doLog(" Mic19ViewAdapter onCreateViewHolder ");
View item ;
item = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_micro,parent,false);
MicroViewHolder microViewHolder = new MicroViewHolder(item);
return microViewHolder;
}
private void setViewDiff(View[] views , boolean isDiff) {
for (int i = 0; i <views.length; i++) {
int width = 0;
View view = views[i];
//头像,锁头,上麦图 宽度
if (isDiff) {
width = ResourcesKtxKt.getDimensionToInt(R.dimen.dp_62);
} else {
width = ResourcesKtxKt.getDimensionToInt(R.dimen.dp_50);
}
if (view instanceof SVGAView){
// 头饰
width = (int) (width / 0.7575);
}else if (view instanceof SVGAImageView){
//光圈
width = (int) (width / 0.5555);
}else if (view.getId() == R.id.micro_layout){
//头像布局 , 特殊更改
width = ResourcesKtxKt.getDimensionToInt(R.dimen.dp_66);
if (isDiff) {
width = (int) (ResourcesKtxKt.getDimensionToInt(R.dimen.dp_66) / 0.7575);
}
}
OtherExtKt.setViewWH(view, width, width,false);
}
}
@Override
public String microType() {
return BaseMicroViewAdapter.MICRO_TYPE_REVELRY_19;
}
@Override
public int getItemViewType(int position) {
return position != BossPos ? TYPE_NORMAL : TYPE_BOSS;
}
@Override
public int getItemCount() {
return 19;
}
class MicroViewHolder extends GiftValueViewHolder {
MicroViewHolder(View itemView) {
super(itemView);
micType = -1;
}
@Override
public void bind(RoomQueueInfo info, int position) {
// int width = MyUtil.INSTANCE.getMAppWidth() / 5;
OtherExtKt.setViewWH(rootView,ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,false);
setViewDiff(new View[]{ivHalo,ivHeadWear, ivAvatar, ivLockImage, ivUpImage,microLayout}, position == 6);
super.bind(info, position);
// ivUpImage.setImageResource(R.drawable.icon_room_up_micro);
// 麦位皮肤
// ivUpImage = up_image = icon_room_up_micro - 可上麦
// ivLockImage = lock_image = icon_room_lock_micro - 锁麦
RoomMicDress roomMicSkins = ResourceManager.INSTANCE.getRoomMicSkins();
if (roomMicSkins != null) {
if (getItemViewType() == TYPE_BOSS) {
OtherExtKt.doLog("麦位 加载 麦位 图 boss position = "+position+" = "+roomMicSkins.bossMicUrl);
ImageLoadKt.loadImage(ivUpImage,roomMicSkins.bossMicUrl);
ImageLoadKt.loadImage(ivLockImage,roomMicSkins.bossMicLockUrl);
} else {
OtherExtKt.doLog("麦位 加载 麦位 图 normal position = "+position+" = "+roomMicSkins.bossMicUrl);
ImageLoadKt.loadImage(ivUpImage,roomMicSkins.normalMicUrl);
ImageLoadKt.loadImage(ivLockImage,roomMicSkins.normalMicLockUrl);
}
}else {
OtherExtKt.doLog("麦位 加载 麦位 图 def position = "+position);
if (getItemViewType() == TYPE_BOSS) {
ivUpImage.setImageResource(R.drawable.icon_room_up_micro_boss);
ivLockImage.setImageResource(R.drawable.icon_room_lock_micro);
} else {
ivUpImage.setImageResource(R.drawable.icon_room_up_micro);
ivLockImage.setImageResource(R.drawable.icon_room_lock_micro);
}
}
}
@SuppressLint("SetTextI18n")
@Override
public void setDefalutText(int index) {
super.setDefalutText(index);
}
}
}

View File

@@ -0,0 +1,70 @@
package com.chwl.app.avroom.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.core.bean.RoomQueueInfo;
public class Mic20ViewAdapter extends BaseMicroViewAdapter {
public Mic20ViewAdapter(Context context) {
super(context);
}
/**
* Set LayoutManager and bind this to RecyclerView
*/
@Override
public void bindToRecyclerView(RecyclerView recyclerView) {
recyclerView.setLayoutManager(new GridLayoutManager(context,5,RecyclerView.VERTICAL,false));
recyclerView.setAdapter(this);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View item;
item = LayoutInflater.from(parent.getContext()).
inflate(R.layout.list_item_micro, parent, false);
return new Mic20ViewAdapter.MicroViewHolder(item);
}
@Override
public String microType() {
return BaseMicroViewAdapter.MICRO_TYPE_REVELRY_20;
}
@Override
public int getItemViewType(int position) {
return TYPE_NORMAL;
}
@Override
public int getItemCount() {
return 20;
}
class MicroViewHolder extends GiftValueViewHolder {
MicroViewHolder(View itemView) {
super(itemView);
}
@Override
public void bind(RoomQueueInfo info, int position) {
super.bind(info, position);
// ivUpImage.setImageResource(R.drawable.icon_room_up_micro);
}
@SuppressLint("SetTextI18n")
@Override
public void setDefalutText(int index) {
super.setDefalutText(index);
}
}
}

View File

@@ -0,0 +1,99 @@
package com.chwl.app.avroom.adapter;
import android.graphics.drawable.GradientDrawable;
import android.widget.TextView;
import androidx.appcompat.widget.AppCompatImageView;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.netease.nim.uikit.support.glide.GlideApp;
import com.chwl.app.R;
import com.chwl.app.common.widget.CircleImageView;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.room.queuing_mic.bean.GroupType;
import com.chwl.core.room.queuing_mic.bean.QueuingMicMemeberInfo;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.library.utils.ResUtil;
import java.util.List;
/**
* @author jack
* @Description
* @Date 2018/12/14
*/
public class MicQueueAdapter extends BaseQuickAdapter<QueuingMicMemeberInfo, BaseViewHolder> {
public MicQueueAdapter(List<QueuingMicMemeberInfo> list) {
super(R.layout.item_mic_queue_list, list);
}
@Override
protected void convert(BaseViewHolder helper, final QueuingMicMemeberInfo item) {
if (item == null) return;
helper.setText(R.id.tv_userName, item.getNick())
.setText(R.id.tv_no, (helper.getAdapterPosition() + 1) + "");
CircleImageView ivAvatar = helper.getView(R.id.iv_avatar_view);
GlideApp.with(ivAvatar.getContext())
.load(item.getAvatar())
.placeholder(R.drawable.default_avatar)
.into(ivAvatar);
AppCompatImageView ivGender = helper.getView(R.id.iv_gender);
if (item.getGender() == UserInfo.GENDER_MALE) {
ivGender.setImageResource(R.drawable.ic_gender_male);
} else {
ivGender.setImageResource(R.drawable.ic_gender_female);
}
TextView tvOpt = helper.getView(R.id.tv_opt);
GradientDrawable attentionBg = (GradientDrawable) tvOpt.getBackground();
if (AvRoomDataManager.get().isManager()) {
if (item.getGroupType() == GroupType.MALE) {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_micqueueadapter_01));
attentionBg.setColor(mContext.getResources().getColor(R.color.color_518EFF));
} else if (item.getGroupType() == GroupType.FEMALE) {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_micqueueadapter_02));
attentionBg.setColor(mContext.getResources().getColor(R.color.color_FF6B82));
} else {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_micqueueadapter_03));
attentionBg.setColor(mContext.getResources().getColor(R.color.appColor));
}
tvOpt.setTextColor(mContext.getResources().getColor(R.color.color_white));
final int itemPos = helper.getAdapterPosition();
tvOpt.setOnClickListener(v -> {
if (onUpMicListener != null) {
onUpMicListener.onUpMic(item, itemPos);
}
});
} else {
if (item.getGroupType() == GroupType.MALE) {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_micqueueadapter_04));
attentionBg.setColor(mContext.getResources().getColor(R.color.color_518EFF));
} else if (item.getGroupType() == GroupType.FEMALE) {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_micqueueadapter_05));
attentionBg.setColor(mContext.getResources().getColor(R.color.color_FF6B82));
} else {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_micqueueadapter_06));
tvOpt.setTextColor(mContext.getResources().getColor(R.color.appColor));
attentionBg.setColor(mContext.getResources().getColor(R.color.color_f0f0f0));
}
tvOpt.setOnClickListener(null);
}
}
public interface OnUpMicListener {
void onUpMic(QueuingMicMemeberInfo uid, int itemPos);
}
private OnUpMicListener onUpMicListener;
public void setOnUpMicListener(OnUpMicListener onUpMicListener) {
this.onUpMicListener = onUpMicListener;
}
}

View File

@@ -0,0 +1,110 @@
package com.chwl.app.avroom.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.core.bean.RoomQueueInfo;
/**
* @author xiaoyu
* @date 2017/12/18
*/
public class MicroViewAdapter extends BaseMicroViewAdapter {
public MicroViewAdapter(Context context) {
super(context);
}
@Override
protected int getMicPositionNameOffset() {
return 1;
}
/**
* Set LayoutManager and bind this to RecyclerView
*/
@Override
public void bindToRecyclerView(RecyclerView recyclerView) {
GridLayoutManager layoutManager = new GridLayoutManager(context, 4);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (position == 0) {
return 4;
} else {
return 1;
}
}
});
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(this);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View item;
if (viewType == TYPE_BOSS) {
item = LayoutInflater.from(parent.getContext()).
inflate(R.layout.item_boss_micro, parent, false);
return new BossMicroViewHolder(item);
} else {
item = LayoutInflater.from(parent.getContext()).
inflate(R.layout.list_item_micro, parent, false);
return new MicroViewHolder(item);
}
}
@Override
public String microType() {
return BaseMicroViewAdapter.MICRO_TYPE_NORMAL;
}
@Override
public int getItemViewType(int position) {
if (position == 0) return TYPE_BOSS;
return TYPE_NORMAL;
}
class MicroViewHolder extends BaseMicroViewAdapter.GiftValueViewHolder {
MicroViewHolder(View itemView) {
super(itemView);
}
@Override
public void bind(RoomQueueInfo info, int position) {
super.bind(info, position);
// if (position == 7) {
// ivUpImage.setImageResource(R.drawable.icon_room_up_micro_vip);
// } else {
// ivUpImage.setImageResource(R.drawable.icon_room_up_micro);
// }
}
@SuppressLint("SetTextI18n")
@Override
public void setDefalutText(int index) {
// if (index == 7) {
// tvNick.setTextColor(Color.WHITE);
// tvNick.setText(ResUtil.getString(R.string.avroom_adapter_microviewadapter_01));
// if (tvNumber != null) {
// tvNumber.setBackgroundResource(R.drawable.shape_micro_vip);
// tvNumber.setTextColor(Color.WHITE);
// tvNumber.setText(String.valueOf((index + 1)));
// }
// } else {
super.setDefalutText(index);
// }
}
}
}

View File

@@ -0,0 +1,17 @@
package com.chwl.app.avroom.adapter;
import com.chwl.core.room.queue.bean.MicMemberInfo;
/**
* Created by lvzebiao on 2018/11/5.
*/
public interface OnMicroItemClickListener {
void onAvatarBtnClick(int position);
void onUpMicBtnClick(int position, MicMemberInfo chatRoomMember);
void onLockBtnClick(int position);
void onRoomSettingsClick();
}

View File

@@ -0,0 +1,239 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.recyclerview.widget.RecyclerView;
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chwl.app.utils.NamePlateHelper;
import com.chwl.core.level.UserLevelVo;
import com.chwl.core.room.bean.RoomOnlineUserBean;
import com.netease.nim.uikit.impl.cache.NimUserInfoCache;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.uinfo.constant.GenderEnum;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
import com.chwl.app.R;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.app.ui.widget.NobleAvatarView;
import com.chwl.app.utils.RegexUtil;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.level.UserLevelResourceType;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.manager.IMNetEaseManager;
import com.chwl.core.manager.RoomEvent;
import com.chwl.core.noble.NobleResourceType;
import com.chwl.core.noble.NobleUtil;
import com.chwl.core.room.bean.OnlineChatMember;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.library.utils.ListUtils;
import java.util.List;
import io.reactivex.disposables.Disposable;
/**
* <p> 房间在线人数列表 (上麦,房主,游客,管理员) </p>
*
* @author Administrator
* @date 2017/12/4
*/
public class OnlineUserAdapter extends BaseMultiItemQuickAdapter<RoomOnlineUserBean, BaseViewHolder> {
private boolean mIsHomeParty;
private Disposable mDisposable;
private OnRoomOnlineNumberChangeListener mListener;
public OnlineUserAdapter(Context context, boolean isHomeParty) {
super(null);
addItemType(RoomOnlineUserBean.NORMAL, R.layout.list_item_online_user);
addItemType(RoomOnlineUserBean.NOBLE, R.layout.list_item_online_user_mystery);
mIsHomeParty = isHomeParty;
}
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
registerRoomEvent();
}
@Override
protected void convert(@NonNull BaseViewHolder helper, RoomOnlineUserBean item) {
if (item.getItemType() == OnlineChatMember.NOBLE) {
return;
}
// 性别
final ImageView sexImage = helper.getView(R.id.sex);
if (item.getGender() == 1) {
sexImage.setVisibility(View.VISIBLE);
sexImage.setImageResource(R.drawable.ic_gender_male);
} else if (item.getGender() == 2) {
sexImage.setVisibility(View.VISIBLE);
sexImage.setImageResource(R.drawable.ic_gender_female);
} else {
sexImage.setVisibility(View.GONE);
}
// 昵称
helper.setText(R.id.nick, RegexUtil.getPrintableString(item.getNick()));
// 头像
NobleAvatarView nobleAvatarView = helper.getView(R.id.noble_avatar_view);
nobleAvatarView.setSize(37, 54, 0);
nobleAvatarView.setData(item);
// 官字
helper.getView(R.id.iv_user_official).setVisibility(item.isOfficial() ? View.VISIBLE : View.GONE);
// 管理
ImageView ivManager = helper.getView(R.id.manager_logo);
if (item.getMemberType() != null && item.getMemberType().equals("MANAGER")) {
ivManager.setVisibility(View.VISIBLE);
ivManager.setImageResource(R.drawable.icon_admin_logo);
} else if (item.getMemberType() != null && item.getMemberType().equals("CREATOR")) {
ivManager.setVisibility(View.VISIBLE);
ivManager.setImageResource(R.drawable.icon_user_list_room_ownner);
} else {
ivManager.setVisibility(View.GONE);
}
// 在麦
ImageView ivMic = helper.getView(R.id.room_online_tag);
ivMic.setVisibility(item.isInMic() ? View.VISIBLE : View.GONE);
//等级
UserLevelVo levelVo = item.getUserLevelVo();
String experLevelUrl = null;
String charmLevelUrl = null;
if (levelVo != null) {
experLevelUrl = levelVo.getExperUrl();
charmLevelUrl = levelVo.getCharmUrl();
}
//经验等级
AppCompatImageView ivUserExper = helper.getView(R.id.iv_user_exper);
boolean isExperLevelUrlEmpty = TextUtils.isEmpty(experLevelUrl);
ivUserExper.setVisibility(!isExperLevelUrlEmpty ? View.VISIBLE : View.GONE);
if (!isExperLevelUrlEmpty) {
ImageLoadUtils.loadImage(mContext, experLevelUrl, ivUserExper);
}
//魅力等级
AppCompatImageView ivUserCharm = helper.getView(R.id.iv_user_charm);
boolean isCharmLevelUrlEmpty = TextUtils.isEmpty(charmLevelUrl);
ivUserCharm.setVisibility(!isCharmLevelUrlEmpty ? View.VISIBLE : View.GONE);
if (!isCharmLevelUrlEmpty) {
ImageLoadUtils.loadImage(mContext, charmLevelUrl, ivUserCharm);
}
// 铭牌
View inNamePlate = helper.getView(R.id.in_nameplate);
NamePlateHelper.INSTANCE.load(inNamePlate, inNamePlate.findViewById(R.id.tv_official_mask), inNamePlate.findViewById(R.id.iv_official_mask), item);
}
private void registerRoomEvent() {
mDisposable = IMNetEaseManager.get()
.getChatRoomEventObservable()
.subscribe(roomEvent -> {
if (roomEvent == null) return;
int event = roomEvent.getEvent();
if (roomEvent.getEvent() == RoomEvent.ADD_BLACK_LIST ||
roomEvent.getEvent() == RoomEvent.DOWN_MIC ||
roomEvent.getEvent() == RoomEvent.KICK_OUT_ROOM) {
if (roomEvent.getEvent() == RoomEvent.ADD_BLACK_LIST ||
roomEvent.getEvent() == RoomEvent.KICK_OUT_ROOM) {
if (mListener != null
&& !AvRoomDataManager.get().isOwner(AuthModel.get().getCurrentUid())) {
mListener.addMemberBlack();
return;
}
}
if (ListUtils.isListEmpty(mData)) return;
if (mIsHomeParty && roomEvent.getEvent() == RoomEvent.DOWN_MIC) {
updateDownUpMic(roomEvent.getAccount(), false);
return;
}
if (mListener != null)
mListener.addMemberBlack();
} else if (roomEvent.getEvent() == RoomEvent.ROOM_MANAGER_ADD
|| roomEvent.getEvent() == RoomEvent.ROOM_MANAGER_REMOVE) {
updateManager(roomEvent);
} else if (roomEvent.getEvent() == RoomEvent.UP_MIC) {
updateDownUpMic(roomEvent.getAccount(), true);
} else if (event == RoomEvent.ROOM_MEMBER_IN) {
updateMemberIn(roomEvent);
} else if (event == RoomEvent.ROOM_MEMBER_EXIT) {
if (mListener != null) {
mListener.onMemberExit(roomEvent.getAccount());
}
}
});
}
private void updateMemberIn(RoomEvent roomEvent) {
if (mListener != null) {
mListener.onMemberIn(roomEvent.getAccount());
}
}
private void updateManager(RoomEvent roomEvent) {
if (mListener != null)
mListener.onUpdateMemberManager(roomEvent.getAccount(),
roomEvent.getEvent() == RoomEvent.ROOM_MANAGER_REMOVE);
}
private void updateDownUpMic(String account, boolean isUpMic) {
if (mListener != null) {
mListener.onMemberDownUpMic(account, isUpMic);
}
}
public void release() {
if (mDisposable != null) {
mDisposable.dispose();
mDisposable = null;
}
}
public void setListener(OnRoomOnlineNumberChangeListener listener) {
mListener = listener;
}
public interface OnRoomOnlineNumberChangeListener {
/**
* 成员进来回调
*
* @param account
*/
void onMemberIn(String account);
/**
* 成员出去回调
*
* @param account
*/
void onMemberExit(String account);
/**
* 成员上下麦更新
*
* @param account
* @param isUpMic
*/
void onMemberDownUpMic(String account, boolean isUpMic);
/**
* 设置管理员回调
*
* @param account
*/
void onUpdateMemberManager(String account, boolean isRemoveManager);
void addMemberBlack();
}
}

View File

@@ -0,0 +1,98 @@
package com.chwl.app.avroom.adapter;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.widget.AppCompatImageView;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.netease.nim.uikit.support.glide.GlideApp;
import com.chwl.app.R;
import com.chwl.app.common.widget.CircleImageView;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.room.pk.bean.PKQueuingMicMemberInfo;
import com.chwl.core.room.pk.bean.PKTeamInfo;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.library.utils.ResUtil;
import java.util.List;
/**
* @author jack
* @Description
* @Date 2018/12/14
*/
public class PKMicQueueAdapter extends BaseQuickAdapter<PKQueuingMicMemberInfo, BaseViewHolder> {
public PKMicQueueAdapter(List<PKQueuingMicMemberInfo> list) {
super(R.layout.item_pk_mic_queue_list, list);
}
@Override
protected void convert(BaseViewHolder helper, final PKQueuingMicMemberInfo item) {
helper.setText(R.id.tv_userName, item.getNick())
.setText(R.id.tv_no, (helper.getAdapterPosition() + 1) + "");
CircleImageView ivAvatar = helper.getView(R.id.iv_avatar_view);
GlideApp.with(ivAvatar.getContext())
.load(item.getAvatar())
.placeholder(R.drawable.default_avatar)
.into(ivAvatar);
AppCompatImageView ivGender = helper.getView(R.id.iv_gender);
if (item.getGender() == UserInfo.GENDER_MALE) {
ivGender.setImageResource(R.drawable.ic_gender_male);
} else {
ivGender.setImageResource(R.drawable.ic_gender_female);
}
TextView tvOpt = helper.getView(R.id.tv_opt);
tvOpt.setTextColor(mContext.getResources().getColor(R.color.color_FFFFFF));
if (AvRoomDataManager.get().isManager()) {
if (item.getGroupType() == PKTeamInfo.TEAM_RED) {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_pkmicqueueadapter_01));
tvOpt.setBackgroundResource(R.drawable.shape_pk_join_red_team_mark);
} else if (item.getGroupType() == PKTeamInfo.TEAM_BLUE) {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_pkmicqueueadapter_02));
tvOpt.setBackgroundResource(R.drawable.shape_pk_join_blue_team_mark);
} else {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_pkmicqueueadapter_03));
tvOpt.setBackgroundResource(R.drawable.shape_bg_add_attention);
}
final int itemPos = helper.getAdapterPosition();
tvOpt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onUpMicListener != null) {
onUpMicListener.onUpMic(item, itemPos);
}
}
});
} else {
if (item.getGroupType() == PKTeamInfo.TEAM_RED) {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_pkmicqueueadapter_04));
tvOpt.setBackgroundResource(R.drawable.shape_pk_join_red_team_mark);
} else if (item.getGroupType() == PKTeamInfo.TEAM_BLUE) {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_pkmicqueueadapter_05));
tvOpt.setBackgroundResource(R.drawable.shape_pk_join_blue_team_mark);
} else {
tvOpt.setText(ResUtil.getString(R.string.avroom_adapter_pkmicqueueadapter_06));
tvOpt.setBackgroundResource(R.drawable.shape_bg_add_attention);
}
tvOpt.setOnClickListener(null);
}
}
public interface OnUpMicListener {
void onUpMic(PKQueuingMicMemberInfo memeberInfo, int itemPos);
}
private OnUpMicListener onUpMicListener;
public void setOnUpMicListener(OnUpMicListener onUpMicListener) {
this.onUpMicListener = onUpMicListener;
}
}

View File

@@ -0,0 +1,78 @@
package com.chwl.app.avroom.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.core.bean.RoomQueueInfo;
/**
* @author xiaoyu
* @date 2017/12/18
*/
public class PartyMicroViewAdapter extends BaseMicroViewAdapter {
public PartyMicroViewAdapter(Context context) {
super(context);
}
/**
* Set LayoutManager and bind this to RecyclerView
*/
@Override
public void bindToRecyclerView(RecyclerView recyclerView) {
GridLayoutManager layoutManager = new GridLayoutManager(context, 5);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(this);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View item;
item = LayoutInflater.from(parent.getContext()).
inflate(R.layout.list_item_micro, parent, false);
return new MicroViewHolder(item);
}
@Override
public String microType() {
return BaseMicroViewAdapter.MICRO_TYPE_PARTY;
}
@Override
public int getItemViewType(int position) {
return TYPE_NORMAL;
}
@Override
public int getItemCount() {
return 10;
}
class MicroViewHolder extends GiftValueViewHolder {
MicroViewHolder(View itemView) {
super(itemView);
}
@Override
public void bind(RoomQueueInfo info, int position) {
super.bind(info, position);
// ivUpImage.setImageResource(R.drawable.icon_room_up_micro);
}
@SuppressLint("SetTextI18n")
@Override
public void setDefalutText(int index) {
super.setDefalutText(index);
}
}
}

View File

@@ -0,0 +1,153 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chwl.app.R;
import com.chwl.core.room.pk.bean.PKRecordInfo;
import com.chwl.core.room.pk.bean.PKTeamInfo;
import com.chwl.core.room.pk.bean.PKTeamMember;
import com.chwl.core.room.pk.bean.RoomPkData;
import com.chwl.library.utils.FormatUtils;
import com.chwl.library.utils.ResUtil;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author jack
* @Description
* @Date 2018/12/29
*/
public class RecordForPKAdapter extends BaseQuickAdapter<PKRecordInfo, BaseViewHolder> {
private Context context;
private SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd\nHH:mm:ss");
public RecordForPKAdapter(Context context, @Nullable List<PKRecordInfo> data) {
super(R.layout.item_record_for_pk, data);
this.context = context;
}
@Override
protected void convert(BaseViewHolder helper, PKRecordInfo item) {
if (item.getVoteMode() == RoomPkData.VOTE_MODE_GIFT) {
helper.setText(R.id.tv_pk_type, context.getResources().getString(R.string.vote_type_gift_value));
} else if (item.getVoteMode() == RoomPkData.VOTE_MODE_PERSON) {
helper.setText(R.id.tv_pk_type, context.getResources().getString(R.string.vote_type_gift_member));
}
helper.setText(R.id.tv_time, formater.format(new Date(item.getBeginTime())));
LinearLayout llRedTeamMembers = (LinearLayout) helper.getView(R.id.ll_red_team_members);
LinearLayout llBlueTeamMembers = (LinearLayout) helper.getView(R.id.ll_blue_team_members);
TextView tvRedTeamScore = (TextView) helper.getView(R.id.tv_red_team_score);
TextView tvRedTeamResult = (TextView) helper.getView(R.id.tv_red_team_result);
TextView tvBlueTeamScore = (TextView) helper.getView(R.id.tv_blue_team_score);
TextView tvBlueTeamResult = (TextView) helper.getView(R.id.tv_blue_team_result);
GradientDrawable redTeamMembersBackground = (GradientDrawable) llRedTeamMembers.getBackground();
GradientDrawable blueTeamMembersBackground = (GradientDrawable) llBlueTeamMembers.getBackground();
TextView tvRedTeamMember1 = (TextView) helper.getView(R.id.tv_red_team_member_1);
TextView tvRedTeamMember3 = (TextView) helper.getView(R.id.tv_red_team_member_3);
TextView tvRedTeamMember2 = (TextView) helper.getView(R.id.tv_red_team_member_2);
TextView tvRedTeamMember4 = (TextView) helper.getView(R.id.tv_red_team_member_4);
TextView tvBlueTeamMember1 = (TextView) helper.getView(R.id.tv_blue_team_member_1);
TextView tvBlueTeamMember3 = (TextView) helper.getView(R.id.tv_blue_team_member_3);
TextView tvBlueTeamMember2 = (TextView) helper.getView(R.id.tv_blue_team_member_2);
TextView tvBlueTeamMember4 = (TextView) helper.getView(R.id.tv_blue_team_member_4);
List<TextView> redTeamMemberViews = new ArrayList<>();
redTeamMemberViews.add(tvRedTeamMember1);
redTeamMemberViews.add(tvRedTeamMember2);
redTeamMemberViews.add(tvRedTeamMember3);
redTeamMemberViews.add(tvRedTeamMember4);
List<TextView> blueTeamMemberViews = new ArrayList<>();
blueTeamMemberViews.add(tvBlueTeamMember1);
blueTeamMemberViews.add(tvBlueTeamMember2);
blueTeamMemberViews.add(tvBlueTeamMember3);
blueTeamMemberViews.add(tvBlueTeamMember4);
PKTeamInfo teamRed = findPKTeam(PKTeamInfo.TEAM_RED, item.getTeams());
PKTeamInfo teamBlue = findPKTeam(PKTeamInfo.TEAM_BLUE, item.getTeams());
if (teamRed != null) {
tvRedTeamScore.setText(FormatUtils.formatPKValue(teamRed.getScore()));
for (int i = 0; i < redTeamMemberViews.size(); i++) {
if (i < teamRed.getTeamMembers().size()) {
PKTeamMember pkTeamMember = teamRed.getTeamMembers().get(i);
redTeamMemberViews.get(i).setVisibility(View.VISIBLE);
redTeamMemberViews.get(i).setText(pkTeamMember.getNick());
} else {
redTeamMemberViews.get(i).setVisibility(View.GONE);
}
}
}
if (teamBlue != null) {
tvBlueTeamScore.setText(FormatUtils.formatPKValue(teamBlue.getScore()));
for (int i = 0; i < blueTeamMemberViews.size(); i++) {
if (i < teamBlue.getTeamMembers().size()) {
PKTeamMember pkTeamMember = teamBlue.getTeamMembers().get(i);
blueTeamMemberViews.get(i).setVisibility(View.VISIBLE);
blueTeamMemberViews.get(i).setText(pkTeamMember.getNick());
} else {
blueTeamMemberViews.get(i).setVisibility(View.GONE);
}
}
}
if (PKTeamInfo.TEAM_RED == item.getResult()) {
redTeamMembersBackground.setColor(context.getResources().getColor(R.color.color_FD4D72));
blueTeamMembersBackground.setColor(context.getResources().getColor(R.color.color_CCCCCC));
tvRedTeamResult.setText(ResUtil.getString(R.string.avroom_adapter_recordforpkadapter_01));
tvRedTeamResult.setBackgroundResource(R.drawable.bg_pk_record_red_team);
tvBlueTeamResult.setText(ResUtil.getString(R.string.avroom_adapter_recordforpkadapter_02));
tvBlueTeamResult.setBackgroundResource(R.drawable.bg_pk_record_loser);
} else if (PKTeamInfo.TEAM_BLUE == item.getResult()) {
redTeamMembersBackground.setColor(context.getResources().getColor(R.color.color_CCCCCC));
blueTeamMembersBackground.setColor(context.getResources().getColor(R.color.color_3B74FE));
tvRedTeamResult.setText(ResUtil.getString(R.string.avroom_adapter_recordforpkadapter_03));
tvRedTeamResult.setBackgroundResource(R.drawable.bg_pk_record_loser);
tvBlueTeamResult.setText(ResUtil.getString(R.string.avroom_adapter_recordforpkadapter_04));
tvBlueTeamResult.setBackgroundResource(R.drawable.bg_pk_record_blue_team);
} else if (RoomPkData.PK_RESULT_DRAW == item.getResult()) {
redTeamMembersBackground.setColor(context.getResources().getColor(R.color.color_CCCCCC));
blueTeamMembersBackground.setColor(context.getResources().getColor(R.color.color_CCCCCC));
tvRedTeamResult.setText(ResUtil.getString(R.string.avroom_adapter_recordforpkadapter_05));
tvRedTeamResult.setBackgroundResource(R.drawable.bg_pk_record_loser);
tvBlueTeamResult.setText(ResUtil.getString(R.string.avroom_adapter_recordforpkadapter_06));
tvBlueTeamResult.setBackgroundResource(R.drawable.bg_pk_record_loser);
} else {
redTeamMembersBackground.setColor(context.getResources().getColor(R.color.color_CCCCCC));
blueTeamMembersBackground.setColor(context.getResources().getColor(R.color.color_CCCCCC));
tvRedTeamResult.setText(ResUtil.getString(R.string.avroom_adapter_recordforpkadapter_07));
tvRedTeamResult.setBackgroundResource(R.drawable.bg_pk_record_loser);
tvBlueTeamResult.setText(ResUtil.getString(R.string.avroom_adapter_recordforpkadapter_08));
tvBlueTeamResult.setBackgroundResource(R.drawable.bg_pk_record_loser);
}
}
private PKTeamInfo findPKTeam(int teamMark, List<PKTeamInfo> pkTeamInfoList) {
for (PKTeamInfo pkTeamInfo : pkTeamInfoList) {
if (teamMark == pkTeamInfo.getTeam()) {
return pkTeamInfo;
}
}
return null;
}
}

View File

@@ -0,0 +1,78 @@
package com.chwl.app.avroom.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.core.bean.RoomQueueInfo;
/**
* @author xiaoyu
* @date 2017/12/18
*/
public class RevelryMicroViewAdapter extends BaseMicroViewAdapter {
public RevelryMicroViewAdapter(Context context) {
super(context);
}
/**
* Set LayoutManager and bind this to RecyclerView
*/
@Override
public void bindToRecyclerView(RecyclerView recyclerView) {
GridLayoutManager layoutManager = new GridLayoutManager(context, 5);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(this);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View item;
item = LayoutInflater.from(parent.getContext()).
inflate(R.layout.list_item_micro, parent, false);
return new MicroViewHolder(item);
}
@Override
public String microType() {
return BaseMicroViewAdapter.MICRO_TYPE_REVELRY;
}
@Override
public int getItemViewType(int position) {
return TYPE_NORMAL;
}
@Override
public int getItemCount() {
return 15;
}
class MicroViewHolder extends GiftValueViewHolder {
MicroViewHolder(View itemView) {
super(itemView);
}
@Override
public void bind(RoomQueueInfo info, int position) {
super.bind(info, position);
// ivUpImage.setImageResource(R.drawable.icon_room_up_micro);
}
@SuppressLint("SetTextI18n")
@Override
public void setDefalutText(int index) {
super.setDefalutText(index);
}
}
}

View File

@@ -0,0 +1,45 @@
package com.chwl.app.avroom.adapter
import android.graphics.drawable.Drawable
import android.view.View
import android.widget.ImageView
import androidx.core.view.isVisible
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.chwl.app.R
import com.chwl.app.ui.utils.load
class RoomBgAdapter : BaseQuickAdapter<String, BaseViewHolder>(R.layout.room_bg_setting_item) {
private var selectItem: String? = null
override fun convertPayloads(
helper: BaseViewHolder,
item: String?,
payloads: MutableList<Any>
) {
super.convertPayloads(helper, item, payloads)
convertStatus(helper, item)
}
override fun convert(helper: BaseViewHolder, item: String?) {
val imageView = helper.getView<ImageView>(R.id.iv_image)
imageView.load(item)
convertStatus(helper, item)
}
private fun convertStatus(helper: BaseViewHolder, item: String?) {
val statusView = helper.getView<View>(R.id.tv_status)
statusView.isVisible = item == selectItem
}
fun getSelectItem() = selectItem
fun selectItem(url: String?) {
selectItem = url
notifyItemRangeChanged(0, itemCount, true)
}
}

View File

@@ -0,0 +1,36 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import com.chwl.app.R;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
/**
* 右滑操作的,写了暂时不用
* Created by lvzebiao
*/
public class RoomBlackListAdapter extends BaseQuickAdapter<ChatRoomMember, BaseViewHolder>{
private Context context;
private int itemWidth;
public RoomBlackListAdapter(Context context) {
super(R.layout.list_item_room_black);
this.context = context;
itemWidth = UIUtil.getScreenWidth(context);
}
@Override
protected void convert(BaseViewHolder helper, ChatRoomMember chatRoomMember) {
helper.setText(R.id.nick, chatRoomMember.getNick());
ImageLoadUtils.loadAvatar(context, chatRoomMember.getAvatar(), helper.getView(R.id.avatar));
helper.getView(R.id.layout_item).getLayoutParams().width = itemWidth;
}
}

View File

@@ -0,0 +1,196 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.appcompat.widget.AppCompatImageView;
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chwl.app.R;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.app.ui.widget.NobleAvatarView;
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import com.chwl.app.utils.RegexUtil;
import com.chwl.core.noble.bean.NobleInfo;
import com.chwl.core.noble.NobleUtil;
import com.chwl.core.room.bean.RoomContributeUserInfo;
import com.chwl.core.room.bean.RoomRankMultiItem;
import com.chwl.library.utils.ResUtil;
import java.math.BigDecimal;
import java.util.ArrayList;
/**
* <p>房间消费adapter </p>
*
* @author Administrator
* @date 2017/11/20
*/
public class RoomConsumeListAdapter extends BaseMultiItemQuickAdapter<RoomContributeUserInfo, BaseViewHolder> {
private Context context;
public RoomConsumeListAdapter(Context context) {
super(new ArrayList<>());
this.context = context;
addItemType(RoomContributeUserInfo.TYPE_GRID, R.layout.list_item_room_consume_first);
addItemType(RoomRankMultiItem.TYPE_LINEAR, R.layout.list_item_room_consume);
}
@Override
protected void convert(BaseViewHolder baseViewHolder, RoomContributeUserInfo roomConsumeInfo) {
if (roomConsumeInfo == null) {
return;
}
if (roomConsumeInfo.getItemType() == RoomRankMultiItem.TYPE_LINEAR) {
setLinearData(baseViewHolder, roomConsumeInfo);
} else {
setGridData(baseViewHolder, roomConsumeInfo);
}
}
private void setGridData(BaseViewHolder baseViewHolder, RoomContributeUserInfo roomConsumeInfo) {
RelativeLayout avatarContainer = baseViewHolder.getView(R.id.avatar_container);
int position = baseViewHolder.getLayoutPosition();
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) avatarContainer.getLayoutParams();
ImageView ivAvatar = baseViewHolder.getView(R.id.iv_avatar);
ViewGroup.LayoutParams avatarParams = ivAvatar.getLayoutParams();
RelativeLayout.LayoutParams nickLayoutParams = (RelativeLayout.LayoutParams)
baseViewHolder.getView(R.id.nick_layout).getLayoutParams();
if (position == 0) { //排行榜第二名
params.topMargin = UIUtil.dip2px(context, 33);
params.width = params.height = UIUtil.dip2px(context, 90);
avatarParams.width = avatarParams.height = UIUtil.dip2px(context, 58);
nickLayoutParams.topMargin = UIUtil.dip2px(context, 118);
} else if (position == 1) {//排行榜第一名
params.topMargin = 0;
params.width = params.height = UIUtil.dip2px(context, 110);
avatarParams.width = avatarParams.height = UIUtil.dip2px(context, 71);
nickLayoutParams.topMargin = UIUtil.dip2px(context, 105);
} else {//排行榜第三名
params.topMargin = UIUtil.dip2px(context, 26);
params.width = params.height = UIUtil.dip2px(context, 90);
avatarParams.width = avatarParams.height = UIUtil.dip2px(context, 58);
nickLayoutParams.topMargin = UIUtil.dip2px(context, 111);
}
ImageView ivRankIcon = baseViewHolder.getView(R.id.iv_rank_icon);
int emptyPic;
//虚位以待,没数据展示,隐藏相关即可
baseViewHolder.setVisible(R.id.tv_nick, !roomConsumeInfo.isEmptyBean())
.setVisible(R.id.tv_erban_id, !roomConsumeInfo.isEmptyBean())
.setVisible(R.id.coin_text, !roomConsumeInfo.isEmptyBean())
.setVisible(R.id.tv_empty_text, roomConsumeInfo.isEmptyBean());
if (roomConsumeInfo.isEmptyBean()) {
if (position == 0) {
emptyPic = R.drawable.icon_consume_second_empty;
} else if (position == 1) {
emptyPic = R.drawable.icon_consume_first_empty;
} else {
emptyPic = R.drawable.icon_consume_third_empty;
}
ivAvatar.setVisibility(View.GONE);
ivRankIcon.setImageResource(emptyPic);
} else {
if (position == 0) {
emptyPic = R.drawable.icon_consume_second;
} else if (position == 1) {
emptyPic = R.drawable.icon_consume_first;
} else {
emptyPic = R.drawable.icon_consume_third;
}
ivAvatar.setVisibility(View.VISIBLE);
if (roomConsumeInfo.isHide()) {
ImageLoadUtils.loadAvatarBig(context.getResources().getString(R.string.url_mystery_man), ivAvatar);
} else {
ImageLoadUtils.loadAvatarBig(roomConsumeInfo.getAvatar(), ivAvatar);
}
ivRankIcon.setImageResource(emptyPic);
setCommonView(baseViewHolder, roomConsumeInfo);
}
}
private void setLinearData(BaseViewHolder baseViewHolder, RoomContributeUserInfo roomConsumeInfo) {
NobleAvatarView nobleAvatarView = baseViewHolder.getView(R.id.noble_avatar_view);
nobleAvatarView.setSize(45, 66, 14);
NobleInfo nobleInfo = new NobleInfo();
nobleInfo.setBadge(roomConsumeInfo.getBadge());
nobleInfo.setHeadWear(roomConsumeInfo.getMicDecorate());
if (roomConsumeInfo.isHide()) {
nobleAvatarView.setData(context.getResources().getString(R.string.url_mystery_man), nobleInfo);
} else {
nobleAvatarView.setData(roomConsumeInfo.getAvatar(), nobleInfo);
}
AppCompatImageView ivNobleLevel = baseViewHolder.getView(R.id.iv_noble_level);
ivNobleLevel.setVisibility(View.GONE);
String nobleBadge;
if (!TextUtils.isEmpty((nobleBadge = roomConsumeInfo.getBadge()))) {
ivNobleLevel.setVisibility(View.VISIBLE);
NobleUtil.loadResource(nobleBadge, ivNobleLevel);
}
AppCompatImageView ivUserLevel = baseViewHolder.getView(R.id.iv_user_level);
ivUserLevel.setVisibility(View.GONE);
if (!TextUtils.isEmpty(roomConsumeInfo.getExperUrl())) {
ivUserLevel.setVisibility(View.VISIBLE);
ImageLoadUtils.loadImage(mContext, roomConsumeInfo.getExperUrl(), ivUserLevel);
}
TextView numberText = baseViewHolder.getView(R.id.auction_number_text);
ImageView numberImage = baseViewHolder.getView(R.id.auction_number_image);
int position = baseViewHolder.getLayoutPosition();
if (position <= 2) {
numberText.setVisibility(View.INVISIBLE);
numberImage.setVisibility(View.VISIBLE);
if (position == 0) {
numberImage.setImageResource(R.drawable.icon_auction_week_list_first);
} else if (position == 1) {
numberImage.setImageResource(R.drawable.icon_auction_week_list_second);
} else {
numberImage.setImageResource(R.drawable.icon_auction_week_list_third);
}
} else {
numberText.setVisibility(View.VISIBLE);
numberImage.setVisibility(View.GONE);
numberText.setText(mContext.getString(R.string.consume_position, (position + 1)));
}
setCommonView(baseViewHolder, roomConsumeInfo);
}
/**
* 设置共同的部分
*/
private void setCommonView(BaseViewHolder baseViewHolder, RoomContributeUserInfo roomConsumeInfo) {
String goldAmount;
if (roomConsumeInfo.getGoldAmount() >= 10000) {
BigDecimal b = new BigDecimal(roomConsumeInfo.getGoldAmount() / 10000.0);
double df = b.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
goldAmount = String.valueOf(df) + ResUtil.getString(R.string.avroom_adapter_roomconsumelistadapter_01);
} else {
goldAmount = String.valueOf(roomConsumeInfo.getGoldAmount());
}
baseViewHolder.setText(R.id.tv_erban_id, roomConsumeInfo.isHide() ? "****" : "ID:" + roomConsumeInfo.getErbanNo())
.setImageResource(R.id.iv_sex,
roomConsumeInfo.getGender() == 1 ? R.drawable.ic_gender_male : R.drawable.ic_gender_female)
.setText(R.id.coin_text, goldAmount)
.setText(R.id.tv_nick, roomConsumeInfo.isHide() ?
context.getResources().getString(R.string.mystery_man)
: RegexUtil.getPrintableString(roomConsumeInfo.getNick()));
}
}

View File

@@ -0,0 +1,205 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.appcompat.widget.AppCompatImageView;
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chwl.app.R;
import com.chwl.app.common.widget.CircleImageView;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.app.utils.RegexUtil;
import com.chwl.core.room.bean.RoomContributeUserInfo;
import com.chwl.core.room.bean.RoomRankMultiItem;
import java.util.ArrayList;
public class RoomConsumerListAdapterTemp extends BaseMultiItemQuickAdapter<RoomRankMultiItem, BaseViewHolder> {
public final static int TYPE_EMPTY = 3;
private RoomConsumerTopThreeListener mRoomConsumerTopThreeListener;
public RoomConsumerListAdapterTemp(Context context) {
super(new ArrayList<>());
addItemType(RoomContributeUserInfo.TYPE_GRID, R.layout.layout_room_rank_top_three);
addItemType(RoomRankMultiItem.TYPE_LINEAR, R.layout.list_item_room_consume);
addItemType(TYPE_EMPTY, R.layout.item_empty_list);
}
public void setmRoomConsumerTopThreeListener(RoomConsumerTopThreeListener mRoomConsumerTopThreeListener) {
this.mRoomConsumerTopThreeListener = mRoomConsumerTopThreeListener;
}
@Override
protected void convert(BaseViewHolder baseViewHolder, RoomRankMultiItem roomConsumeInfo) {
if (roomConsumeInfo == null) {
return;
}
if (roomConsumeInfo.getItemType() == RoomRankMultiItem.TYPE_LINEAR) {
setLinearData(baseViewHolder, roomConsumeInfo);
} else if (roomConsumeInfo.getItemType() == TYPE_EMPTY) {
} else {
setGridView(baseViewHolder, roomConsumeInfo);
}
}
private void setGridView(BaseViewHolder baseViewHolder, RoomRankMultiItem roomRankMultiItem) {
ArrayList<RoomContributeUserInfo> data = (ArrayList<RoomContributeUserInfo>) roomRankMultiItem.getData();
View root = baseViewHolder.itemView;
RelativeLayout rlTopOne = root.findViewById(R.id.layout_room_rank_top_1);
CircleImageView ciTopOne = root.findViewById(R.id.iv_room_rank_top_1_avatar);
ImageView ivGenderOne = root.findViewById(R.id.iv_room_rank_gender_one);
ImageView ivBgOne = root.findViewById(R.id.iv_room_rank_top_1_avatar_default);
TextView tvOneId = root.findViewById(R.id.tv_number_one_id);
TextView tvLabelOne = root.findViewById(R.id.tv_label_no_1);
TextView tvOneName = root.findViewById(R.id.tv_label_number_one);
RelativeLayout rlTopTwo = root.findViewById(R.id.layout_room_rank_top_2);
CircleImageView ciTopTwo = root.findViewById(R.id.iv_room_rank_top_2_avatar);
ImageView ivGenderTwo = root.findViewById(R.id.iv_room_rank_gender_two);
ImageView ivBgTwo = root.findViewById(R.id.iv_room_rank_top_2_avatar_default);
TextView tvTwoId = root.findViewById(R.id.tv_number_two_id);
TextView tvLabelTwo = root.findViewById(R.id.tv_two_to_last);
TextView tvTwoName = root.findViewById(R.id.tv_label_number_two);
RelativeLayout rlTopThree = root.findViewById(R.id.layout_room_rank_top_3);
CircleImageView ciTopThree = root.findViewById(R.id.iv_room_rank_top_3_avatar);
ImageView ivGenderThree = root.findViewById(R.id.iv_room_rank_gender_three);
ImageView ivBgThree = root.findViewById(R.id.iv_room_rank_top_3_avatar_default);
TextView tvThreeId = root.findViewById(R.id.tv_number_three_id);
TextView tvLabelThree = root.findViewById(R.id.tv_three_to_last);
TextView tvThreeName = root.findViewById(R.id.tv_label_number_three);
if (data != null) {
for (int i = 0; i < data.size(); i++) {
RoomContributeUserInfo userInfo = data.get(i);
if (userInfo != null) {
// 无数据状态需要展示 虚位以待
boolean isEmptyBean = userInfo.isEmptyBean();
if (i == 0) {
if (!TextUtils.isEmpty(userInfo.getAvatar()))
ImageLoadUtils.loadAvatarBig(userInfo.getAvatar(), ciTopOne);
ivGenderOne.setVisibility(isEmptyBean ? View.GONE : View.VISIBLE);
ivGenderOne.setImageResource(userInfo.getGender() == 1 ? R.drawable.ic_gender_male : R.drawable.ic_gender_female);
ciTopOne.setVisibility(isEmptyBean ? View.GONE : View.VISIBLE);
tvLabelOne.setText(isEmptyBean ? "" : String.valueOf(userInfo.getGoldAmount()));
ivBgOne.setImageResource(isEmptyBean ? R.drawable.icon_consume_first_empty : R.drawable.icon_consume_first);
tvOneId.setText(isEmptyBean? "" : "ID:" + userInfo.getErbanNo());
tvOneName.setText(isEmptyBean ? "" : userInfo.getNick());
rlTopOne.setOnClickListener(isEmptyBean ? null : new View.OnClickListener() {
@Override
public void onClick(View v) {
if (userInfo.isHide()) return;
if (userInfo.isEmptyBean()) return;
if (mRoomConsumerTopThreeListener != null)
mRoomConsumerTopThreeListener.topThreeListener(userInfo.getUid());
}
});
} else if (i == 1) {
if (!TextUtils.isEmpty(userInfo.getAvatar()))
ImageLoadUtils.loadAvatarBig(userInfo.getAvatar(), ciTopTwo);
ivGenderTwo.setVisibility(isEmptyBean ? View.GONE : View.VISIBLE);
ivGenderTwo.setImageResource(userInfo.getGender() == 1 ? R.drawable.ic_gender_male : R.drawable.ic_gender_female);
ciTopTwo.setVisibility(isEmptyBean ? View.GONE : View.VISIBLE);
tvLabelTwo.setVisibility(isEmptyBean ? View.GONE : View.VISIBLE);
ivBgTwo.setImageResource(isEmptyBean ? R.drawable.icon_consume_second_empty : R.drawable.icon_consume_second);
tvTwoId.setText(isEmptyBean ? "" : "ID:" + userInfo.getErbanNo());
tvTwoName.setText(isEmptyBean ? "" : userInfo.getNick());
tvLabelTwo.setText(String.valueOf(userInfo.getGoldAmount()));// RoomRankDialogUtils.getRoomRankValueText(userInfo.getGoldAmount())
rlTopTwo.setOnClickListener(isEmptyBean ? null : new View.OnClickListener() {
@Override
public void onClick(View v) {
if (userInfo.isHide()) return;
if (userInfo.isEmptyBean()) return;
if (mRoomConsumerTopThreeListener != null)
mRoomConsumerTopThreeListener.topThreeListener(userInfo.getUid());
}
});
} else if (i == 2) {
if (!TextUtils.isEmpty(userInfo.getAvatar()))
ImageLoadUtils.loadAvatarBig(userInfo.getAvatar(), ciTopThree);
ivGenderThree.setVisibility(isEmptyBean ? View.GONE : View.VISIBLE);
ivGenderThree.setImageResource(userInfo.getGender() == 1 ? R.drawable.ic_gender_male : R.drawable.ic_gender_female);
ciTopThree.setVisibility(isEmptyBean ? View.GONE : View.VISIBLE);
tvLabelThree.setVisibility(isEmptyBean ? View.GONE : View.VISIBLE);
ivBgThree.setImageResource(isEmptyBean ? R.drawable.icon_consume_third_empty : R.drawable.icon_consume_third);
tvThreeId.setText(isEmptyBean ? "" : "ID:" + userInfo.getErbanNo());
tvThreeName.setText(isEmptyBean ? "" : userInfo.getNick());
tvLabelThree.setText(String.valueOf(userInfo.getGoldAmount()));
rlTopThree.setOnClickListener(isEmptyBean ? null : new View.OnClickListener() {
@Override
public void onClick(View v) {
if (userInfo.isHide()) return;
if (userInfo.isEmptyBean()) return;
if (mRoomConsumerTopThreeListener != null)
mRoomConsumerTopThreeListener.topThreeListener(userInfo.getUid());
}
});
}
}
}
}
}
private void setLinearData(BaseViewHolder baseViewHolder, RoomRankMultiItem roomConsumeInfo) {
RoomContributeUserInfo roomContributeUserInfo = (RoomContributeUserInfo) roomConsumeInfo.getData();
CircleImageView avatarView = baseViewHolder.getView(R.id.avatar_view);
ImageLoadUtils.loadAvatar(mContext, roomContributeUserInfo.getAvatar(), avatarView);
AppCompatImageView ivNobleLevel = baseViewHolder.getView(R.id.iv_noble_level);
ivNobleLevel.setVisibility(View.GONE);
AppCompatImageView ivUserLevel = baseViewHolder.getView(R.id.iv_user_level);
ivUserLevel.setVisibility(View.GONE);
ImageView numberImage = baseViewHolder.getView(R.id.auction_number_image);
numberImage.setVisibility(View.GONE);
baseViewHolder.setText(R.id.auction_number_text,roomContributeUserInfo.getRanking()+"");
baseViewHolder.setGone(R.id.iv_number,true);
setCommonView(baseViewHolder, roomContributeUserInfo);
}
/**
* 设置共同的部分
*/
private void setCommonView(BaseViewHolder baseViewHolder, RoomContributeUserInfo roomConsumeInfo) {
String goldAmount = String.valueOf(roomConsumeInfo.getGoldAmount());
baseViewHolder.setText(R.id.tv_erban_id, "ID:" + roomConsumeInfo.getErbanNo())
.setImageResource(R.id.iv_sex,
roomConsumeInfo.getGender() == 1 ? R.drawable.ic_gender_male : R.drawable.ic_gender_female)
.setText(R.id.coin_text, goldAmount)
.setText(R.id.tv_nick, RegexUtil.getPrintableString(roomConsumeInfo.getNick()));
}
public interface RoomConsumerTopThreeListener {
void topThreeListener(long uid);
}
}

View File

@@ -0,0 +1,35 @@
package com.chwl.app.avroom.adapter;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import java.util.List;
/**
* Created by MadisonRong on 25/04/2018.
*/
public class RoomContributeListAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList;
public RoomContributeListAdapter(FragmentManager fm, List<Fragment> fragmentList) {
super(fm);
this.fragmentList = fragmentList;
}
public RoomContributeListAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
}

View File

@@ -0,0 +1,18 @@
package com.chwl.app.avroom.adapter
import android.widget.ImageView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.chwl.app.R
import com.chwl.app.ui.utils.load
import com.chwl.core.room.bean.RoomIcon
import com.chwl.core.room.game.bean.GameInfo
class RoomGameListAdapter :
BaseQuickAdapter<GameInfo, BaseViewHolder>(R.layout.room_gameplay_item2) {
override fun convert(helper: BaseViewHolder, item: GameInfo?) {
helper.setText(R.id.tv_name, item?.name?:"")
val iconView = helper.getView<ImageView>(R.id.iv_icon)
iconView.load(item?.pic2?:"")
}
}

View File

@@ -0,0 +1,23 @@
package com.chwl.app.avroom.adapter
import android.widget.ImageView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.BaseViewHolder
import com.chwl.app.R
import com.chwl.app.avroom.bean.RoomGameplayItem
import com.chwl.app.ui.utils.load
class RoomGameplayAdapter :
BaseQuickAdapter<RoomGameplayItem, BaseViewHolder>(R.layout.room_gameplay_item2) {
override fun convert(helper: BaseViewHolder, item: RoomGameplayItem?) {
helper.setText(R.id.tv_name, item?.getName())
val iconView = helper.getView<ImageView>(R.id.iv_icon)
val iconRes = item?.getIconRes()
if (iconRes != null) {
iconView.setImageResource(iconRes)
} else {
val iconUrl = item?.getIconUrl()
iconView.load(iconUrl ?: "")
}
}
}

View File

@@ -0,0 +1,246 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.app.avroom.ChatMemberDiffUtilCallback;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.core.manager.AvRoomDataManager;
import com.chwl.core.manager.IMNetEaseManager;
import com.chwl.core.manager.RoomEvent;
import com.chwl.core.user.bean.UserInfo;
import com.chwl.library.common.util.OtherExtKt;
import com.chwl.library.utils.ListUtils;
import com.netease.nim.uikit.impl.cache.NimUserInfoCache;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import com.netease.nimlib.sdk.uinfo.constant.GenderEnum;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
/**
* <p> </p>
*
* @author jiahui
* @date 2017/12/21
*/
public class RoomInviteAdapter extends RecyclerView.Adapter<RoomInviteAdapter.RoomInviteViewHolder> {
private List<ChatRoomMember> mChatRoomMemberList;
private Context mContext;
private OnItemClickListener mOnItemClickListener;
private LayoutInflater mInflater;
private Disposable mDisposable;
public RoomInviteAdapter(Context context, OnItemClickListener onItemClickListener) {
mInflater = LayoutInflater.from(context);
mContext = context;
mOnItemClickListener = onItemClickListener;
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
mDisposable = IMNetEaseManager.get().getChatRoomEventObservable()
.subscribe(new Consumer<RoomEvent>() {
@Override
public void accept(RoomEvent roomEvent) throws Exception {
if (roomEvent == null) return;
int event = roomEvent.getEvent();
if (roomEvent.getEvent() == RoomEvent.ADD_BLACK_LIST ||
roomEvent.getEvent() == RoomEvent.DOWN_MIC ||
event == RoomEvent.ROOM_MEMBER_EXIT ||
roomEvent.getEvent() == RoomEvent.KICK_OUT_ROOM) {
if (ListUtils.isListEmpty(mChatRoomMemberList)) return;
ListIterator<ChatRoomMember> iterator = mChatRoomMemberList.listIterator();
for (; iterator.hasNext(); ) {
ChatRoomMember onlineChatMember = iterator.next();
if (onlineChatMember != null
&& Objects.equals(onlineChatMember.getAccount(), roomEvent.getAccount())) {
iterator.remove();
}
}
notifyDataSetChanged();
if (mOnRoomOnlineNumberChangeListener != null)
mOnRoomOnlineNumberChangeListener.onRoomOnlineNumberChange(getItemCount());
} else if (event == RoomEvent.ROOM_MEMBER_IN) {
updateMemberIn(roomEvent);
}
}
});
}
public void onRelease() {
if (mDisposable != null) {
mDisposable.dispose();
mDisposable = null;
}
}
private void updateMemberIn(RoomEvent roomEvent) {
ChatRoomMember chatRoomMember = AvRoomDataManager.get().getChatRoomMember(roomEvent.getAccount());
if (chatRoomMember == null) return;
if (!ListUtils.isListEmpty(mChatRoomMemberList)) {
for (ChatRoomMember temp : mChatRoomMemberList) {
if (Objects.equals(temp.getAccount(), chatRoomMember.getAccount()))
return;
}
}
List<ChatRoomMember> list = new ArrayList<>(1);
list.add(chatRoomMember);
addChatRoomMemberList(list);
if (mOnRoomOnlineNumberChangeListener != null)
mOnRoomOnlineNumberChangeListener.onRoomOnlineNumberChange(getItemCount());
}
public void addChatRoomMemberList(final List<ChatRoomMember> chatRoomMemberList) {
if (ListUtils.isListEmpty(mChatRoomMemberList)) {
mChatRoomMemberList = chatRoomMemberList;
notifyDataSetChanged();
} else {
mChatRoomMemberList.addAll(chatRoomMemberList);
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(
new ChatMemberDiffUtilCallback(mChatRoomMemberList, chatRoomMemberList), true);
diffResult.dispatchUpdatesTo(this);
}
}
public List<ChatRoomMember> getChatRoomMemberList() {
return mChatRoomMemberList;
}
@Override
public RoomInviteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new RoomInviteViewHolder(mInflater.inflate(R.layout.room_invite_list_item_layout, parent, false));
}
@Override
public void onBindViewHolder(RoomInviteViewHolder holder, int position) {
final ChatRoomMember chatRoomMember = mChatRoomMemberList.get(position);
if (chatRoomMember == null) return;
NimUserInfo nimUserInfo = NimUserInfoCache.getInstance().getUserInfo(chatRoomMember.getAccount());
final ImageView sexImage = holder.sexImage;
if (nimUserInfo == null) {
NimUserInfoCache.getInstance().getUserInfoFromRemote(chatRoomMember.getAccount(),
new RequestCallbackWrapper<NimUserInfo>() {
@Override
public void onResult(int i, NimUserInfo nimUserInfo, Throwable throwable) {
if (nimUserInfo != null) {
if (nimUserInfo.getGenderEnum() == GenderEnum.MALE) {
sexImage.setVisibility(View.VISIBLE);
sexImage.setImageResource(R.drawable.ic_gender_male);
} else if (nimUserInfo.getGenderEnum() == GenderEnum.FEMALE) {
sexImage.setVisibility(View.VISIBLE);
sexImage.setImageResource(R.drawable.ic_gender_female);
} else {
sexImage.setVisibility(View.GONE);
}
}
}
});
} else {
if (nimUserInfo.getGenderEnum() == GenderEnum.MALE) {
sexImage.setVisibility(View.VISIBLE);
sexImage.setImageResource(R.drawable.ic_gender_male);
} else if (nimUserInfo.getGenderEnum() == GenderEnum.FEMALE) {
sexImage.setVisibility(View.VISIBLE);
sexImage.setImageResource(R.drawable.ic_gender_female);
} else {
sexImage.setVisibility(View.GONE);
}
}
holder.mViewLine.setVisibility(position == getItemCount() - 1 ? View.GONE : View.VISIBLE);
ImageLoadUtils.loadAvatar(mContext, chatRoomMember.getAvatar(), holder.mIvAvatar);
holder.mTvMemberName.setText(chatRoomMember.getNick());
try {
Map<String, Object> map = (Map<String, Object>) chatRoomMember.getExtension().get(chatRoomMember.getAccount());
String nick = map.get(UserInfo.NICK).toString();
String avatar = map.get(UserInfo.AVATAR).toString();
boolean enterHide = (boolean) map.get(UserInfo.ENTER_HIDE);
if (enterHide) {
holder.mIvAvatar.setImageResource(R.drawable.ic_mystery);
} else {
if (chatRoomMember.getAvatar() == null || TextUtils.isEmpty(chatRoomMember.getAvatar())) {
ImageLoadUtils.loadAvatar(mContext, avatar, holder.mIvAvatar);
}
CharSequence nickText = holder.mTvMemberName.getText();
if (!OtherExtKt.isVerify(nickText)){
if (OtherExtKt.isVerify(nick)) {
holder.mTvMemberName.setText(nick);
}
}
}
}catch (Exception e){
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnItemClickListener != null)
mOnItemClickListener.onClick(chatRoomMember);
}
});
}
@Override
public int getItemCount() {
return mChatRoomMemberList != null ? mChatRoomMemberList.size() : 0;
}
static class RoomInviteViewHolder extends RecyclerView.ViewHolder {
private ImageView mIvAvatar;
private ImageView sexImage;
private TextView mTvMemberName;
View mViewLine;
RoomInviteViewHolder(View itemView) {
super(itemView);
mIvAvatar = itemView.findViewById(R.id.iv_avatar);
sexImage = itemView.findViewById(R.id.sex);
mTvMemberName = itemView.findViewById(R.id.tv_member_name);
mViewLine = itemView.findViewById(R.id.view_line);
}
}
public interface OnItemClickListener {
void onClick(ChatRoomMember chatRoomMember);
}
private OnRoomOnlineNumberChangeListener mOnRoomOnlineNumberChangeListener;
public void setOnRoomOnlineNumberChangeListener(OnRoomOnlineNumberChangeListener listener) {
mOnRoomOnlineNumberChangeListener = listener;
}
public interface OnRoomOnlineNumberChangeListener {
void onRoomOnlineNumberChange(int number);
}
}

View File

@@ -0,0 +1,106 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import com.chwl.app.R;
import com.chwl.app.ui.widget.XRecyclerView.ScaleTransitionPagerTitleView;
import com.chwl.app.ui.widget.magicindicator.buildins.UIUtil;
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter;
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.abs.IPagerIndicator;
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.abs.IPagerTitleView;
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.indicators.GradientLineRoundPagerIndicator;
import com.chwl.app.ui.widget.magicindicator.buildins.commonnavigator.indicators.LinePagerIndicator;
import java.util.List;
public class RoomMessageIndicatorAdapter extends CommonNavigatorAdapter {
private final Context mContext;
private final List<? extends CharSequence> mTitleList;
private int textSize = 14;
private float minScale = 1f;
private boolean showIndicator = true;
private OnItemSelectListener mOnItemSelectListener;
public RoomMessageIndicatorAdapter(Context context, List<? extends CharSequence> charSequences) {
this.mContext = context;
this.mTitleList = charSequences;
}
@Override
public int getCount() {
return mTitleList == null ? 0 : mTitleList.size();
}
@Override
public IPagerTitleView getTitleView(Context context, final int i) {
ScaleTransitionPagerTitleView scaleTransitionPagerTitleView = new ScaleTransitionPagerTitleView(context, true);
scaleTransitionPagerTitleView.setNormalColor(ContextCompat.getColor(context, R.color.white_transparent_60));
scaleTransitionPagerTitleView.setSelectedColor(ContextCompat.getColor(context, R.color.color_FFFFFF));
scaleTransitionPagerTitleView.setMinScale(minScale);
scaleTransitionPagerTitleView.setTextSize(textSize);
int padding = UIUtil.dip2px(context, 13);
scaleTransitionPagerTitleView.setPadding(padding, 0, padding, 0);
scaleTransitionPagerTitleView.setText(mTitleList.get(i));
scaleTransitionPagerTitleView.setOnClickListener(view -> {
if (mOnItemSelectListener != null) {
mOnItemSelectListener.onItemSelect(i, scaleTransitionPagerTitleView);
}
});
return scaleTransitionPagerTitleView;
}
@Override
public IPagerIndicator getIndicator(Context context) {
LinePagerIndicator indicator = new LinePagerIndicator(context);
indicator.setMode(LinePagerIndicator.MODE_EXACTLY);
indicator.setLineHeight(UIUtil.dip2px(mContext, 1.5));
indicator.setRoundRadius(UIUtil.dip2px(mContext, 1));
indicator.setLineWidth(UIUtil.dip2px(mContext, 8));
indicator.setColors(context.getResources().getColor(R.color.color_10ECD6));
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
// lp.bottomMargin = mBottomMargin;
indicator.setLayoutParams(lp);
return indicator;
}
public int getTextSize() {
return textSize;
}
public void setTextSize(int textSize) {
this.textSize = textSize;
}
public float getMinScale() {
return minScale;
}
public void setMinScale(float minScale) {
this.minScale = minScale;
}
public boolean isShowIndicator() {
return showIndicator;
}
public void setShowIndicator(boolean showIndicator) {
this.showIndicator = showIndicator;
}
public void setOnItemSelectListener(OnItemSelectListener onItemSelectListener) {
mOnItemSelectListener = onItemSelectListener;
}
public interface OnItemSelectListener {
void onItemSelect(int position, TextView view);
}
}

View File

@@ -0,0 +1,105 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.R;
import com.chwl.app.common.widget.CircleImageView;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.core.user.UserModel;
import com.chwl.library.common.util.OtherExtKt;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import java.util.List;
/**
* Created by chenran on 2017/10/11.
*/
public class RoomNormalListAdapter extends RecyclerView.Adapter<RoomNormalListAdapter.RoomNormalListHolder> implements View.OnClickListener{
private Context context;
private List<ChatRoomMember> normalList;
private OnRoomNormalListOperationClickListener listOperationClickListener;
public RoomNormalListAdapter(Context context) {
this.context = context;
}
public void setNormalList(List<ChatRoomMember> normalList) {
this.normalList = normalList;
}
public List<ChatRoomMember> getNormalList() {
return normalList;
}
public void setListOperationClickListener(OnRoomNormalListOperationClickListener listOperationClickListener) {
this.listOperationClickListener = listOperationClickListener;
}
@Override
public RoomNormalListHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_room_normal, parent, false);
return new RoomNormalListHolder(view);
}
@Override
public void onBindViewHolder(RoomNormalListHolder holder, int position) {
ChatRoomMember chatRoomMember = normalList.get(position);
holder.nick.setText(chatRoomMember.getNick());
holder.operationImg.setTag(chatRoomMember);
holder.operationImg.setOnClickListener(this);
ImageLoadUtils.loadAvatar(context, chatRoomMember.getAvatar(), holder.avatar);
if (UserModel.get().getCacheLoginUserInfo() != null && UserModel.get().getCacheLoginUserInfo().isSuperAdmin()) {
OtherExtKt.setVis(holder.operationImg, false, false);
} else {
OtherExtKt.setVis(holder.operationImg,true,false);
}
}
@Override
public int getItemCount() {
if (normalList == null) {
return 0;
} else {
return normalList.size();
}
}
@Override
public void onClick(View v) {
if (v.getTag() != null && v.getTag() instanceof ChatRoomMember) {
ChatRoomMember chatRoomMember = (ChatRoomMember) v.getTag();
if (listOperationClickListener != null) {
listOperationClickListener.onRemoveOperationClick(chatRoomMember);
}
}
}
public class RoomNormalListHolder extends RecyclerView.ViewHolder {
private CircleImageView avatar;
private TextView nick;
private TextView erbanNo;
private TextView operationImg;
public RoomNormalListHolder(View itemView) {
super(itemView);
avatar = (CircleImageView) itemView.findViewById(R.id.avatar);
nick = (TextView) itemView.findViewById(R.id.nick);
erbanNo = (TextView) itemView.findViewById(R.id.erban_no);
operationImg = (TextView) itemView.findViewById(R.id.remove_opration);
}
}
public interface OnRoomNormalListOperationClickListener {
void onRemoveOperationClick(ChatRoomMember chatRoomMember);
}
}

View File

@@ -0,0 +1,27 @@
package com.chwl.app.avroom.adapter;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import java.util.List;
public class RoomRankFragmentPageAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList;
public RoomRankFragmentPageAdapter(FragmentManager fm, List<Fragment> fragmentList) {
super(fm);
this.fragmentList = fragmentList;
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
}

View File

@@ -0,0 +1,63 @@
package com.chwl.app.avroom.adapter;
import android.content.Context;
import android.widget.TextView;
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.chwl.app.R;
import com.chwl.app.avroom.fragment.RoomRankDialogUtils;
import com.chwl.app.common.widget.CircleImageView;
import com.chwl.app.ui.utils.ImageLoadUtils;
import com.chwl.core.room.bean.RoomRankHalfHourRankInfo;
import com.chwl.core.room.bean.RoomRankMultiItem;
import java.util.ArrayList;
public class RoomRankHalfHourListAdapter extends BaseMultiItemQuickAdapter<RoomRankMultiItem, BaseViewHolder> {
public final static int TYPE_TIPS = 4;
public RoomRankHalfHourListAdapter(Context context) {
super(new ArrayList<>());
addItemType(RoomRankMultiItem.TYPE_LINEAR, R.layout.item_room_rank_layout);
addItemType(RoomRankMultiItem.TYPE_EMPTY, R.layout.item_empty_list);
addItemType(TYPE_TIPS, R.layout.item_rank_half_tips);
}
@Override
protected void convert(BaseViewHolder baseViewHolder, RoomRankMultiItem roomConsumeInfo) {
if (roomConsumeInfo == null) {
return;
}
if (roomConsumeInfo.getItemType() == RoomRankMultiItem.TYPE_LINEAR) {
setLinearData(baseViewHolder, roomConsumeInfo);
} else if (roomConsumeInfo.getItemType() == RoomRankMultiItem.TYPE_EMPTY) {
}
}
private void setLinearData(BaseViewHolder baseViewHolder, RoomRankMultiItem roomConsumeInfo) {
if (roomConsumeInfo == null) {
return;
}
RoomRankHalfHourRankInfo roomRankHalfHourRankInfo = (RoomRankHalfHourRankInfo) roomConsumeInfo.getData();
if (roomRankHalfHourRankInfo == null)
return;
// 值
TextView valueTV = baseViewHolder.getView(R.id.tv_room_rank_value);
valueTV.setText(RoomRankDialogUtils.getRoomRankValueText(roomRankHalfHourRankInfo.getTotalNum()));
int drawable = RoomRankDialogUtils.getNumberImage(roomRankHalfHourRankInfo.getSeqNo());
if (drawable != 0)
baseViewHolder.setImageResource(R.id.iv_number, drawable);
// 标题
baseViewHolder.setText(R.id.tv_room_rank_title, roomRankHalfHourRankInfo.getRoomTitle());
// 头像
CircleImageView avatarView = baseViewHolder.getView(R.id.iv_room_rank_avatar);
ImageLoadUtils.loadAvatar(roomRankHalfHourRankInfo.getAvatar(),avatarView);
baseViewHolder.setText(R.id.tv_room_rank_id, "ID:" + roomRankHalfHourRankInfo.getErbanNo());
}
}

View File

@@ -0,0 +1,31 @@
package com.chwl.app.avroom.adapter;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import java.util.List;
/**
* Created by MadisonRong on 25/04/2018.
*/
public class RoomVPAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList;
public RoomVPAdapter(FragmentManager fm, List<Fragment> fragmentList) {
super(fm,FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.fragmentList = fragmentList;
}
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
}

Some files were not shown because too many files have changed in this diff Show More