开始画房间页面功能

This commit is contained in:
2025-06-09 17:43:01 +08:00
parent aa865a69b3
commit 4c7e996706
159 changed files with 8598 additions and 75 deletions

View File

@@ -148,10 +148,8 @@ dependencies {
api('com.google.android.exoplayer:exoplayer-ui:2.19.1')
api("com.egame.vap:animplayer:2.0.8")
api("com.liulishuo.okdownload:okdownload:1.0.7")
// SVGA player
// api('com.github.yyued:SVGAPlayer-Android:2.6.1')
// OpenGL ES
// api('androidx.opengl:opengl:1.3.0')
api('com.zlc.glide:webpdecoder:1.6.4.9.0')
//腾讯im
// api project(':tuiconversation')

View File

@@ -0,0 +1,104 @@
package com.qxcm.moduleutil.adapter;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import java.util.ArrayList;
import java.util.List;
/**
*@author qx
*@data 2025/6/9
*@description:可动态添加和删除的viewPage适配器
*/
public class CommonPageAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragmentList = new ArrayList<>();
private List<Integer> mItemIdList = new ArrayList<>();
private int id = 0;
private FragmentManager mFm;
public CommonPageAdapter(FragmentManager fm, @NonNull List<Fragment> fragmentList) {
super(fm);
this.mFm = fm;
for (Fragment fragment : fragmentList) {
this.mFragmentList.add(fragment);
mItemIdList.add(id++);
}
}
public CommonPageAdapter(FragmentManager fm) {
super(fm);
}
public List<Fragment> getFragmentList() {
return mFragmentList;
}
public void addPage(int index, Fragment fragment) {
mFragmentList.add(index, fragment);
mItemIdList.add(index, id++);
notifyDataSetChanged();
}
public void addPage(Fragment fragment) {
mFragmentList.add(fragment);
mItemIdList.add(id++);
notifyDataSetChanged();
}
public void delPage(int index) {
mFragmentList.remove(index);
mItemIdList.remove(index);
notifyDataSetChanged();
}
public void updatePage(List<Fragment> fragmentList) {
mFragmentList.clear();
mItemIdList.clear();
for (int i = 0; i < fragmentList.size(); i++) {
mFragmentList.add(fragmentList.get(i));
mItemIdList.add(id++);//注意这里是id++不是i++。
}
notifyDataSetChanged();
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
/**
* 返回值有三种,
* POSITION_UNCHANGED 默认值,位置没有改变
* POSITION_NONE item已经不存在
* position item新的位置
* 当position发生改变时这个方法应该返回改变后的位置以便页面刷新。
*/
@Override
public int getItemPosition(Object object) {
if (object instanceof Fragment) {
if (mFragmentList.contains(object)) {
return mFragmentList.indexOf(object);
} else {
return POSITION_NONE;
}
}
return super.getItemPosition(object);
}
@Override
public long getItemId(int position) {
return mItemIdList.get(position);
}
}

View File

@@ -0,0 +1,27 @@
package com.qxcm.moduleutil.base;
import android.app.Activity;
import com.qxcm.moduleutil.activity.IPresenter;
import com.qxcm.moduleutil.activity.IView;
public final class BaseRoomContacts {
public interface View extends IView<Activity> {
}
public interface IBaseRoomPre extends IPresenter {
void downWheat(String roomId);
void applyWheat(String roomId, String pitNumber);
void applyWheatWait(String roomId, String pitNumber);
void getRoomInfo(String roomId, String password);
void putOnWheat(String roomId, String userId,String pitNum);
}
}

View File

@@ -0,0 +1,171 @@
package com.qxcm.moduleutil.base;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.ViewDataBinding;
import com.qxcm.moduleutil.bean.room.RoomInfoResp;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseRoomFragment<P extends BaseRoomPresenter, VDB extends ViewDataBinding> extends BaseMvpFragment<P, VDB> implements BaseRoomContacts.View {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
EventBus.getDefault().register(this);
}
@Override
public void onDestroyView() {
unRegisterWheatViews();
EventBus.getDefault().unregister(this);
super.onDestroyView();
}
@Override
protected void initView() {
registerWheatViews();
}
/**
* 房间信息
*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void roomInfo(RoomInfoResp resp) {
roomInfoUpdate(resp);
// EventBus.getDefault().post(new RoomCardiacValueChangedEvent());
}
public abstract void roomInfoUpdate(RoomInfoResp resp);
public abstract void registerWheatViews();
public abstract void unRegisterWheatViews();
public abstract int[] collectCurrentCardiacValues();
public int[][] collectAmativenessCurrentCardiacValues() { return new int[2][0]; }
public abstract void hideAllWheatMaozi();
public void showWheatMaoziHuangguan(int wheat) {}
public void showWheatMaoziBianbian(int... wheats) {}
public void showAmativenessMaleWheatMaozi(int index, int level) {}
public void showAmativenessFemaleWheatMaozi(int index, int level) {}
protected void tzblChanged() {
}
// @Subscribe(threadMode = ThreadMode.MAIN)
// public void onRoomTzblChangedEvent(RoomTzblChangedEvent event) {
// tzblChanged();
// }
// @Subscribe(threadMode = ThreadMode.MAIN)
// public void onRoomCardiacValueChangedEvent(RoomCardiacValueChangedEvent event) {
//// hideAllWheatMaozi();
// checkWheatMaoziState(collectCurrentCardiacValues());
// int[][] cvs = collectAmativenessCurrentCardiacValues();
// checkAmativenessMaleWheatMaoziState(cvs[0]);
// checkAmativenessFemaleWheatMaoziState(cvs[1]);
// }
private void checkWheatMaoziState(int[] cvs) {
int max = -999999999;
int min = 999999999;
List<Integer> maxs = new ArrayList<>();
List<Integer> mins = new ArrayList<>();
// 找出最大值/最小值
for (int i = 0; i < cvs.length; i++) {
int v = cvs[i];
if (v < 0) continue; // 小于0的麦位表示麦位没人
if (v >= max) { max = v; }
if (v <= min) { min = v; }
}
// 如果最大值和最小值相同,全部不带帽子
if (min == max) return;
// 找出最大值的麦位/最小值的麦位
for (int i = 0; i < cvs.length; i++) {
int v = cvs[i];
if (v < 0) continue; // 小于0的麦位表示麦位没人
if (v == max) { maxs.add(i); }
if (v == min) { mins.add(i); }
}
// 排序最大值的麦位,选出最优先的一个,带皇冠
if (maxs.size() > 0) {
// showWheatMaoziHuangguan(maxs.get(0));
}
// 给所有最小值的麦位,带便便
if (mins.size() > 0) {
int[] ws = new int[mins.size()];
for (int i = 0; i < ws.length; i++) { ws[i] = mins.get(i); }
// showWheatMaoziBianbian(ws);
}
}
private void checkAmativenessMaleWheatMaoziState(int[] cvs) {
int max = -999999999;
List<Integer> maxs = new ArrayList<>();
// 找出最大值
for (int v : cvs) {
if (v < 0) continue; // 小于0的麦位表示麦位没人
if (v >= max) {
max = v;
}
}
// 找出最大值的麦位
for (int i = 0; i < cvs.length; i++) {
int v = cvs[i];
if (v < 0) continue; // 小于0的麦位表示麦位没人
if (v == max) { maxs.add(i); }
}
// 获得男生第一帽子等级
if (maxs.size() > 0) {
int level = getAmativenessWheatMaoziLevel(max);
if (level > 0) showAmativenessMaleWheatMaozi(maxs.get(0), level);
}
}
private void checkAmativenessFemaleWheatMaoziState(int[] cvs) {
int max = -999999999;
List<Integer> maxs = new ArrayList<>();
// 找出最大值
for (int v : cvs) {
if (v < 0) continue; // 小于0的麦位表示麦位没人
if (v >= max) {
max = v;
}
}
// 找出最大值的麦位
for (int i = 0; i < cvs.length; i++) {
int v = cvs[i];
if (v < 0) continue; // 小于0的麦位表示麦位没人
if (v == max) { maxs.add(i); }
}
// 获得女生第一帽子等级
if (maxs.size() > 0) {
int level = getAmativenessWheatMaoziLevel(max);
if (level > 0) showAmativenessFemaleWheatMaozi(maxs.get(0), level);
}
}
private int getAmativenessWheatMaoziLevel(int value) {
if (value >= 52000) {
return 3;
} else if (value >= 10000) {
return 2;
} else if (value >= 1000) {
return 1;
} else {
return 0;
}
}
}

View File

@@ -0,0 +1,158 @@
package com.qxcm.moduleutil.base;
import android.content.Context;
import com.blankj.utilcode.util.ObjectUtils;
import com.qxcm.moduleutil.activity.IView;
import com.qxcm.moduleutil.presenter.BasePresenter;
import org.greenrobot.eventbus.EventBus;
import io.reactivex.disposables.Disposable;
public class BaseRoomPresenter<V extends IView> extends BasePresenter<V> implements BaseRoomContacts.IBaseRoomPre {
public BaseRoomPresenter(V view, Context context) {
super(view, context);
}
@Override
public void downWheat(String roomId) {
// ApiClient.getInstance().downWheat(roomId, new BaseObserver<String>() {
// @Override
// public void onSubscribe(Disposable d) {
// addDisposable(d);
// }
//
// @Override
// public void onNext(String s) {
//// getRoomInfo(roomId);
// EventBus.getDefault().post(new UserDownWheatEvent());
// RtcManager.getInstance().downWheat();
// }
//
// @Override
// public void onComplete() {
//
// }
// });
}
@Override
public void applyWheat(String roomId, String pitNumber) {
// ApiClient.getInstance().applyWheat(roomId, pitNumber, new BaseObserver<String>() {
// @Override
// public void onSubscribe(Disposable d) {
// addDisposable(d);
// }
//
// @Override
// public void onNext(String s) {
//// getRoomInfo(roomId);
// }
//
// @Override
// public void onComplete() {
//
// }
// });
}
@Override
public void applyWheatWait(String roomId, String pitNumber) {
// ApiClient.getInstance().applyWheatWait(roomId, pitNumber, new BaseObserver<ApplyWheatWaitResp>() {
// @Override
// public void onSubscribe(Disposable d) {
// addDisposable(d);
// }
//
// @Override
// public void onNext(ApplyWheatWaitResp applyWheatWaitResp) {
// if (applyWheatWaitResp != null && !applyWheatWaitResp.getState().equals("1")) {
// EventBus.getDefault().post(new ApplyWaitEvent(true, pitNumber));
//// ToastUtils.show("申请成功");
// }
// }
//
// @Override
// public void onComplete() {
//
// }
// });
}
@Override
public void getRoomInfo(String roomId, String password) {
// NewApi.getInstance().roomInfo(roomId, password, new com.qpyy.libcommon.api.BaseObserver<RoomInfoResp>() {
//// NewApi.getInstance().roomGetIn(roomId, password, new com.qpyy.libcommon.api.BaseObserver<RoomInfoResp>() {
// @Override
// public void onSubscribe(Disposable d) {
// addDisposable(d);
// }
//
// @Override
// public void onNext(RoomInfoResp roomInfoResp) {
// if (roomInfoResp.getRejoin() == 1) {
// UserBean userBean = BaseApplication.getInstance().getUser();
// Config config = null;
// if (!ObjectUtils.isEmpty(roomInfoResp.getRoom_info().getSound_effect())) {
// config = roomInfoResp.getRoom_info().getSound_effect().getConfig();
// }
// RtcManager.getInstance().destroyAndLogin(RtcConstants.RtcType_CURR, roomInfoResp.getRoom_info().getSceneId(), config, roomId, userBean.getUser_id(), userBean.getNickname(), "", new RtcDestroyCallback() {
// @Override
// public void onDestroySuccess() {
// if (roomInfoResp.isOnWheat()) {//在麦位上就恢复麦克风状态
// RtcManager.getInstance().applyWheat(String.format("%s_%s", roomId, SpUtils.getUserId()));
// } else {//否则停止推流
// RtcManager.getInstance().downWheat();
// }
// RtcManager.getInstance().resumeAudio();
// }
// });
// } else {
// if (roomInfoResp.isOnWheat()) {//在麦位上就恢复麦克风状态
// RtcManager.getInstance().resumeMic();
// } else {//否则停止推流
// RtcManager.getInstance().downWheat();
// }
// }
// EventBus.getDefault().post(roomInfoResp);
// }
//
// @Override
// public void onComplete() {
//
// }
//
// @Override
// public void onError(Throwable e) {
// super.onError(e);
// if (e instanceof APIException) {
// EventBus.getDefault().post(new RoomOutEvent());
// }
// }
// });
}
@Override
public void putOnWheat(String roomId, String userId,String pitNum) {
MvpRef.get().showLoadings();
// ApiClient.getInstance().putOnWheat(roomId, userId,pitNum, new BaseObserver<PutOnWheatResp>() {
// @Override
// public void onSubscribe(Disposable d) {
// addDisposable(d);
// }
//
// @Override
// public void onNext(PutOnWheatResp s) {
//
// }
//
// @Override
// public void onComplete() {
// MvpRef.get().disLoadings();
// }
// });
}
}

View File

@@ -101,7 +101,7 @@ public class CommonAppContext extends MultiDexApplication {
}
private void initARouter() {
if(BuildConfig.DEBUG) {
if(true) {
ARouter.openDebug();
ARouter.openLog();
}

View File

@@ -0,0 +1,11 @@
package com.qxcm.moduleutil.base;
import lombok.Data;
@Data
public class RoomRollModel {
private String room_id;
private String user_id;
private String pit_number;
private int number;
}

View File

@@ -0,0 +1,68 @@
package com.qxcm.moduleutil.bean;
public class FaceBean {
/**
* number : 0
* face_spectial : https://gudao-prod.oss-cn-hangzhou.aliyuncs.com/user-dir/N4WsWKm4pS.gif
* pit : 9
* type : 1
*/
private int number;
private String face_spectial;
private String pit;
private int type;
private int millTime;
public FaceBean(int number, int type) {
this.number = number;
this.type = type;
}
public FaceBean() {
}
public FaceBean(String face_spectial, double time, int type) {
this.face_spectial = face_spectial;
this.type = type;
this.millTime = (int) (time * 1000);
}
public int getMillTime() {
return millTime;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getFace_spectial() {
return face_spectial;
}
public void setFace_spectial(String face_spectial) {
this.face_spectial = face_spectial;
}
public String getPit() {
return pit;
}
public void setPit(String pit) {
this.pit = pit;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}

View File

@@ -10,6 +10,8 @@ import lombok.Data;
*/
@Data
public class UserInfo {
public static final String FEMALE = "2";
public static final String MALE = "1";
private int id; //用户id
private String user_code;//用户id码
private String avatar;//头像

View File

@@ -0,0 +1,49 @@
package com.qxcm.moduleutil.bean.room;
import com.stx.xhb.xbanner.entity.SimpleBannerInfo;
import java.io.Serializable;
public class BannerItem extends SimpleBannerInfo implements Serializable {
private String picture;
private int type;
private int game_type;
private String url;
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getGame_type() {
return game_type;
}
public void setGame_type(int game_type) {
this.game_type = game_type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public Object getXBannerUrl() {
return picture;
}
}

View File

@@ -0,0 +1,19 @@
package com.qxcm.moduleutil.bean.room;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 项目名称 qipao-android
* 包名com.qpyy.room.bean
* 创建人 黄强
* 创建时间 2020/8/19 15:25
* 描述 describe
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ClosePhone {
public boolean isClosePhone;
}

View File

@@ -0,0 +1,22 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
import lombok.Data;
@Data
public class Config implements Serializable {
public Integer codecID;
public Integer bitrate;
public Integer channel;
public Integer HeadphoneAEC;
public Integer AGC;
public Integer AEC;
public Integer ANS;
public Integer ANSMode;
public Integer scenario;
}

View File

@@ -0,0 +1,24 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
import lombok.Data;
@Data
public class HeartListBean implements Serializable {
// private int id;
// private int room_id;
// private int user1_id;
// private int user2_id;
// private int heart_value;
// private int status;
// private int friend_id;
// private int friend_config_id;
// private long contact_end_time;
// private int is_del;
// private long create_time;
// private long update_time;
private String heartNum;
private String heartId;
}

View File

@@ -0,0 +1,73 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
public class RankInfo implements Serializable {
/**
* rank_id : 54
* rank_name : 王冠
* nobility_id : 0
* nobility_name :
* picture :
*/
public int rank_id;
public String rank_name;
public int nobility_id;
public String nobility_name;
public String picture;
public int money;
public RankInfo() {
}
public int getMoney() {
return money;
}
public int getRank_id() {
return rank_id;
}
public void setRank_id(int rank_id) {
this.rank_id = rank_id;
}
public String getRank_name() {
return rank_name;
}
public void setRank_name(String rank_name) {
this.rank_name = rank_name;
}
public int getNobility_id() {
return nobility_id;
}
public void setNobility_id(int nobility_id) {
this.nobility_id = nobility_id;
}
public String getNobility_name() {
return nobility_name;
}
public void setNobility_name(String nobility_name) {
this.nobility_name = nobility_name;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
}

View File

@@ -0,0 +1,124 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
import java.util.List;
import lombok.Data;
@Data
public class RoomBean implements Serializable {
/**
* room_id : 173
* room_code : 10200
* popularity : 88
* chatrooms : 107600315219969
* room_name : 红楼(全麦仙女等您独宠)
* bg_picture :
* cover_picture : https://gudao-prod.oss-cn-hangzhou.aliyuncs.com/android_images/551686/20200219161053_1582099853481168.jpg
* playing : 欢迎来到红楼
* 祝您玩的开心
* 普通试音100金币
* 高级试音300金币
* 互动一分钟999金币 主持费300金币
* 互动三分钟2999金币 主持费600金币
* 互动四分钟全麦100金币
* 互动五分钟全麦300金币
* <p>
* 带有半小时9999金币
* 主持单费2999金币
* 带走一小时13140金币
* 主持单费3999金币
* 带走包夜52099金币
* 主持单费9999金币
* <p>
* 带走主持半小时13140金币
* 全麦2100金币
* label_id : 25
* label_name : 女神
* wheat : 1
* greeting : 欢迎来到红楼
* 祝您玩的开心
* 普通试音100金币
* 高级试音300金币
* 互动一分钟999金币 主持费300金币
* 互动三分钟2999金币 主持费600金币
* 互动四分钟全麦100金币
* 互动五分钟全麦300金币
* <p>
* 带有半小时9999金币
* 主持单费2999金币
* 带走一小时13140金币
* 主持单费3999金币
* 带走包夜52099金币
* 主持单费9999金币
* <p>
* 带走主持半小时13140金币
* 全麦2100金币
* type_id : 0
* type_name : null
* show_ball_game : 0
* is_password : 0
* pit_list : [{"id":"1549","room_id":"173","user_id":"559397","pit_number":"1","voice":"0","shutup":"0","state":"2","nickname":"麒麟🌺","head_picture":"https://gudao-prod.oss-cn-hangzhou.aliyuncs.com/android_images/559397/20200305123221_158338274166572.jpeg","sex":"2","emchat_username":"ol7xe0Q5CfoV2lMgdEJ_B2K9wcrk","rank_id":"2","nobility":"0","xin_dong":"10","banned":0,"rank_info":{"rank_id":2,"rank_name":"2","nobility_id":0,"nobility_name":"","picture":""},"dress_picture":""},{"id":"1550","room_id":"173","user_id":"551780","pit_number":"2","voice":"0","shutup":"2","state":"2","nickname":"幺鸡🌺","head_picture":"https://gudao-prod.oss-cn-hangzhou.aliyuncs.com/ios_images/2020-02-27/CD3024D8-1DBC-4D67-B96B-8859B6A65FCC.png","sex":"2","emchat_username":"ol7xe0SZavgYOyHvbx088Co04fh0","rank_id":"6","nobility":"0","xin_dong":"10","banned":0,"rank_info":{"rank_id":6,"rank_name":"6","nobility_id":0,"nobility_name":"","picture":""},"dress_picture":""},{"id":"1551","room_id":"173","user_id":"556367","pit_number":"3","voice":"0","shutup":"0","state":"2","nickname":"蜜桃Nico🌺","head_picture":"https://gudao-prod.oss-cn-hangzhou.aliyuncs.com/android_images/556367/20200304004515_1583253915637558.jpg","sex":"2","emchat_username":"ol7xe0WZQODx6ArdZl2AUuG6czvM","rank_id":"0","nobility":"0","xin_dong":"10","banned":0,"rank_info":{"rank_id":0,"rank_name":"","nobility_id":0,"nobility_name":"","picture":""},"dress_picture":""},{"id":"1552","room_id":"173","user_id":"557384","pit_number":"4","voice":"0","shutup":"0","state":"2","nickname":"海你🌺","head_picture":"https://gudao-prod.oss-cn-hangzhou.aliyuncs.com/android_images/557384/20200305133807_1583386684653.jpg","sex":"2","emchat_username":"ol7xe0QObyzXcfcLE-2YvWkqPS7c","rank_id":"2","nobility":"0","xin_dong":"10","banned":0,"rank_info":{"rank_id":2,"rank_name":"2","nobility_id":0,"nobility_name":"","picture":""},"dress_picture":""},{"id":"1553","room_id":"173","user_id":"552419","pit_number":"5","voice":"0","shutup":"2","state":"2","nickname":"绵绵🌺","head_picture":"https://gudao-prod.oss-cn-hangzhou.aliyuncs.com/android_images/552419/20200303161046_1583223042812.jpg","sex":"0","emchat_username":"ol7xe0cDgfZDSJ5DMJJigGuw3nSM","rank_id":"3","nobility":"0","xin_dong":"10","banned":0,"rank_info":{"rank_id":3,"rank_name":"3","nobility_id":0,"nobility_name":"","picture":""},"dress_picture":""},{"id":"1554","room_id":"173","user_id":"552249","pit_number":"6","voice":"0","shutup":"2","state":"2","nickname":"萌萌🌺","head_picture":"https://yutangyuyin.oss-cn-hangzhou.aliyuncs.com/android_images/552249/20200229003745_1582907864986335.jpg","sex":"2","emchat_username":"87c9acbaa00134193ae83646f1920875","rank_id":"0","nobility":"0","xin_dong":"10","banned":0,"rank_info":{"rank_id":0,"rank_name":"","nobility_id":0,"nobility_name":"","picture":""},"dress_picture":""},{"id":"1555","room_id":"173","user_id":"551998","pit_number":"7","voice":"0","shutup":"2","state":"2","nickname":"糯米团儿🌺","head_picture":"https://yutangyuyin.oss-cn-hangzhou.aliyuncs.com/android_images/551998/20200304003924_1583253564426522.jpg","sex":"2","emchat_username":"AE4F4C0E1AC450696CA34AAFE3243751","rank_id":"2","nobility":"0","xin_dong":"10","banned":0,"rank_info":{"rank_id":2,"rank_name":"2","nobility_id":0,"nobility_name":"","picture":""},"dress_picture":""},{"id":"1556","room_id":"173","user_id":"","pit_number":"8","voice":"0","shutup":"2","state":"2","nickname":"空调不够冷","head_picture":"http://thirdqq.qlogo.cn/g?b=oidb&amp;k=Q05NNBwkaItMj6cO5TjLrg&amp;s=100&amp;t=1560935564","sex":"0","emchat_username":null,"rank_id":null,"nobility":null,"xin_dong":0},{"id":"1557","room_id":"173","user_id":"553635","pit_number":"9","voice":"1","shutup":"0","state":"2","nickname":"貔貅🌺","head_picture":"https://yutangyuyin.oss-cn-hangzhou.aliyuncs.com/android_images/553635/20200303234859_1583250539340950.jpeg","sex":"2","emchat_username":"da156bd05da1146aa6c2a195d561b139","rank_id":"16","nobility":"0","xin_dong":"10","banned":0,"rank_info":{"rank_id":16,"rank_name":"16","nobility_id":0,"nobility_name":"","picture":""},"dress_picture":""}]
* official_notice : 官方公告:官方倡导绿色互动,请勿发布政治、违法、低俗、暴力、广告等内容,禁止违规交易,违规者将被禁封账号,情节严重者追究法律责任。
* apply_count : 22
* contribution : 14453977
* role : 3
*/
private String room_id;
private String room_code;
private String popularity;
private String chatrooms;
private String room_name;
private String label_icon_room;
private String bg_picture;
private String cover_picture;
private String playing;
private String label_id;
private String label_name;
private String wheat;
private String greeting;
private String type_id;
private String type_name;
private int show_ball_game;
private int is_password;
private String official_notice;
private String apply_count;
private String contribution;
private int role;
private List<RoomPitBean> pit_list;
private int cardiac; // 显示心动 1开 0关
private int is_fm;
private int room_type;//0普通房1电台房2相亲房3派单厅"
private SoundEffectResp sound_effect;
private int voice_set;//音效场景id
private int chat_status;//开关公屏 1开 0关
private int actual_role;//真实角色 5为官方
private String is_pretty ;//靓号 1 显示 0 不显示
private String is_boss_pit ;//老板麦 1 显示 0 不显示
private int is_owner_model;//房主模式0无权限1开启2关闭
public static final int TYPE_NORMAL = 0;//普通房
public static final int TYPE_STATION = 1;//电台房
public static final int TYPE_MEAT = 2;//相亲房
public static final int TYPE_ORDER = 3;//派单房
private int status; // 相亲状态
private AInfo activity_img; // 相亲活动介绍图片
private RoomFriendBean friend;
public int getSceneId() {
if (sound_effect != null) {
return sound_effect.getId();
}
return 1;
}
@Data
public static class AInfo implements Serializable {
public String url;
}
}

View File

@@ -0,0 +1,13 @@
package com.qxcm.moduleutil.bean.room;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoomClearCardiacAllModel {
private String room_id;
}

View File

@@ -0,0 +1,15 @@
package com.qxcm.moduleutil.bean.room;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoomClearCardiacModel {
private String room_id;
private String pit_number;
}

View File

@@ -0,0 +1,17 @@
package com.qxcm.moduleutil.bean.room;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoomClosePitModel {
private String action;
private String pit_number;
private String room_id;
}

View File

@@ -0,0 +1,16 @@
package com.qxcm.moduleutil.bean.room;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoomCountDownModel {
private String room_id;
private String pit_number;
private int seconds;
}

View File

@@ -0,0 +1,17 @@
package com.qxcm.moduleutil.bean.room;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoomDownWheatModel {
private String room_id;
private String pit_number;
private int user_id;
private String emcht_name;
}

View File

@@ -0,0 +1,16 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
import java.util.List;
import lombok.Data;
@Data
public class RoomFriendBean implements Serializable {
private String friend_id;
private int friend_status;
private int room_on_line_cp; // // cp在线数
private int is_preside;//0:不是主持人 1:是主持人
private long end_time;
private List<HeartListBean> heart_list;
}

View File

@@ -0,0 +1,182 @@
package com.qxcm.moduleutil.bean.room;
import java.util.List;
public class RoomGiveGiftModel {
/**
* room_id : 3
* gift_list : [{"user_id":"547177","nickname_from":"titititi","nickname_to":"佳人有约","gift_name":"比心","picture":"礼物图片url","special":"礼物特效url","number":"1"}]
* cardiac_list : [{"rough_number":"当前麦位心动值","room_id":"3","pit_number":"1"},{"rough_number":"0","room_id":"3","pit_number":"2"},{"rough_number":"0","room_id":"3","pit_number":"3"},{"rough_number":"0","room_id":"3","pit_number":"4"},{"rough_number":"0","room_id":"3","pit_number":"5"},{"rough_number":"0","room_id":"3","pit_number":"6"},{"rough_number":"0","room_id":"3","pit_number":"7"},{"rough_number":"0","room_id":"3","pit_number":"8"},{"rough_number":"0","room_id":"3","pit_number":"9"}]
* contribution : 5430
*/
private String room_id;
private String contribution;
private List<GiftListBean> gift_list;
private List<CardiacListBean> cardiac_list;
public String getRoom_id() {
return room_id;
}
public void setRoom_id(String room_id) {
this.room_id = room_id;
}
public String getContribution() {
return contribution;
}
public void setContribution(String contribution) {
this.contribution = contribution;
}
public List<GiftListBean> getGift_list() {
return gift_list;
}
public void setGift_list(List<GiftListBean> gift_list) {
this.gift_list = gift_list;
}
public List<CardiacListBean> getCardiac_list() {
return cardiac_list;
}
public void setCardiac_list(List<CardiacListBean> cardiac_list) {
this.cardiac_list = cardiac_list;
}
public static class GiftListBean {
/**
* user_id : 547177
* nickname_from : titititi
* nickname_to : 佳人有约
* gift_name : 比心
* picture : 礼物图片url
* special : 礼物特效url
* number : 1
*/
private String user_id;
private String nickname_from;
private String nickname_to;
private String gift_name;
private String picture;
private String special;
private String number;
private String head_picture;
public String getHead_picture() {
return head_picture;
}
public void setHead_picture(String head_picture) {
this.head_picture = head_picture;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getNickname_from() {
return nickname_from;
}
public void setNickname_from(String nickname_from) {
this.nickname_from = nickname_from;
}
public String getNickname_to() {
return nickname_to;
}
public void setNickname_to(String nickname_to) {
this.nickname_to = nickname_to;
}
public String getGift_name() {
return gift_name;
}
public void setGift_name(String gift_name) {
this.gift_name = gift_name;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public String getSpecial() {
return special;
}
public void setSpecial(String special) {
this.special = special;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
public static class CardiacListBean {
/**
* rough_number : 当前麦位心动值
* room_id : 3
* pit_number : 1
*/
private String rough_number;
private String room_id;
private String pit_number;
private String xin_dong;
public String getXin_dong() {
return xin_dong;
}
public void setXin_dong(String xin_dong) {
this.xin_dong = xin_dong;
}
public String getRough_number() {
return rough_number;
}
public void setRough_number(String rough_number) {
this.rough_number = rough_number;
}
public String getRoom_id() {
return room_id;
}
public void setRoom_id(String room_id) {
this.room_id = room_id;
}
public String getPit_number() {
return pit_number;
}
public void setPit_number(String pit_number) {
this.pit_number = pit_number;
}
}
}

View File

@@ -0,0 +1,105 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
import java.util.List;
import lombok.Data;
/**
* 项目名称 qipao-android
* 包名com.qpyy.room.bean
* 创建人 王欧
* 创建时间 2020/7/24 2:58 PM
* 描述 describe
*/
@Data
public class RoomInfoResp implements Serializable {
private RoomBean room_info;
private RoomOwnerBean owner_info;
private RoomUserBean user_info;
private List<BannerItem> banner;
private RoomOrderDemand demand;//嘉宾需求
private int rejoin;
private int is_show_self;//盲盒是否送自己
//弹出麦位操作弹出
public boolean isWheatManager() {
//是管理员且在1或者9号麦当时房主模式时2号麦也有管理权限
// return isManager() && (user_info.getPit() == 1 || user_info.getPit() == 9 || (room_info.getIs_owner_model() == 1 && user_info.getPit() == 2));
return isManager() && ( user_info.getPit() == 9 || (room_info.getIs_owner_model() == 1 && user_info.getPit() == 2));
}
public boolean isPreside(){
return user_info.getIs_preside() == 1;
}
//管理权限
public boolean isManager() {
return room_info.getRole() == 1 || room_info.getRole() == 2 || room_info.getRole() == 5;
}
//管理权限
public boolean isOwner() {
return room_info.getRole() == 1;
}
//可查看房间流水
public boolean isMicPlace() {
return (room_info.getRole() == 1 || room_info.getRole() == 2 || room_info.getActual_role() == 5) && room_info.getRoom_type() != 1;
}
/**
* 是否主持
*
* @return
*/
public boolean isHost() {
return (room_info.getRole() == 1 || room_info.getRole() == 2) && user_info.getPit() == 9;
}
/**
* 是否是派单厅
*
* @return
*/
public boolean isOrderRoom() {
return room_info.getRoom_type() == RoomBean.TYPE_ORDER;
}
/**
* 是否在麦位
*
* @return
*/
public boolean isOnWheat() {
return user_info.getPit() != 0;
}
/**
* 是否在排麦中
*
* @return
*/
public boolean isRowWheat() {
return user_info.getApply_wait() == 1;
}
/**
* 是否是点单排麦中
*
* @return
*/
public boolean isOrderRowWheat() {
return isRowWheat() && user_info.getApply_wait_type() == 1;
}
/**
* 是否自由模式
*
* @return
*/
public boolean isFreedomMode() {
return "1".equals(room_info.getWheat());
}
}

View File

@@ -0,0 +1,49 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
import lombok.Data;
@Data
public class RoomOrderDemand implements Serializable {
private Detail detail;
private String time;
private String time_text;
private String total;
public boolean hasDemand() {
return detail != null && detail.getId() > 0;
}
public int getDemandId() {
if (hasDemand()) {
return detail.getId();
}
return 0;
}
@Data
public static class Detail implements Serializable {
private String lisence_name;
private String gender;
private String price_area;
private String remark;
private int id;
public String getGenderDesc() {
if (gender == null) {
return "";
}
// switch (gender) {
// case UserBean.FEMALE:
// return "女";
// case UserBean.MALE:
// return "男";
// default:
return "不限";
// }
}
}
}

View File

@@ -0,0 +1,70 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
public class RoomOwnerBean implements Serializable {
/**
* user_id : 551686
* user_code : 884003
* head_picture : https://yutangyuyin.oss-cn-hangzhou.aliyuncs.com/android_images/551686/20200221200911_1582286951202590.jpg
* sex : 2
* nickname : 秋水(做我家的崽)
*/
private String user_id;
private String user_code;
private String head_picture;
private String sex;
private String nickname;
private int status;///0离开1在线
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getUser_code() {
return user_code;
}
public void setUser_code(String user_code) {
this.user_code = user_code;
}
public String getHead_picture() {
return head_picture;
}
public void setHead_picture(String head_picture) {
this.head_picture = head_picture;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}

View File

@@ -0,0 +1,243 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
public class RoomPitBean implements Serializable {
/**
* id : 1549
* room_id : 173
* user_id : 559397
* pit_number : 1
* voice : 0
* shutup : 0
* state : 2
* nickname : 麒麟🌺
* head_picture : https://gudao-prod.oss-cn-hangzhou.aliyuncs.com/android_images/559397/20200305123221_158338274166572.jpeg
* sex : 2
* emchat_username : ol7xe0Q5CfoV2lMgdEJ_B2K9wcrk
* rank_id : 2
* nobility : 0
* xin_dong : 10
* banned : 0
* dress_picture :
*/
private String id;
private String room_id;
private String user_id;
private String pit_number;
private String voice;
private String shutup;
private String state;
private String nickname;
private String head_picture;
private String sex;
private String emchat_username;
private String rank_id;
private String nobility;
private String xin_dong;
private String banned;
private String dress_picture;
private RankInfo rank_info;
private int count_down;
private int ball_state;//1开球0未开球
private int is_online;//是否在线 : 1在线 2离线
private String to_pit_number;
public String getTo_pit_number() {
return to_pit_number;
}
public void setTo_pit_number(String to_pit_number) {
this.to_pit_number = to_pit_number;
}
public int getIs_online() {
return is_online;
}
public void setIs_online(int is_online) {
this.is_online = is_online;
}
public int getBall_state() {
return ball_state;
}
public void setBall_state(int ball_state) {
this.ball_state = ball_state;
}
public int getCount_down() {
return count_down;
}
public void setCount_down(int count_down) {
this.count_down = count_down;
}
public RankInfo getRank_info() {
return rank_info;
}
public void setRank_info(RankInfo rank_info) {
this.rank_info = rank_info;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getRoom_id() {
return room_id;
}
public void setRoom_id(String room_id) {
this.room_id = room_id;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getPit_number() {
return pit_number;
}
public void setPit_number(String pit_number) {
this.pit_number = pit_number;
}
public String getVoice() {
return voice;
}
public void setVoice(String voice) {
this.voice = voice;
}
public String getShutup() {
return shutup;
}
public void setShutup(String shutup) {
this.shutup = shutup;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getHead_picture() {
return head_picture;
}
public void setHead_picture(String head_picture) {
this.head_picture = head_picture;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getEmchat_username() {
return emchat_username;
}
public void setEmchat_username(String emchat_username) {
this.emchat_username = emchat_username;
}
public String getRank_id() {
return rank_id;
}
public void setRank_id(String rank_id) {
this.rank_id = rank_id;
}
public String getNobility() {
return nobility;
}
public void setNobility(String nobility) {
this.nobility = nobility;
}
public String getXin_dong() {
return xin_dong;
}
public void setXin_dong(String xin_dong) {
this.xin_dong = xin_dong;
}
public String getBanned() {
return banned;
}
public void setBanned(String banned) {
this.banned = banned;
}
public String getDress_picture() {
return dress_picture;
}
public void setDress_picture(String dress_picture) {
this.dress_picture = dress_picture;
}
@Override
public String toString() {
return "RoomPitBean{" +
"id='" + id + '\'' +
", room_id='" + room_id + '\'' +
", user_id='" + user_id + '\'' +
", pit_number='" + pit_number + '\'' +
", voice='" + voice + '\'' +
", shutup='" + shutup + '\'' +
", state='" + state + '\'' +
", nickname='" + nickname + '\'' +
", head_picture='" + head_picture + '\'' +
", sex='" + sex + '\'' +
", emchat_username='" + emchat_username + '\'' +
", rank_id='" + rank_id + '\'' +
", nobility='" + nobility + '\'' +
", xin_dong='" + xin_dong + '\'' +
", banned='" + banned + '\'' +
", dress_picture='" + dress_picture + '\'' +
", rank_info=" + rank_info +
", count_down=" + count_down +
", ball_state=" + ball_state +
", is_online=" + is_online +
'}';
}
}

View File

@@ -0,0 +1,208 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
public class RoomUserBean implements Serializable {
/**
* banned : 0
* favorite : 0
* pit : 0
* voice : 0
* shutup : 0
*/
private int banned;
private int favorite;
private int pit;
private int voice;//1开 2关 麦克风
private int shutup;
private RankInfo rank_info;
private int show_cat;
private int guide;
private int mixer;
private int apply_wait;//是否排麦中1是 0否
private int role;
private String rank_icon;
private String nobility_icon;
private String nickname;
private String user_id;
private int user_is_new;
private int apply_wait_type;//1申请上老板位2申请上1-7号麦
private String charm_icon;
private int is_preside;//是否是主持人 1是 0否
public int getIs_preside() {
return is_preside;
}
public void setIs_preside(int is_preside) {
this.is_preside = is_preside;
}
public String getCharm_icon() {
return charm_icon;
}
public void setCharm_icon(String charm_icon) {
this.charm_icon = charm_icon;
}
public int getApply_wait_type() {
return apply_wait_type;
}
public void setApply_wait_type(int apply_wait_type) {
this.apply_wait_type = apply_wait_type;
}
public int getUser_is_new() {
return user_is_new;
}
public void setUser_is_new(int user_is_new) {
this.user_is_new = user_is_new;
}
private String ball;//a1,b1,c1l
private String room_id;
public int getRole() {
return role;
}
public void setRole(int role) {
this.role = role;
}
public String getRank_icon() {
return rank_icon;
}
public void setRank_icon(String rank_icon) {
this.rank_icon = rank_icon;
}
public String getNobility_icon() {
return nobility_icon;
}
public void setNobility_icon(String nobility_icon) {
this.nobility_icon = nobility_icon;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getRoom_id() {
return room_id;
}
public void setRoom_id(String room_id) {
this.room_id = room_id;
}
public String getBall() {
return ball;
}
public void setBall(String ball) {
this.ball = ball;
}
public int getApply_wait() {
return apply_wait;
}
public void setApply_wait(int apply_wait) {
this.apply_wait = apply_wait;
}
public int getMixer() {
return mixer;
}
public void setMixer(int mixer) {
this.mixer = mixer;
}
public int getGuide() {
return guide;
}
public void setGuide(int guide) {
this.guide = guide;
}
public int getShow_cat() {
return show_cat;
}
public void setShow_cat(int show_cat) {
this.show_cat = show_cat;
}
public RankInfo getRank_info() {
return rank_info;
}
public void setRank_info(RankInfo rank_info) {
this.rank_info = rank_info;
}
public int getBanned() {
return banned;
}
public void setBanned(int banned) {
this.banned = banned;
}
public int getFavorite() {
return favorite;
}
public void setFavorite(int favorite) {
this.favorite = favorite;
}
public int getPit() {
return pit;
}
public void setPit(int pit) {
this.pit = pit;
}
public int getVoice() {
return voice;
}
public void setVoice(int voice) {
this.voice = voice;
}
public int getShutup() {
return shutup;
}
public void setShutup(int shutup) {
this.shutup = shutup;
}
}

View File

@@ -0,0 +1,22 @@
package com.qxcm.moduleutil.bean.room;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoomUserJoinModel {
private String room_id;
private String user_id;
private String nickname;
private String rank_icon;
private String nobility_icon;
private int user_is_new;
private int role;
private String background;
private String color;
}

View File

@@ -0,0 +1,25 @@
package com.qxcm.moduleutil.bean.room;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoomWheatModel {
private String nickname;
private String user_id;
private String shutup;
private String banned;
private String head_picture;
private String dress_picture;
private String room_id;
private String pit_number;
private String emchat_username;
private String xin_dong;
private String sex;
private int ball_state;//1开0关
}

View File

@@ -0,0 +1,23 @@
package com.qxcm.moduleutil.bean.room;
import java.io.Serializable;
import lombok.Data;
@Data
public class SoundEffectResp implements Serializable {
private int id;
private String name;
private String info;
private String room_type;
private String rank_id;
private String status;
private String add_time;
private String icon;
private String icon_select;
private Config config;
}

View File

@@ -0,0 +1,16 @@
package com.qxcm.moduleutil.event;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoomBanWheatEvent {
private String roomId;
private String pit_number;
private boolean isBanWheat;
}

View File

@@ -0,0 +1,15 @@
package com.qxcm.moduleutil.event;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RoomBeckoningEvent {
private String roomId;
private boolean isOpen;
}

View File

@@ -0,0 +1,11 @@
package com.qxcm.moduleutil.event;
public class RoomCardiacValueChangedEvent {
public String pitNumber;
public String value;
public RoomCardiacValueChangedEvent() { this("", ""); }
public RoomCardiacValueChangedEvent(String pit, String value) {
this.pitNumber = pit;
this.value = value;
}
}

View File

@@ -0,0 +1,15 @@
package com.qxcm.moduleutil.event;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@Data
@NoArgsConstructor
public class RoomFaceEvent {
private String room_id;
private String pit_number;
private String special;
private double time;
}

View File

@@ -0,0 +1,158 @@
package com.qxcm.moduleutil.interfaces;
import com.qxcm.moduleutil.base.RoomRollModel;
import com.qxcm.moduleutil.bean.room.ClosePhone;
import com.qxcm.moduleutil.bean.room.RoomClearCardiacAllModel;
import com.qxcm.moduleutil.bean.room.RoomClearCardiacModel;
import com.qxcm.moduleutil.bean.room.RoomClosePitModel;
import com.qxcm.moduleutil.bean.room.RoomCountDownModel;
import com.qxcm.moduleutil.bean.room.RoomDownWheatModel;
import com.qxcm.moduleutil.bean.room.RoomGiveGiftModel;
import com.qxcm.moduleutil.bean.room.RoomWheatModel;
import com.qxcm.moduleutil.bean.room.RoomPitBean;
import com.qxcm.moduleutil.event.RoomBanWheatEvent;
import com.qxcm.moduleutil.event.RoomBeckoningEvent;
import com.qxcm.moduleutil.event.RoomFaceEvent;
/**
* 项目名称 qipao-android
* 包名com.qpyy.room.widget
* 创建人 王欧
* 创建时间 2020/8/14 10:51 AM
* 描述 describe
*/
public interface IBaseWheat extends SoundLevelUpdateListener {
void register(Object obj);
void unRegister(Object obj);
void setCardiac(String rough_number, float bl);
void clearCardiac();
void setData(RoomPitBean pitBean);
boolean isOn();
void showGift(RoomGiveGiftModel.GiftListBean listBean);
/**
* 麦位心动值
*
* @param cardiacListBean
*/
void subscribeMessages(RoomGiveGiftModel.CardiacListBean cardiacListBean);
/**
* 房间心动值开关变化通知 1开2关
*
* @param roomBeckoningEvent
*/
void subscribeMessages(RoomBeckoningEvent roomBeckoningEvent);
/**
* 清空单个麦位心动值
*
* @param roomClearCardiacModel
*/
void subscribeMessages(RoomClearCardiacModel roomClearCardiacModel);
/**
* 清空所有麦位心动值
*
* @param roomClearCardiacAllModel
*/
void subscribeMessages(RoomClearCardiacAllModel roomClearCardiacAllModel);
/**
* 房间内上麦
*
* @param roomWheatModel
*/
void subscribeMessages(RoomWheatModel roomWheatModel);
/**
* 房间内下麦
*
* @param roomDownWheatModel
*/
void subscribeMessages(RoomDownWheatModel roomDownWheatModel);
/**
* 麦位倒计时
*
* @param roomCountDownModel
*/
void subscribeMessages(RoomCountDownModel roomCountDownModel);
/**
* 禁麦麦位数据
*
* @param roomBanWheatEvent
*/
void subscribeMessages(RoomBanWheatEvent roomBanWheatEvent);
/**
* 是否封麦 1封麦2解封
*
* @param roomClosePitModel
*/
void subscribeMessages(RoomClosePitModel roomClosePitModel);
/**
* 麦位表情
*
* @param roomFaceEvent
*/
void subscribeMessages(RoomFaceEvent roomFaceEvent);
/**
* 抽签
*
* @param roomRollModel
*/
void subscribeMessages(RoomRollModel roomRollModel);
// /**
// * 开球
// *
// * @param event
// */
// void subscribeMessages(QiuGameStartEvent event);
//
// /**
// * 气球
// *
// * @param event
// */
// void subscribeMessages(QiuGameEndEvent event);
//
// /**
// * 亮球
// *
// * @param event
// */
// void subscribeMessages(QiuGameResultEvent event);
/**
* closePhone
*
* @param closePhone
*/
void subscribeMessages(ClosePhone closePhone);
/**
* 是否锁麦
*
* @return
*/
boolean isLocked();
/**
* 是否主持
*
* @return
*/
boolean isHost();
}

View File

@@ -0,0 +1,8 @@
package com.qxcm.moduleutil.interfaces;
public interface SoundLevelUpdateListener {
/**
* 远端拉流音频声浪回调
*/
void onRemoteSoundLevelUpdate(String userId, int soundLevel);
}

View File

@@ -8,6 +8,7 @@ public class ARouteConstants {
public static final String USER_ALBUM_DETAIL = "/modulevocal/AlbumDetailActivity";
public static final String CREATE_ALBUM = "/modulevocal/CreateAlbumActivity";
public static final String ROOM_DETAILS = "/moduleroom/RoomActivity";
public static final String FRAGMENT_CIRCLE = "CirleListFragment";

View File

@@ -0,0 +1,153 @@
package com.qxcm.moduleutil.utils;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.view.View;
import com.blankj.utilcode.util.ConvertUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.qxcm.moduleutil.widget.animator.ExplosionField;
public class GiftAnimatorUtil {
public static ObjectAnimator tada(View view) {
return tada(view, 1f);
}
public static void tadaAnim(View view) {
ObjectAnimator tada = tada(view, 1f);
tada.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
new ExplosionField(view.getContext()).explode(view, new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(GONE);
}
});
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
tada.start();
}
public static void anim(View view, float oX, float oY) {
if (SpUtil.getOpenEffect() == 0) {
return;
}
view.setVisibility(VISIBLE);
view.setTranslationX(0);
view.setTranslationY(0);
ObjectAnimator tada = tada(view);
PropertyValuesHolder objectAnimatorY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, ScreenUtils.getScreenHeight(), oY);
int x = ScreenUtils.getScreenWidth() / 2;
PropertyValuesHolder objectAnimatorX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, x, oX);
ObjectAnimator valueAnimator = ObjectAnimator.ofPropertyValuesHolder(view, objectAnimatorY, objectAnimatorX).
setDuration(500);
AnimatorSet set = new AnimatorSet();
set.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
if (Math.abs(view.getY() - oY) < ConvertUtils.dp2px(50)) {
new ExplosionField(view.getContext()).explode(view, new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(GONE);
}
});
} else {
view.setVisibility(GONE);
}
}
@Override
public void onAnimationCancel(Animator animator) {
view.setVisibility(GONE);
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
set.playSequentially(valueAnimator, tada);
set.start();
}
public static ObjectAnimator tada(View view, float shakeFactor) {
PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofKeyframe(View.SCALE_X,
Keyframe.ofFloat(0f, 1f),
Keyframe.ofFloat(.1f, .9f),
Keyframe.ofFloat(.2f, .9f),
Keyframe.ofFloat(.3f, 1.1f),
Keyframe.ofFloat(.4f, 1.1f),
Keyframe.ofFloat(.5f, 1.1f),
Keyframe.ofFloat(.6f, 1.1f),
Keyframe.ofFloat(.7f, 1.1f),
Keyframe.ofFloat(.8f, 1.1f),
Keyframe.ofFloat(.9f, 1.1f),
Keyframe.ofFloat(1f, 1f)
);
PropertyValuesHolder pvhScaleY = PropertyValuesHolder.ofKeyframe(View.SCALE_Y,
Keyframe.ofFloat(0f, 1f),
Keyframe.ofFloat(.1f, .9f),
Keyframe.ofFloat(.2f, .9f),
Keyframe.ofFloat(.3f, 1.1f),
Keyframe.ofFloat(.4f, 1.1f),
Keyframe.ofFloat(.5f, 1.1f),
Keyframe.ofFloat(.6f, 1.1f),
Keyframe.ofFloat(.7f, 1.1f),
Keyframe.ofFloat(.8f, 1.1f),
Keyframe.ofFloat(.9f, 1.1f),
Keyframe.ofFloat(1f, 1f)
);
PropertyValuesHolder pvhRotate = PropertyValuesHolder.ofKeyframe(View.ROTATION,
Keyframe.ofFloat(0f, 0f),
Keyframe.ofFloat(.1f, -3f * shakeFactor),
Keyframe.ofFloat(.2f, -3f * shakeFactor),
Keyframe.ofFloat(.3f, 3f * shakeFactor),
Keyframe.ofFloat(.4f, -3f * shakeFactor),
Keyframe.ofFloat(.5f, 3f * shakeFactor),
Keyframe.ofFloat(.6f, -3f * shakeFactor),
Keyframe.ofFloat(.7f, 3f * shakeFactor),
Keyframe.ofFloat(.8f, -3f * shakeFactor),
Keyframe.ofFloat(.9f, 3f * shakeFactor),
Keyframe.ofFloat(1f, 0)
);
return ObjectAnimator.ofPropertyValuesHolder(view, pvhScaleX, pvhScaleY, pvhRotate).
setDuration(1000);
}
}

View File

@@ -0,0 +1,587 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.os.CountDownTimer;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.opensource.svgaplayer.SVGAImageView;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.base.RoomRollModel;
import com.qxcm.moduleutil.bean.FaceBean;
import com.qxcm.moduleutil.bean.room.ClosePhone;
import com.qxcm.moduleutil.bean.room.RoomClearCardiacAllModel;
import com.qxcm.moduleutil.bean.room.RoomClearCardiacModel;
import com.qxcm.moduleutil.bean.room.RoomClosePitModel;
import com.qxcm.moduleutil.bean.room.RoomCountDownModel;
import com.qxcm.moduleutil.bean.room.RoomDownWheatModel;
import com.qxcm.moduleutil.bean.room.RoomGiveGiftModel;
import com.qxcm.moduleutil.bean.room.RoomPitBean;
import com.qxcm.moduleutil.bean.room.RoomWheatModel;
import com.qxcm.moduleutil.event.RoomBanWheatEvent;
import com.qxcm.moduleutil.event.RoomBeckoningEvent;
import com.qxcm.moduleutil.event.RoomCardiacValueChangedEvent;
import com.qxcm.moduleutil.event.RoomFaceEvent;
import com.qxcm.moduleutil.interfaces.IBaseWheat;
import com.qxcm.moduleutil.utils.SpUtil;
import com.qxcm.moduleutil.utils.logger.Logger;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
public abstract class BaseWheatView extends ConstraintLayout implements IBaseWheat {
public ImageView mRiv;
public ImageView mIvGift;
public WheatCharmView mCharmView;
public TextView mTvName;
public ImageView mIvSex;
public SVGAImageView mIvFrame;
public SVGAImageView mIvRipple;
public ExpressionImgView mIvFace;
public ImageView mIvShutup;
public TextView tvTime;
public TextView mTvNo;
public RoomPitBean pitBean;//麦位数据
public String roomId;//房间id
CountDownTimer mCountDownTimer;
public static final String WHEAT_BOSS = "8";//老板位
public static final String WHEAT_HOST = "9";//主持位
public float oX;
public float oY;
boolean closePhone = false;//自己麦位关闭话筒,用于判断声纹显示
public String pitNumber;
public ImageView iv_zhul;
public ImageView iv_on_line;
private boolean showGiftAnim = true;//显示麦位动画
public BaseWheatView(Context context) {
this(context, null, 0);
}
public BaseWheatView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BaseWheatView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflate(context, getLayoutId(), this);
mRiv = findViewById(R.id.riv);
mIvGift = findViewById(R.id.iv_gift);
mCharmView = findViewById(R.id.charm_view);
mTvName = findViewById(R.id.tv_name);
mIvSex = findViewById(R.id.iv_sex);
mIvFrame = findViewById(R.id.iv_frame);
mIvRipple = findViewById(R.id.iv_ripple);
mIvFace = findViewById(R.id.iv_face);
mIvShutup = findViewById(R.id.iv_shutup);
tvTime = findViewById(R.id.tv_time);
mTvNo = findViewById(R.id.tv_no);
iv_zhul = findViewById(R.id.iv_zhul);
iv_on_line = findViewById(R.id.iv_online);
setClipChildren(false);
setClipToPadding(false);
oX = mIvGift.getX();
oY = mIvGift.getY();
initPit(context, attrs);
}
protected abstract void initPit(Context context, AttributeSet attrs);
protected abstract int getLayoutId();
protected abstract void setPitData(RoomPitBean bean);
protected float getTzbl() {
return 0.0f;
}
private @DrawableRes int mOriginImage = 0;
private @DrawableRes int mOriginNoImage = 0;
public @DrawableRes int getOriginImage() {
return mOriginImage;
}
public @DrawableRes int getOriginNoImage() {
return mOriginNoImage;
}
public void setImageResource(@DrawableRes int image, @DrawableRes int noImage, CharSequence no) {
mOriginImage = image;
mOriginNoImage = noImage;
mRiv.setImageResource(mOriginImage);
if (mTvNo != null) {
mTvNo.setText(no);
mTvNo.setBackgroundResource(mOriginNoImage);
mTvNo.setVisibility(VISIBLE);
}
}
/**
* 设置麦位数据
*
* @param bean
*/
@Override
@Subscribe(threadMode = ThreadMode.MAIN)
public void setData(RoomPitBean bean) {
if (!pitNumber.equals(bean.getPit_number())) {
return;
}
this.pitBean = bean;
this.roomId = bean.getRoom_id();
countDownTime(bean.getCount_down());
setCardiac(pitBean.getXin_dong(), getTzbl());
setPitData(bean);
if (bean.getIs_online()==2){
iv_on_line.setVisibility(VISIBLE);
}else {
iv_on_line.setVisibility(GONE);
}
// if (isOn() && bean.getBall_state() == 1) {
// gameImgView.startGame();
// } else {
// gameImgView.overGame();
// }
//心动值
//显示心动
if ("1".equals(pitBean.getShutup())) {
mIvShutup.setVisibility(VISIBLE);
} else {
mIvShutup.setVisibility(GONE);
}
//自动调节麦位波纹
if (!TextUtils.isEmpty(bean.getDress_picture())) {
mIvRipple.setScaleX(1.1f);
mIvRipple.setScaleY(1.1f);
} else {
mIvRipple.setScaleX(0.9f);
mIvRipple.setScaleY(0.9f);
}
}
/**
* 开始倒计时
*
* @param time
*/
public void countDownTime(int time) {
try {
if (time <= 0) {
setTime(0);
releaseCountDownTimer();
return;
}
releaseCountDownTimer();
mCountDownTimer = new CountDownTimer(time * 1000L, 1000L) {
@Override
public void onTick(long millisUntilFinished) {
int time1 = (int) (millisUntilFinished / 1000);
pitBean.setCount_down(time1);
setTime(time1);
}
@Override
public void onFinish() {
setTime(0);
}
};
mCountDownTimer.start();
} catch (Exception e) {
Logger.e("countDownTime", e);
}
}
public void setTime(int time) {
if (time == 0) {
tvTime.setText("");
tvTime.setVisibility(View.INVISIBLE);
} else {
tvTime.setText(String.format("%s'%s", time / 60, time % 60));
tvTime.setVisibility(View.VISIBLE);
}
}
@Override
protected void onAttachedToWindow() {
showGiftAnim = true;
super.onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
showGiftAnim = false;
releaseCountDownTimer();
super.onDetachedFromWindow();
}
/**
* 释放倒计时
*/
private void releaseCountDownTimer() {
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
mCountDownTimer = null;
}
}
/**
* 麦位是否有人
*
* @return
*/
@Override
public boolean isOn() {
return pitBean != null && !TextUtils.isEmpty(pitBean.getUser_id()) && !"0".equals(pitBean.getUser_id());
}
/**
* 显示麦位礼物动画
*
* @param listBean
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void showGift(RoomGiveGiftModel.GiftListBean listBean) {
if (!showGiftAnim) {
mIvGift.setVisibility(GONE);
return;
}
if (listBean.getUser_id() == null || !listBean.getUser_id().equals(pitBean.getUser_id())) {
return;
}
// ImageUtils.loadImageView(listBean.getPicture(), mIvGift);
WheatGiftAnim.addGift(mIvGift, listBean.getPicture());
}
/**
* 设置心动值
*
* @param rough_number
*/
@Override
public void setCardiac(String rough_number, float bl) {
if (mCharmView != null) {
pitBean.setXin_dong(rough_number);
mCharmView.setSex(pitBean.getSex(), pitBean.getUser_id(), pitBean.getXin_dong(), false);
//
// } else {
// try {
// String d = pitBean.getXin_dong();
// long xd = Long.parseLong(d);
// if (xd <= 0) {
// mCharmView.setSex(pitBean.getSex(), pitBean.getUser_id(), d, false);
// } else {
// float xxd = xd * bl;
// mCharmView.setSex(pitBean.getSex(), pitBean.getUser_id(), String.format(Locale.CHINESE, "%sx%.2f=%.2f", d, bl, xxd), true);
// }
// } catch (Exception e) {
// mCharmView.setSex(pitBean.getSex(), pitBean.getUser_id(), pitBean.getXin_dong(), false);
// }
// }
EventBus.getDefault().post(new RoomCardiacValueChangedEvent(pitNumber, pitBean.getXin_dong()));
}
}
/**
* 清空心动值
*/
@Override
public void clearCardiac() {
if (mCharmView != null) {
pitBean.setXin_dong("0");
mCharmView.setSex(pitBean.getSex(), pitBean.getUser_id(), pitBean.getXin_dong(), false);
EventBus.getDefault().post(new RoomCardiacValueChangedEvent(pitNumber, pitBean.getXin_dong()));
}
}
public int getCardiac() {
if (pitBean == null) {
return 0;
} else {
try {
return Integer.parseInt(pitBean.getXin_dong());
} catch (Throwable e) {
return 0;
}
}
}
@Override
public void register(Object obj) {
EventBus.getDefault().register(this);
// RtcManager.getInstance().addSoundLevelListener(this);
}
@Override
public void unRegister(Object obj) {
// RtcManager.getInstance().removeSoundLevelListener(this);
EventBus.getDefault().unregister(this);
}
/**
* 心动值显示开关
*
* @param roomBeckoningEvent
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomBeckoningEvent roomBeckoningEvent) {
if (roomId.equals(roomBeckoningEvent.getRoomId())) {
mCharmView.setVisibility(roomBeckoningEvent.isOpen() ? VISIBLE : INVISIBLE);
}
}
/**
* 心动值变化
*
* @param cardiacListBean
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomGiveGiftModel.CardiacListBean cardiacListBean) {
if (!roomId.equals(cardiacListBean.getRoom_id())) {
return;
}
if (this.pitNumber.equals(cardiacListBean.getPit_number())) {
this.setCardiac(cardiacListBean.getXin_dong(), getTzbl());
}
}
/**
* 清空单个麦位心动值
*
* @param roomClearCardiacModel
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomClearCardiacModel roomClearCardiacModel) {
if (!roomId.equals(roomClearCardiacModel.getRoom_id())) {
return;
}
if (this.pitNumber.equals(roomClearCardiacModel.getPit_number())) {
clearCardiac();
}
}
/**
* 清空所有心动值
*
* @param roomClearCardiacAllModel
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomClearCardiacAllModel roomClearCardiacAllModel) {
if (!roomId.equals(roomClearCardiacAllModel.getRoom_id())) {
return;
}
clearCardiac();
}
/**
* 上麦
*
* @param roomWheatModel
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomWheatModel roomWheatModel) {
if (!roomId.equals(roomWheatModel.getRoom_id()) || !pitNumber.equals(roomWheatModel.getPit_number())) {
return;
}
pitBean.setNickname(roomWheatModel.getNickname());
pitBean.setHead_picture(roomWheatModel.getHead_picture());
pitBean.setBanned(roomWheatModel.getBanned());
pitBean.setUser_id(roomWheatModel.getUser_id());
pitBean.setDress_picture(roomWheatModel.getDress_picture());
pitBean.setSex(roomWheatModel.getSex());
pitBean.setBall_state(roomWheatModel.getBall_state());
pitBean.setPit_number(roomWheatModel.getPit_number());
pitBean.setXin_dong(roomWheatModel.getXin_dong());
setData(pitBean);
}
/**
* 下麦
*
* @param roomDownWheatModel
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomDownWheatModel roomDownWheatModel) {
if (!roomId.equals(roomDownWheatModel.getRoom_id()) || !pitNumber.equals(roomDownWheatModel.getPit_number())) {
return;
}
closePhone = SpUtil.getUserId()==roomDownWheatModel.getUser_id();
pitBean.setUser_id("0");
pitBean.setPit_number(roomDownWheatModel.getPit_number());
setData(pitBean);
}
/**
* 倒计时
*
* @param roomCountDownModel
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomCountDownModel roomCountDownModel) {
if (!roomId.equals(roomCountDownModel.getRoom_id()) || !pitNumber.equals(roomCountDownModel.getPit_number())) {
return;
}
pitBean.setCount_down(roomCountDownModel.getSeconds());
countDownTime(roomCountDownModel.getSeconds());
}
/**
* 禁麦
*
* @param roomBanWheatEvent
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomBanWheatEvent roomBanWheatEvent) {
if (!roomId.equals(roomBanWheatEvent.getRoomId()) || !pitNumber.equals(roomBanWheatEvent.getPit_number())) {
return;
}
pitBean.setShutup(roomBanWheatEvent.isBanWheat() ? "1" : "2");
setData(pitBean);
}
/**
* 锁麦
*
* @param roomClosePitModel
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomClosePitModel roomClosePitModel) {
if (!roomId.equals(roomClosePitModel.getRoom_id()) || !pitNumber.equals(roomClosePitModel.getPit_number())) {
return;
}
pitBean.setState(roomClosePitModel.getAction());
//麦位上锁
setData(pitBean);
}
/**
* 用户关闭麦克风
*
* @param closePhone
*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void subscribeMessages(ClosePhone closePhone) {
if (pitBean.getUser_id().equals(SpUtil.getUserId())) {
this.closePhone = closePhone.isClosePhone();
}
}
/**
* 麦位是否被锁
*
* @return
*/
@Override
public boolean isLocked() {
return !isOn() && "1".equals(pitBean.getState());
}
/**
* 表情
*
* @param roomFaceEvent
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomFaceEvent roomFaceEvent) {
if (!roomId.equals(roomFaceEvent.getRoom_id()) || !pitNumber.equals(roomFaceEvent.getPit_number())) {
return;
}
mIvFace.addData(new FaceBean(roomFaceEvent.getSpecial(), roomFaceEvent.getTime(), 1));
}
/**
* 抽签
*
* @param roomRollModel
*/
@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void subscribeMessages(RoomRollModel roomRollModel) {
if (!roomId.equals(roomRollModel.getRoom_id()) || !pitNumber.equals(roomRollModel.getPit_number())) {
return;
}
mIvFace.addData(new FaceBean(roomRollModel.getNumber(), 2));
}
/**
* 球球大作战开球
*
* @param event
*/
/**
* 是否主持
*
* @return
*/
@Override
public boolean isHost() {
return WHEAT_HOST.equals(pitNumber);
}
@Override
public void onRemoteSoundLevelUpdate(String userId, int volume) {
if (userId.equals(pitBean.getUser_id())) {
if (volume == 0) {
mIvRipple.post(() -> {
mIvRipple.setVisibility(GONE);
});
} else {
mIvRipple.post(() -> {
if (!mIvRipple.isAnimating()) {
mIvRipple.startAnimation();
}
mIvRipple.setVisibility(VISIBLE);
});
}
if (pitBean.getUser_id().equals(SpUtil.getUserId()) && closePhone) {
mIvRipple.post(() -> {
mIvRipple.setVisibility(GONE);
});
}
}
}
}

View File

@@ -0,0 +1,211 @@
package com.qxcm.moduleutil.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.ColorRes;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.qxcm.moduleutil.R;
/**
* 圆形进度条控件
* Author: JueYes jueyes_1024@163.com
* Time: 2019-08-07 15:38
*/
public class CircularProgressView extends View {
private Paint mBackPaint, mProgPaint; // 绘制画笔
private RectF mRectF; // 绘制区域
private int[] mColorArray; // 圆环渐变色
private int mProgress; // 圆环进度(0-100)
public CircularProgressView(Context context) {
this(context, null);
}
public CircularProgressView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CircularProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
@SuppressLint("Recycle")
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularProgressView);
// 初始化背景圆环画笔
mBackPaint = new Paint();
mBackPaint.setStyle(Paint.Style.STROKE); // 只描边,不填充
mBackPaint.setStrokeCap(Paint.Cap.ROUND); // 设置圆角
mBackPaint.setAntiAlias(true); // 设置抗锯齿
mBackPaint.setDither(true); // 设置抖动
mBackPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_backWidth, 5));
mBackPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_backColor, Color.LTGRAY));
// 初始化进度圆环画笔
mProgPaint = new Paint();
mProgPaint.setStyle(Paint.Style.STROKE); // 只描边,不填充
mProgPaint.setStrokeCap(Paint.Cap.ROUND); // 设置圆角
mProgPaint.setAntiAlias(true); // 设置抗锯齿
mProgPaint.setDither(true); // 设置抖动
mProgPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_progWidth, 10));
mProgPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_progColor, Color.BLUE));
// 初始化进度圆环渐变色
int startColor = typedArray.getColor(R.styleable.CircularProgressView_progStartColor, -1);
int firstColor = typedArray.getColor(R.styleable.CircularProgressView_progFirstColor, -1);
if (startColor != -1 && firstColor != -1) mColorArray = new int[]{startColor, firstColor};
else mColorArray = null;
// 初始化进度
mProgress = typedArray.getInteger(R.styleable.CircularProgressView_progress, 0);
typedArray.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int viewWide = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
int viewHigh = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
int mRectLength = (int) ((viewWide > viewHigh ? viewHigh : viewWide) - (mBackPaint.getStrokeWidth() > mProgPaint.getStrokeWidth() ? mBackPaint.getStrokeWidth() : mProgPaint.getStrokeWidth()));
int mRectL = getPaddingLeft() + (viewWide - mRectLength) / 2;
int mRectT = getPaddingTop() + (viewHigh - mRectLength) / 2;
mRectF = new RectF(mRectL, mRectT, mRectL + mRectLength, mRectT + mRectLength);
// 设置进度圆环渐变色
if (mColorArray != null && mColorArray.length > 1)
mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(mRectF, 0, 360, false, mBackPaint);
canvas.drawArc(mRectF, 275, 360 * mProgress / 1000, false, mProgPaint);
}
// ---------------------------------------------------------------------------------------------
/**
* 获取当前进度
*
* @return 当前进度0-100
*/
public int getProgress() {
return mProgress;
}
/**
* 设置当前进度
*
* @param progress 当前进度0-100
*/
public void setProgress(int progress) {
this.mProgress = progress;
invalidate();
}
// /**
// * 设置当前进度并展示进度动画。如果动画时间小于等于0则不展示动画
// *
// * @param progress 当前进度0-100
// * @param animTime 动画时间(毫秒)
// */
// public void setProgress(int progress, long animTime) {
// if (animTime <= 0) setProgress(progress);
// else {
// ValueAnimator animator = ValueAnimator.ofInt(mProgress, progress);
// animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
// @Override
// public void onAnimationUpdate(ValueAnimator animation) {
// mProgress = (int) animation.getAnimatedValue();
// invalidate();
// }
// });
// animator.setInterpolator(new OvershootInterpolator());
// animator.setDuration(animTime);
// animator.start();
// }
// }
/**
* 设置背景圆环宽度
*
* @param width 背景圆环宽度
*/
public void setBackWidth(int width) {
mBackPaint.setStrokeWidth(width);
invalidate();
}
/**
* 设置背景圆环颜色
*
* @param color 背景圆环颜色
*/
public void setBackColor(@ColorRes int color) {
mBackPaint.setColor(ContextCompat.getColor(getContext(), color));
invalidate();
}
/**
* 设置进度圆环宽度
*
* @param width 进度圆环宽度
*/
public void setProgWidth(int width) {
mProgPaint.setStrokeWidth(width);
invalidate();
}
/**
* 设置进度圆环颜色
*
* @param color 景圆环颜色
*/
public void setProgColor(@ColorRes int color) {
mProgPaint.setColor(ContextCompat.getColor(getContext(), color));
mProgPaint.setShader(null);
invalidate();
}
/**
* 设置进度圆环颜色(支持渐变色)
*
* @param startColor 进度圆环开始颜色
* @param firstColor 进度圆环结束颜色
*/
public void setProgColor(@ColorRes int startColor, @ColorRes int firstColor) {
mColorArray = new int[]{ContextCompat.getColor(getContext(), startColor), ContextCompat.getColor(getContext(), firstColor)};
mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
invalidate();
}
/**
* 设置进度圆环颜色(支持渐变色)
*
* @param colorArray 渐变色集合
*/
public void setProgColor(@ColorRes int[] colorArray) {
if (colorArray == null || colorArray.length < 2) return;
mColorArray = new int[colorArray.length];
for (int index = 0; index < colorArray.length; index++)
mColorArray[index] = ContextCompat.getColor(getContext(), colorArray[index]);
mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
invalidate();
}
}

View File

@@ -0,0 +1,130 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;
import com.bumptech.glide.integration.webp.decoder.WebpDrawable;
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.SimpleTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import com.qxcm.moduleutil.bean.FaceBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ExpressionImgView extends AppCompatImageView {
private Context mContext;
private Runnable goneCmd = new Runnable() {
@Override
public void run() {
setVisibility(GONE);
}
};
public ExpressionImgView(Context context) {
this(context, null);
}
public ExpressionImgView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ExpressionImgView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
}
public void addData(FaceBean faceBean) {
setVisibility(VISIBLE);
removeCallbacks(goneCmd);
if (faceBean.getType() == 1) {
String url = faceBean.getFace_spectial();
if (TextUtils.isEmpty(url)) {
return;
}
GlideApp.with(mContext).load(url).listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
postDelayed(goneCmd, faceBean.getMillTime() == 0 ? 3000 : Math.max(faceBean.getMillTime(), 1000));
return false;
}
}).skipMemoryCache(true).into(this);
} else {
GlideApp.with(mContext).load(String.format("http://soundriver.oss-cn-hangzhou.aliyuncs.com/custom/random%ss.webp", faceBean.getNumber())).into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable drawable, @Nullable Transition<? super Drawable> transition) {
if (drawable instanceof WebpDrawable) {
ExpressionImgView.this.setImageDrawable(drawable);
((WebpDrawable) drawable).start();
((WebpDrawable) drawable).setLoopCount(1);
((WebpDrawable) drawable).registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
@Override
public void onAnimationEnd(Drawable drawable) {
super.onAnimationEnd(drawable);
postDelayed(goneCmd, 500);
}
});
}
}
});
}
}
private int getWebpPlayTime(Drawable resource) {
WebpDrawable webpDrawable = (WebpDrawable) resource;
try {
Field gifStateField = WebpDrawable.class.getDeclaredField("state");
gifStateField.setAccessible(true);
Class gifStateClass = Class.forName("com.bumptech.glide.integration.webp.decoder.WebpDrawable$WebpState");
Field gifFrameLoaderField = gifStateClass.getDeclaredField("frameLoader");
gifFrameLoaderField.setAccessible(true);
Class gifFrameLoaderClass = Class.forName("com.bumptech.glide.integration.webp.decoder.WebpFrameLoader");
Field gifDecoderField = gifFrameLoaderClass.getDeclaredField("webpDecoder");
gifDecoderField.setAccessible(true);
Class gifDecoderClass = Class.forName("com.bumptech.glide.integration.webp.decoder.WebpDecoder");
Object gifDecoder = gifDecoderField.get(gifFrameLoaderField.get(gifStateField.get(resource)));
Method getDelayMethod = gifDecoderClass.getDeclaredMethod("getDelay", int.class);
getDelayMethod.setAccessible(true);
// 设置只播放一次
// 获得总帧数
int count = webpDrawable.getFrameCount();
int delay = 0;
for (int i = 0; i < count; i++) {
// 计算每一帧所需要的时间进行累加
delay += (int) getDelayMethod.invoke(gifDecoder, i);
}
return delay;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
public void remove() {
setVisibility(GONE);
}
}

View File

@@ -0,0 +1,66 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import androidx.databinding.DataBindingUtil;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.databinding.RoomViewMusicRatationBinding;
import com.qxcm.moduleutil.widget.floatingView.FloatingMagnetView;
public class MusicRotationView extends FloatingMagnetView {
private RoomViewMusicRatationBinding mBinding;
public MusicRotationView(Context context) {
this(context, null, 0);
}
public MusicRotationView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MusicRotationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.room_view_music_ratation,this,true);
}
/**
* 开启图片旋转动画
*/
public void startRotateAnimation() {
Animation rotateAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.image_rotate);
LinearInterpolator lin = new LinearInterpolator();
rotateAnimation.setInterpolator(lin);
mBinding.rivAvatar.setAnimation(rotateAnimation);
mBinding.rivAvatar.setVisibility(View.VISIBLE);
}
@Override
public void setVisibility(int visibility) {
super.setVisibility(visibility);
if (visibility == GONE) {
// RtcManager.getInstance().setAudioUrl(null);
}
}
/**
* 关闭图片旋转动画
*/
public void endRotateAnimation() {
mBinding.rivAvatar.clearAnimation();
mBinding.rivAvatar.setAnimation(null);
mBinding.rivAvatar.setVisibility(View.VISIBLE);
}
@Override
protected boolean isNearestLeft() {
return true;
}
}

View File

@@ -0,0 +1,292 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.SeekBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.databinding.RoomDialogMusicWindowOpenBinding;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MusicView extends FrameLayout {
private Context mContext;
private int playPattern = 1; //1循环播放 2单曲循环 3随机播放
private boolean isPaly = false;
// private MusicTable mMusicTable;
private OnItemClickListener mOnItemClickListener;
// private List<MusicTable> musicTables = new ArrayList<>();
private RoomDialogMusicWindowOpenBinding mBinding;
public MusicView(@NonNull Context context) {
super(context);
initView(context);
}
public MusicView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public MusicView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
this.mContext = context;
mBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.room_dialog_music_window_open,this,true);
// playPattern = SpUtils.getPlayPattern();
initListener();
switch (playPattern) {
case 1:
// mBinding.ivPattern.setImageResource(R.mipmap.room_music_win_circulation);
break;
case 2:
mBinding.ivPattern.setImageResource(R.mipmap.room_music_win_singlecircle);
break;
case 3:
// mBinding.ivPattern.setImageResource(R.mipmap.room_music_win_random);
break;
}
// mBinding.seekBar.setProgress(SpUtils.getChannelVolume());
mBinding.ivMinx.setOnClickListener(this::onClick);
mBinding.ivMusicPlayState.setOnClickListener(this::onClick);
mBinding.ivList.setOnClickListener(this::onClick);
mBinding.ivNext.setOnClickListener(this::onClick);
mBinding.ivLast.setOnClickListener(this::onClick);
mBinding.ivPattern.setOnClickListener(this::onClick);
mBinding.flParent.setOnClickListener(this::onMusicDismiss);
mBinding.rlPlayRegion.setOnClickListener(this::onRegion);
}
private void initListener() {
mBinding.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
if (b) {
if (progress < 0) {
progress = 0;
}
if (progress > 100) {
progress = 100;
}
if (mOnItemClickListener != null) {
mOnItemClickListener.setMusicVolume((int) (progress * 0.6));
}
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
//icon_music_stop
public void setPalyState(boolean b) {
this.isPaly = b;
if (isPaly) {
// mBinding.ivMusicPlayState.setImageResource(R.mipmap.room_music_win_start);
} else {
mBinding.ivMusicPlayState.setImageResource(R.mipmap.room_music_win_puase);
}
}
// public void setData(MusicTable musicTable) {
// this.mMusicTable = musicTable;
// mBinding.tvMusicTitle.setText(mMusicTable.getTitle());
// mBinding.tvSinger.setText(mMusicTable.getAuthor());
// }
public void onClick(View view) {
int id = view.getId();
if (id == R.id.iv_minx) {
if (mOnItemClickListener != null) {
mOnItemClickListener.minimize();
}
} else if (id == R.id.iv_list) {
if (mOnItemClickListener != null) {
mOnItemClickListener.openMusicList();
}
} else if (id == R.id.iv_music_play_state) {
if (mOnItemClickListener != null) {
if (isPaly) {
mOnItemClickListener.pausePlay();
} else {
mOnItemClickListener.resumePlay();
}
}
} else if (id == R.id.iv_next) {
next();
} else if (id == R.id.iv_last) {
last();
} else if (id == R.id.iv_pattern) {
if (playPattern == 1) {
playPattern = 2;
} else if (playPattern == 2) {
playPattern = 3;
} else if (playPattern == 3) {
playPattern = 1;
}
switch (playPattern) {
case 1:
// mBinding.ivPattern.setImageResource(R.mipmap.room_music_win_circulation);
break;
case 2:
mBinding.ivPattern.setImageResource(R.mipmap.room_music_win_singlecircle);
break;
case 3:
// mBinding.ivPattern.setImageResource(R.mipmap.room_music_win_random);
break;
}
// SpUtils.setPlayPattern(playPattern);
}
}
public void addOnItemClickListener(OnItemClickListener onItemClickListener) {
this.mOnItemClickListener = onItemClickListener;
}
// public void setMusicList(List<MusicTable> lovalMusicData) {
// this.musicTables = lovalMusicData;
// }
public interface OnItemClickListener {
void minimize();
void openMusicList();
// void playMusic(MusicTable musicTable);
void stopPlay();
void pausePlay();
void resumePlay();
void setMusicVolume(int progress);
}
// public void initData() {
// musicTables = DbController.getInstance(mContext).queryMusicListAll();
// }
public void next() {
// initData();
// if (musicTables.size() == 0) {
// return;
// }
// musicTables.size();
// int index = 0;
// if (mMusicTable != null) {
// for (int i = 0; i < musicTables.size(); i++) {
// if (mMusicTable.getId().equals(musicTables.get(i).getId())) {
// index = i;
// break;
// }
// }
// }
// //下一首播放逻辑
// if (playPattern == 1) {//列表循环
// index++;
// } else if (playPattern == 3) {//随机播放
// if (musicTables.size() > 1) {
// Random random = new Random();
// index = random.nextInt(musicTables.size() - 1);
// }
// }
//
// if (index == musicTables.size()) {
// mMusicTable = musicTables.get(0);
// } else {
// mMusicTable = musicTables.get(index);
// }
// if (mOnItemClickListener != null) {
// mOnItemClickListener.playMusic(mMusicTable);
// }
// setData(mMusicTable);
}
public void last() {
// initData();
// int index = 0;
// for (int i = 0; i < musicTables.size(); i++) {
// if (mMusicTable.getId().equals(musicTables.get(i).getId())) {
// index = i;
// break;
// }
// }
// //上一首播放逻辑
// if (playPattern == 1) {//列表循环
// index--;
// } else if (playPattern == 3) {//随机播放
// Random random = new Random();
// index = random.nextInt(musicTables.size() - 1);
// }
// if (index <= 0) {
// mMusicTable = musicTables.get(musicTables.size() - 1);
// } else {
// mMusicTable = musicTables.get(index);
// }
// if (mOnItemClickListener != null) {
// mOnItemClickListener.playMusic(mMusicTable);
// }
// setData(mMusicTable);
}
/**
* 更新轮循方式
*/
public void updateLoopType(int type) {
playPattern = type;
// if (type == 1) {
// mBinding.ivPattern.setImageResource(R.mipmap.room_music_win_circulation);
// } else if (type == 2) {
// mBinding.ivPattern.setImageResource(R.mipmap.room_music_win_singlecircle);
// } else {
// mBinding.ivPattern.setImageResource(R.mipmap.room_music_win_random);
// }
}
/**
* 点击外部弹窗消失
*/
public void onMusicDismiss(View view) {
if (mOnItemClickListener != null) {
mOnItemClickListener.minimize();
}
}
/**
* 点击播放器内部无效
*/
public void onRegion(View view) {
}
}

View File

@@ -0,0 +1,47 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatImageView;
import com.qxcm.moduleutil.R;
public class NewView extends AppCompatImageView {
private Context mContext;
public NewView(Context context) {
super(context);
initView(context);
}
public NewView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public NewView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
this.mContext = context;
}
public void setNew(int isNew) {
if (isNew == 0) {
this.setVisibility(GONE);
} else if (isNew == 1) {
this.setVisibility(VISIBLE);
setImageResource(R.mipmap.ic_user_new);
}
}
}

View File

@@ -0,0 +1,38 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatImageView;
public class NobilityView extends AppCompatImageView {
private Context mContext;
public NobilityView(Context context) {
super(context);
initView(context);
}
public NobilityView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public NobilityView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
this.mContext = context;
}
public void setNobility(String url) {
setVisibility(TextUtils.isEmpty(url) ? GONE : VISIBLE);
com.qxcm.moduleutil.utils.ImageUtils.loadImageView(url, this);
}
}

View File

@@ -0,0 +1,55 @@
package com.qxcm.moduleutil.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import com.qxcm.moduleutil.R;
@SuppressLint("AppCompatCustomView")
public class RoleView extends ImageView {
private Context mContext;
public RoleView(Context context) {
super(context);
initView(context);
}
public RoleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public RoleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
this.mContext = context;
// setVisibility(GONE);
// setImageResource(R.mipmap.img_host);
}
public void setRole(int role) {
this.setVisibility(VISIBLE);
if (role == 1) {
setImageResource(R.mipmap.img_host);
} else if (role == 2) {
setImageResource(R.mipmap.img_admin);
} else if (role == 5) {
setImageResource(R.mipmap.img_official);
} else {
this.setVisibility(GONE);
}
}
}

View File

@@ -0,0 +1,160 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.bean.UserInfo;
import com.qxcm.moduleutil.bean.room.RoomPitBean;
import com.qxcm.moduleutil.utils.ImageUtils;
/**
* 项目名称 qipao-android
* 包名com.yutang.xqipao.utils.view
* 创建人 王欧
* 创建时间 2020/4/9 12:46 PM
* 描述 describe
*/
public class RoomDefaultWheatView extends BaseWheatView {
public ImageView mIvTagBoss;
public TextView mTvTime;
private boolean showBoss;//显示老板标识
public RoomDefaultWheatView(Context context) {
this(context, null, 0);
}
public RoomDefaultWheatView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoomDefaultWheatView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void initPit(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoomDefaultWheatView);
pitNumber = typedArray.getString(R.styleable.RoomDefaultWheatView_room_wheat_number);
typedArray.recycle();
mIvTagBoss = findViewById(R.id.iv_tag_boos);
mTvTime = findViewById(R.id.tv_time);
}
@Override
protected int getLayoutId() {
return R.layout.room_view_default_wheat;
}
@Override
protected void setPitData(RoomPitBean bean) {
sex = bean.getSex();
if (isOn()) {
//开启声浪
mIvRipple.stopAnimation();
mIvRipple.setVisibility(VISIBLE);
mTvName.setText(bean.getNickname());
ImageUtils.loadHeadCC(bean.getHead_picture(), mRiv);
if (TextUtils.isEmpty(pitBean.getDress_picture())) {
mIvFrame.setVisibility(INVISIBLE);
} else {
mIvFrame.setVisibility(VISIBLE);
ImageUtils.loadDecorationAvatar(pitBean.getDress_picture(), mIvFrame);
}
if (showBoss && WHEAT_BOSS.equals(pitNumber)) {
mIvTagBoss.setVisibility(GONE);
}
} else {
mTvName.setText("");
//麦位上锁
if (showBoss && WHEAT_BOSS.equals(pitNumber)) {
// mIvTagBoss.setVisibility(VISIBLE);
ImageUtils.loadRes(isLocked() ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default, mRiv);
} else {
mIvTagBoss.setVisibility(GONE);
@DrawableRes int origin = getOriginImage();
ImageUtils.loadRes(isLocked() ? R.mipmap.room_ic_wheat_default_suo :
(origin == 0 ? R.mipmap.room_ic_wheat_default : origin), mRiv);
}
mIvFrame.setVisibility(INVISIBLE);
mIvFace.remove();
//停止声浪
mIvRipple.stopAnimation();
mIvRipple.setVisibility(GONE);
}
if (showSexIcon) {
checkSex();
}
}
private boolean showSexIcon = false;
private String sex;
public boolean isMale() {
return "1".equals(sex);
}
public boolean isFemale() {
return "2".equals(sex);
}
public void setShowSexIcon(boolean show) {
showSexIcon = show;
}
public void checkSex() {
if (isOn()) {
mIvSex.setVisibility(VISIBLE);
if (!TextUtils.isEmpty(sex)) {
if (UserInfo.MALE.equals(sex)) {
mIvSex.setBackgroundResource(R.drawable.room_xq_wheat_male_mask);
if (mTvNo != null) mTvNo.setBackgroundResource(R.mipmap.ic_room_xq_wno_male);
} else {
mIvSex.setBackgroundResource(R.drawable.room_xq_wheat_female_mask);
if (mTvNo != null) mTvNo.setBackgroundResource(R.mipmap.ic_room_xq_wno_female);
}
} else {
mIvSex.setVisibility(GONE);
if (mTvNo != null) mTvNo.setBackgroundResource(getOriginNoImage());
}
} else {
mIvSex.setVisibility(GONE);
if (mTvNo != null) mTvNo.setBackgroundResource(getOriginNoImage());
}
}
/**
* 是否显示老板标识
*/
public void setIsBossShow(String is_boss_pit) {
showBoss = "1".equals(is_boss_pit);
}
/**
* 开启计时
*/
public void setTime(int time) {
if (time == 0) {
mTvTime.setText("");
mTvTime.setVisibility(INVISIBLE);
} else {
mTvTime.setText(String.format("%s'%s", time / 60, time % 60));
mTvTime.setVisibility(VISIBLE);
}
}
public void hideMaoziIcon() {
View maozi = findViewById(R.id.iv_maozi);
if (maozi != null) maozi.setVisibility(GONE);
}
}

View File

@@ -0,0 +1,123 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.os.CountDownTimer;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.blankj.utilcode.util.KeyboardUtils;
import com.hjq.toast.ToastUtils;
import com.qxcm.moduleutil.R;
import org.greenrobot.eventbus.EventBus;
import io.reactivex.disposables.Disposable;
public class RoomMessageInputMenu extends ConstraintLayout {
EditText etContent;
Button tvSend;
public RoomMessageInputMenu(Context context) {
this(context, null);
}
public RoomMessageInputMenu(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.room_message_input_menu, this);
etContent = findViewById(R.id.et_content);
tvSend = findViewById(R.id.tv_send);
tvSend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onViewClicked(v);
}
});
setVisibility(GONE);
}
public void onViewClicked(View view) {
if (!canSend) {
ToastUtils.show("消息发送较频繁~");
return;
}
String text = etContent.getText().toString();
if (TextUtils.isEmpty(text)) {
ToastUtils.show("请输入评论内容");
return;
}
// ApiClient.getInstance().sendTxtFilter(text,new BaseObserver<String>() {
// @Override
// public void onSubscribe(Disposable d) {
//
// }
//
// @Override
// public void onNext(String s) {
// EventBus.getDefault().post(new RoomInputEvent(s));
// }
//
// @Override
// public void onComplete() {
//
// }
// });
etContent.setText("");
countDownTimer();
dismiss();
}
/**
* 下面的内容为发送消息逻辑
*/
private CountDownTimer mCountDownTimer;
private boolean canSend = true;
private void countDownTimer() {
releaseCountDownTimer();
mCountDownTimer = new CountDownTimer(3 * 1000L, 1000L) {
@Override
public void onTick(long millisUntilFinished) {
canSend = false;
}
@Override
public void onFinish() {
canSend = true;
}
};
mCountDownTimer.start();
}
@Override
protected void onDetachedFromWindow() {
releaseCountDownTimer();
super.onDetachedFromWindow();
}
private void releaseCountDownTimer() {
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
mCountDownTimer = null;
}
}
public void show() {
setVisibility(VISIBLE);
etContent.requestFocus();
KeyboardUtils.showSoftInput(etContent);
// EventBus.getDefault().post(new RoomInputHideEvent(false));
}
public void dismiss() {
setVisibility(GONE);
KeyboardUtils.hideSoftInput(etContent);
// EventBus.getDefault().post(new RoomInputHideEvent(true));
}
}

View File

@@ -0,0 +1,143 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.graphics.Color;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.databinding.DataBindingUtil;
import com.blankj.utilcode.util.ConvertUtils;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.bean.room.RoomUserJoinModel;
import com.qxcm.moduleutil.databinding.RoomViewWelcomeAnimViewBinding;
import com.qxcm.moduleutil.utils.ImageUtils;
import com.qxcm.moduleutil.utils.SpUtil;
import java.util.LinkedList;
import java.util.Queue;
/**
*@author qx
*@data 2025/6/9
*@description: 进场公屏
*/
public class WelcomeAnimView extends ConstraintLayout implements Animation.AnimationListener {
private Animation mAnimation;
public boolean animEnded = true;
private RoomViewWelcomeAnimViewBinding mBinding;
public WelcomeAnimView(Context context) {
this(context, null);
}
public WelcomeAnimView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.room_view_welcome_anim_view, this, true);
setVisibility(GONE);
mAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.room_anim_set_welcome);
mAnimation.setFillAfter(true);
mAnimation.setAnimationListener(this);
}
public void showAnim() {
if (SpUtil.getOpenEffect() == 0) {
return;
}
if (queue == null || queue.size() == 0) {
return;
}
if (animEnded) {
RoomUserJoinModel animBean = queue.poll();
if (animBean != null) {
// mIvRole.setRole(animBean.getRole());
// mIvNew.setVisibility(animBean.getUser_is_new() == 1 ? VISIBLE : GONE);
mBinding.tvName.setText(animBean.getNickname());
// mIvNobility.setVisibility(TextUtils.isEmpty(animBean.getNobility_icon()) ? GONE : VISIBLE);
// ImageUtils.loadImageView(animBean.getNobility_icon(), mIvNobility);
mBinding.ivRank.setVisibility(TextUtils.isEmpty(animBean.getRank_icon()) ? GONE : VISIBLE);
ImageUtils.loadImageView(animBean.getRank_icon(), mBinding.ivRank);
}
setVisibility(VISIBLE);
//加入房间背景 和 字体颜色
LayoutParams infoParams = (LayoutParams) mBinding.llInfo.getLayoutParams();
if (!TextUtils.isEmpty(animBean.getBackground())) {
mBinding.ivUserInto.setVisibility(VISIBLE);
mBinding.llInfo.setBackgroundResource(R.drawable.bg_r10_transparent);
infoParams.leftMargin = ConvertUtils.dp2px(74);
ImageUtils.loadImageView(animBean.getBackground(), mBinding.ivUserInto);
} else {
infoParams.leftMargin = 0;
mBinding.llInfo.setBackgroundResource(R.drawable.room_bg_welcome_anim);
mBinding.ivUserInto.setVisibility(INVISIBLE);
}
mBinding.llInfo.setLayoutParams(infoParams);
if (!TextUtils.isEmpty(animBean.getColor())) {
try {
mBinding.tvEndTxt.setTextColor(Color.parseColor(animBean.getColor()));
mBinding.tvName.setTextColor(Color.parseColor(animBean.getColor()));
} catch (Exception e) {
mBinding.tvEndTxt.setTextColor(Color.WHITE);
mBinding.tvName.setTextColor(Color.WHITE);
e.printStackTrace();
}
} else {
mBinding.tvEndTxt.setTextColor(Color.WHITE);
mBinding.tvName.setTextColor(Color.WHITE);
}
this.startAnimation(mAnimation);
}
}
public void addAnim(RoomUserJoinModel bean) {
if (SpUtil.getOpenEffect() == 0) {
return;
}
if (queue.size() == 0) {
queue.add(bean);
showAnim();
} else {
queue.add(bean);
}
}
private Queue<RoomUserJoinModel> queue = new LinkedList<>();
@Override
public void onAnimationStart(Animation animation) {
animEnded = false;
}
@Override
public void onAnimationEnd(Animation animation) {
animEnded = true;
showAnim();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
/**
* 关闭特效
*/
public void closeEffect() {
//清空队列
queue.clear();
//关闭动画
if (mAnimation != null && !animEnded) {
animEnded = true;
mAnimation.cancel();
}
}
}

View File

@@ -0,0 +1,48 @@
package com.qxcm.moduleutil.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;
import androidx.databinding.DataBindingUtil;
import com.qxcm.moduleutil.R;
import com.qxcm.moduleutil.databinding.RoomViewWheatCharmBinding;
public class WheatCharmView extends RelativeLayout {
private RoomViewWheatCharmBinding mBinding;
public WheatCharmView(Context context) {
this(context, null);
}
public WheatCharmView(Context context, AttributeSet attrs) {
super(context, attrs);
mBinding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.room_view_wheat_charm, this, true);
setClipChildren(false);
setClipToPadding(false);
}
public void setSex(String sex, String userId, String value, boolean format) {
if (format) {
mBinding.tvValue.setText(value);
} else {
try {
long xd = Long.parseLong(value);
if (xd > 9999 || xd < -9999) {
mBinding.tvValue.setText(String.format("%.2fw", xd / 10000.0f));
// mBinding.tvValue.setText(String.valueOf(xd));
} else {
mBinding.tvValue.setText(value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,75 @@
package com.qxcm.moduleutil.widget;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import com.blankj.utilcode.util.ScreenUtils;
import com.qxcm.moduleutil.utils.GiftAnimatorUtil;
import com.qxcm.moduleutil.utils.ImageUtils;
public class WheatGiftAnim {
public static void addGift(View targetView, String imageUrl) {
final int[] location = new int[2];
targetView.getLocationOnScreen(location);
ImageView imageView = new ImageView(targetView.getContext());
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(targetView.getWidth(), targetView.getHeight());
imageView.setLayoutParams(params);
ImageUtils.loadImageView(imageUrl, imageView);
attach2Activity((Activity) targetView.getContext(), imageView);
ObjectAnimator tada = GiftAnimatorUtil.tada(imageView);
PropertyValuesHolder objectAnimatorY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, ScreenUtils.getScreenHeight(), location[1]);
PropertyValuesHolder objectAnimatorX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, ScreenUtils.getScreenWidth() / 2f, location[0]);
ObjectAnimator valueAnimator = ObjectAnimator.ofPropertyValuesHolder(imageView, objectAnimatorY, objectAnimatorX).
setDuration(1200);
AnimatorSet set = new AnimatorSet();
set.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
removeFromActivity(imageView);
}
@Override
public void onAnimationCancel(Animator animator) {
removeFromActivity(imageView);
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
set.playSequentially(valueAnimator, tada);
set.start();
}
/**
* 将创建的ExplosionField添加到Activity上
*/
private static void attach2Activity(Activity activity, View view) {
ViewGroup rootView = activity.findViewById(Window.ID_ANDROID_CONTENT);
rootView.addView(view);
}
/**
* 将ExplosionField从Activity上移除
*
* @param imageView
*/
private static void removeFromActivity(ImageView imageView) {
ViewGroup rootView = ((Activity) imageView.getContext()).findViewById(Window.ID_ANDROID_CONTENT);
rootView.removeView(imageView);
}
}

View File

@@ -0,0 +1,86 @@
package com.qxcm.moduleutil.widget.animator;
import android.animation.ValueAnimator;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.View;
/**
* 说明:爆炸动画类,让离子移动和控制离子透明度
* 作者Jian
* 时间2017/12/26.
*/
class ExplosionAnimator extends ValueAnimator {
private static final int DEFAULT_DURATION = 3000;
private ParticleModel[][] mParticles;
private Paint mPaint;
private View mContainer;
public ExplosionAnimator(View view, Bitmap bitmap, Rect bound) {
setFloatValues(0.0f, 1.0f);
setDuration(DEFAULT_DURATION);
mPaint = new Paint();
mContainer = view;
mParticles = generateParticles(bitmap, bound);
}
// 生成粒子,按行按列生成全部粒子
private ParticleModel[][] generateParticles(Bitmap bitmap, Rect bound) {
int w = bound.width();
int h = bound.height();
// 横向粒子的个数
int horizontalCount = w / ParticleModel.PART_WH;
// 竖向粒子的个数
int verticalCount = h / ParticleModel.PART_WH;
// 粒子宽度
int bitmapPartWidth = horizontalCount == 0 ? 0 : bitmap.getWidth() / horizontalCount;
// 粒子高度
int bitmapPartHeight = verticalCount == 0 ? 0 : bitmap.getHeight() / verticalCount;
ParticleModel[][] particles = new ParticleModel[verticalCount][horizontalCount];
for (int row = 0; row < verticalCount; row++) {
for (int column = 0; column < horizontalCount; column++) {
//取得当前粒子所在位置的颜色
int color = bitmap.getPixel(column * bitmapPartWidth, row * bitmapPartHeight);
Point point = new Point(column, row);
particles[row][column] = new ParticleModel(color, bound, point);
}
}
return particles;
}
// 由view调用在View上绘制全部的粒子
void draw(Canvas canvas) {
// 动画结束时停止
if (!isStarted()) {
return;
}
// 遍历粒子并绘制在View上
for (ParticleModel[] particle : mParticles) {
for (ParticleModel p : particle) {
p.advance((Float) getAnimatedValue());
mPaint.setColor(p.color);
// 错误的设置方式只是这样设置,透明色会显示为黑色
// mPaint.setAlpha((int) (255 * p.alpha));
// 正确的设置方式,这样透明颜色就不是黑色了
mPaint.setAlpha((int) (Color.alpha(p.color) * p.alpha));
canvas.drawCircle(p.cx, p.cy, p.radius, mPaint);
}
}
mContainer.invalidate();
}
@Override
public void start() {
super.start();
mContainer.invalidate();
}
}

View File

@@ -0,0 +1,118 @@
package com.qxcm.moduleutil.widget.animator;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import com.blankj.utilcode.util.BarUtils;
public class ExplosionField extends View {
private static final String TAG = "ExplosionField";
private static final Canvas mCanvas = new Canvas();
private ExplosionAnimator animator;
public ExplosionField(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
animator.draw(canvas);
}
/**
* 执行爆破破碎动画
*/
public void explode(final View view, final AnimatorListenerAdapter listener) {
Rect rect = new Rect();
view.getGlobalVisibleRect(rect); //得到view相对于整个屏幕的坐标
rect.offset(0, -BarUtils.getStatusBarHeight()); //去掉状态栏高度
if (rect.width() == 0 || rect.height() == 0) {
return;
}
animator = new ExplosionAnimator(this, createBitmapFromView(view), rect);
// 接口回调
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
if (listener != null) listener.onAnimationStart(animation);
// 延时添加到界面上
attach2Activity((Activity) getContext());
// 让被爆炸的View消失爆炸的View是新创建的View原View本身不会发生任何变化
view.animate().alpha(0f).setDuration(150).start();
}
@Override
public void onAnimationEnd(Animator animation) {
if (listener != null) listener.onAnimationEnd(animation);
// 从界面中移除
removeFromActivity((Activity) getContext());
// 让被爆炸的View显示爆炸的View是新创建的View原View本身不会发生任何变化
view.animate().alpha(1f).setDuration(150).start();
}
@Override
public void onAnimationCancel(Animator animation) {
if (listener != null) listener.onAnimationCancel(animation);
}
@Override
public void onAnimationRepeat(Animator animation) {
if (listener != null) listener.onAnimationRepeat(animation);
}
});
animator.start();
}
private Bitmap createBitmapFromView(View view) {
// 为什么屏蔽以下代码段?
// 如果ImageView直接得到位图那么当它设置背景backgroud)时,不会读取到背景颜色
// if (view instanceof ImageView) {
// Drawable drawable = ((ImageView)view).getDrawable();
// if (drawable != null && drawable instanceof BitmapDrawable) {
// return ((BitmapDrawable) drawable).getBitmap();
// }
// }
//view.clearFocus(); //不同焦点状态显示的可能不同——azz:不同就不同有什么关系?)
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
if (bitmap != null) {
synchronized (mCanvas) {
mCanvas.setBitmap(bitmap);
view.draw(mCanvas);
// 清除引用
mCanvas.setBitmap(null);
}
}
return bitmap;
}
/**
* 将创建的ExplosionField添加到Activity上
*/
private void attach2Activity(Activity activity) {
ViewGroup rootView = activity.findViewById(Window.ID_ANDROID_CONTENT);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
rootView.addView(this, lp);
}
/**
* 将ExplosionField从Activity上移除
*/
private void removeFromActivity(Activity activity) {
ViewGroup rootView = activity.findViewById(Window.ID_ANDROID_CONTENT);
rootView.removeView(this);
}
}

View File

@@ -0,0 +1,54 @@
package com.qxcm.moduleutil.widget.animator;
import android.graphics.Point;
import android.graphics.Rect;
import com.blankj.utilcode.util.ConvertUtils;
import java.util.Random;
/**
* 说明:爆破粒子,每个移动与渐变的小块
* 作者Jian
* 时间2017/12/26.
*/
class ParticleModel {
// 默认小球宽高
static final int PART_WH = ConvertUtils.dp2px(5);
// 随机数,随机出位置和大小
static Random random = new Random();
//center x of circle
float cx;
//center y of circle
float cy;
// 半径
float radius;
// 颜色
int color;
// 透明度
float alpha;
// 整体边界
Rect mBound;
ParticleModel(int color, Rect bound, Point point) {
int row = point.y; //行是高
int column = point.x; //列是宽
this.mBound = bound;
this.color = color;
this.alpha = 1f;
this.radius = PART_WH;
this.cx = bound.left + PART_WH * column;
this.cy = bound.top + PART_WH * row;
}
// 每一步动画都得重新计算出自己的状态值
void advance(float factor) {
cx = cx + factor * random.nextInt(mBound.width()) * (random.nextFloat() - 0.5f);
cy = cy + factor * random.nextInt(mBound.height() / 2);
radius = radius - factor * random.nextInt(2);
alpha = (1f - factor) * (1 + random.nextFloat());
}
}

View File

@@ -0,0 +1,31 @@
package com.qxcm.moduleutil.widget.animator;
import android.view.animation.Interpolator;
/**
* ProjectName: FarmDemo-master
* Package: com.lantern.core.myapplication
* Description: 弹簧插值器
* Author: 姚闻达
* CreateDate: 2020/11/10 17:50
* UpdateUser: 更新者
* UpdateDate: 2020/11/10 17:50
* UpdateRemark: 更新说明
* Version: 1.0
*/
public class SpringInterpolator implements Interpolator {
//控制弹簧系数
private float factor;
public SpringInterpolator(float factor) {
this.factor = factor;
}
@Override
public float getInterpolation(float input) {
//factor = 0.4
// pow(2, -10 * x) * sin((x - factor / 4) * (2 * PI) / factor) + 1
return (float) -(Math.pow(2, -10 * input) * Math.sin((input - factor / 4) * (2 * Math.PI) / factor) );
}
}

View File

@@ -0,0 +1,26 @@
package com.qxcm.moduleutil.widget.animator;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
/**
* ProjectName: FarmDemo-master
* Package: com.lantern.core.myapplication
* Description: java类作用描述
* Author: 姚闻达
* CreateDate: 2020/11/10 17:51
* UpdateUser: 更新者
* UpdateDate: 2020/11/10 17:51
* UpdateRemark: 更新说明
* Version: 1.0
*/
public class TreeAnimation {
public static Animation getAnimation() {
// 创建缩放的动画对象
ScaleAnimation sa = new ScaleAnimation(1f, 1.0f, 1.0f, 1.1f, ScaleAnimation.RELATIVE_TO_SELF, 0.0f, ScaleAnimation.RELATIVE_TO_SELF, 1.0f);
// 设置动画播放的时间
sa.setDuration(1500);
sa.setInterpolator(new SpringInterpolator(0.3f));
return sa;
}
}

View File

@@ -0,0 +1,89 @@
package com.qxcm.moduleutil.widget.animator;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.blankj.utilcode.util.ConvertUtils;
import com.qpyy.libcommon.R;
import com.qpyy.libcommon.utils.GiftAnimatorUtil;
import com.qpyy.libcommon.utils.ImageUtils;
import java.util.Random;
public class TreeRewardAnim extends ConstraintLayout {
public TreeRewardAnim(Context context) {
super(context);
}
public TreeRewardAnim(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TreeRewardAnim(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void doAnim(String imageUrl) {
View view = inflate(getContext(), R.layout.room_view_water_tree_gift_anim, null);
view.setScaleX(0.5f);
view.setScaleY(0.5f);
ImageView imageView = view.findViewById(R.id.image);
LayoutParams params = new LayoutParams(ConvertUtils.dp2px(77), ConvertUtils.dp2px(75));
params.startToStart = LayoutParams.PARENT_ID;
params.endToEnd = LayoutParams.PARENT_ID;
params.topToTop = LayoutParams.PARENT_ID;
params.bottomToBottom = LayoutParams.PARENT_ID;
view.setLayoutParams(params);
addView(view);
ImageUtils.loadImageView(imageUrl, imageView);
ObjectAnimator tada = GiftAnimatorUtil.tada(view);
PropertyValuesHolder objectAnimatorY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, view.getY(), view.getY() - new Random().nextInt(ConvertUtils.dp2px(100)));
int max = this.getRight(), min = this.getLeft();
int ran2 = new Random().nextInt(max - min + 1) + min;
int random = new Random().nextInt(4);
int x = new Random().nextInt(ConvertUtils.dp2px(120));
if (random > 1) {
x = -x;
}
PropertyValuesHolder objectAnimatorX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, view.getX(), x);
ObjectAnimator valueAnimator = ObjectAnimator.ofPropertyValuesHolder(view, objectAnimatorY, objectAnimatorX).
setDuration(1000);
PropertyValuesHolder scaleAnimatorY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 0.5f, 1);
PropertyValuesHolder scaleAnimatorX = PropertyValuesHolder.ofFloat(View.SCALE_X, 0.5f, 1);
ObjectAnimator scaleAnimator = ObjectAnimator.ofPropertyValuesHolder(view, scaleAnimatorY, scaleAnimatorX).
setDuration(1000);
AnimatorSet set = new AnimatorSet();
set.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
removeView(view);
}
@Override
public void onAnimationCancel(Animator animator) {
removeView(view);
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
set.playSequentially(valueAnimator, scaleAnimator, tada);
set.start();
}
}

View File

@@ -0,0 +1,75 @@
package com.qxcm.moduleutil.widget.animator;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import com.blankj.utilcode.util.ScreenUtils;
import com.qpyy.libcommon.utils.GiftAnimatorUtil;
import com.qpyy.libcommon.utils.ImageUtils;
public class WheatGiftAnim {
public static void addGift(View targetView, String imageUrl) {
final int[] location = new int[2];
targetView.getLocationOnScreen(location);
ImageView imageView = new ImageView(targetView.getContext());
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(targetView.getWidth(), targetView.getHeight());
imageView.setLayoutParams(params);
ImageUtils.loadImageView(imageUrl, imageView);
attach2Activity((Activity) targetView.getContext(), imageView);
ObjectAnimator tada = GiftAnimatorUtil.tada(imageView);
PropertyValuesHolder objectAnimatorY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, ScreenUtils.getScreenHeight(), location[1]);
PropertyValuesHolder objectAnimatorX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, ScreenUtils.getScreenWidth() / 2f, location[0]);
ObjectAnimator valueAnimator = ObjectAnimator.ofPropertyValuesHolder(imageView, objectAnimatorY, objectAnimatorX).
setDuration(1200);
AnimatorSet set = new AnimatorSet();
set.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
removeFromActivity(imageView);
}
@Override
public void onAnimationCancel(Animator animator) {
removeFromActivity(imageView);
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
set.playSequentially(valueAnimator, tada);
set.start();
}
/**
* 将创建的ExplosionField添加到Activity上
*/
private static void attach2Activity(Activity activity, View view) {
ViewGroup rootView = activity.findViewById(Window.ID_ANDROID_CONTENT);
rootView.addView(view);
}
/**
* 将ExplosionField从Activity上移除
*
* @param imageView
*/
private static void removeFromActivity(ImageView imageView) {
ViewGroup rootView = ((Activity) imageView.getContext()).findViewById(Window.ID_ANDROID_CONTENT);
rootView.removeView(imageView);
}
}

View File

@@ -0,0 +1,178 @@
package com.qxcm.moduleutil.widget.floatingView;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import com.blankj.utilcode.util.BarUtils;
import com.blankj.utilcode.util.ScreenUtils;
/**
* 可拖拽悬浮
*/
public class FloatingMagnetView extends FrameLayout {
public static final int MARGIN_EDGE = 0;
private float mOriginalRawX;
private float mOriginalRawY;
private float mOriginalX;
private float mOriginalY;
private static final int TOUCH_TIME_THRESHOLD = 150;
private long mLastTouchDownTime;
protected MoveAnimator mMoveAnimator;
protected int mScreenWidth;
private int mScreenHeight;
private int mStatusBarHeight;
private boolean isNearestLeft = true;
public FloatingMagnetView(Context context) {
this(context, null);
}
public FloatingMagnetView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FloatingMagnetView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mMoveAnimator = new MoveAnimator();
mStatusBarHeight = BarUtils.getStatusBarHeight();
setClickable(true);
updateSize();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event == null) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
changeOriginalTouchParams(event);
updateSize();
mMoveAnimator.stop();
break;
case MotionEvent.ACTION_MOVE:
updateViewPosition(event);
break;
case MotionEvent.ACTION_UP:
moveToEdge();
if (isOnClickEvent()) {
if (listener != null) {
listener.onClick();
}
}
break;
}
return true;
}
protected boolean isOnClickEvent() {
return System.currentTimeMillis() - mLastTouchDownTime < TOUCH_TIME_THRESHOLD;
}
private void updateViewPosition(MotionEvent event) {
setX(mOriginalX + event.getRawX() - mOriginalRawX);
// 限制不可超出屏幕高度
float desY = mOriginalY + event.getRawY() - mOriginalRawY;
if (desY < mStatusBarHeight) {
desY = mStatusBarHeight;
}
if (desY > mScreenHeight - getHeight()) {
desY = mScreenHeight - getHeight();
}
setY(desY);
}
private void changeOriginalTouchParams(MotionEvent event) {
mOriginalX = getX();
mOriginalY = getY();
mOriginalRawX = event.getRawX();
mOriginalRawY = event.getRawY();
mLastTouchDownTime = System.currentTimeMillis();
}
protected void updateSize() {
mScreenWidth = (ScreenUtils.getScreenWidth() - this.getWidth());
mScreenHeight = ScreenUtils.getScreenHeight();
}
public void moveToEdge() {
moveToEdge(isNearestLeft());
}
public void moveToEdge(boolean isLeft) {
float moveDistance = isLeft ? MARGIN_EDGE : mScreenWidth - MARGIN_EDGE;
mMoveAnimator.start(moveDistance, getY());
}
protected boolean isNearestLeft() {
int middle = mScreenWidth / 2;
isNearestLeft = getX() < middle;
return isNearestLeft;
}
protected class MoveAnimator implements Runnable {
private Handler handler = new Handler(Looper.getMainLooper());
private float destinationX;
private float destinationY;
private long startingTime;
void start(float x, float y) {
this.destinationX = x;
this.destinationY = y;
startingTime = System.currentTimeMillis();
handler.post(this);
}
@Override
public void run() {
if (getRootView() == null || getRootView().getParent() == null) {
return;
}
float progress = Math.min(1, (System.currentTimeMillis() - startingTime) / 400f);
float deltaX = (destinationX - getX()) * progress;
float deltaY = (destinationY - getY()) * progress;
move(deltaX, deltaY);
if (progress < 1) {
handler.post(this);
}
}
private void stop() {
handler.removeCallbacks(this);
}
}
private void move(float deltaX, float deltaY) {
setX(getX() + deltaX);
setY(getY() + deltaY);
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateSize();
moveToEdge(isNearestLeft);
}
public void setListener(OnFloatingClickListener listener) {
this.listener = listener;
}
private OnFloatingClickListener listener;
public interface OnFloatingClickListener {
void onClick();
}
}

View File

@@ -0,0 +1,197 @@
package com.qxcm.moduleutil.widget.floatingView;
import android.app.Activity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import androidx.annotation.LayoutRes;
import androidx.core.view.ViewCompat;
import com.qxcm.moduleutil.base.CommonAppContext;
import java.lang.ref.WeakReference;
/**
* @ClassName FloatingView
* @Description 悬浮窗管理器
*/
public class FloatingView implements IFloatingView {
private View mFloatingView;
private static volatile FloatingView mInstance;
private WeakReference<FrameLayout> mContainer;
@LayoutRes
private int mLayoutId;
private ViewGroup.LayoutParams mLayoutParams = getParams();
private FloatingView() {
}
public static FloatingView get() {
if (mInstance == null) {
synchronized (FloatingView.class) {
if (mInstance == null) {
mInstance = new FloatingView();
}
}
}
return mInstance;
}
@Override
public FloatingView remove() {
orderId = 0;
if (mFloatingView == null) {
return this;
}
if (ViewCompat.isAttachedToWindow(mFloatingView) && getContainer() != null) {
getContainer().removeView(mFloatingView);
}
mFloatingView = null;
return this;
}
private void ensureFloatingView() {
synchronized (this) {
if (mFloatingView != null) {
addViewToWindow(mFloatingView);
return;
}
View view = LayoutInflater.from(CommonAppContext.getInstance()).inflate(mLayoutId, null);
mFloatingView = view;
view.setLayoutParams(mLayoutParams);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
addViewToWindow(view);
}
}
@Override
public FloatingView add() {
ensureFloatingView();
return this;
}
@Override
public FloatingView attach(Activity activity) {
attach(getActivityRoot(activity));
return this;
}
@Override
public FloatingView attach(FrameLayout container) {
if (container == null || mFloatingView == null) {
mContainer = new WeakReference<>(container);
return this;
}
if (mFloatingView.getParent() == container) {
return this;
}
if (getContainer() != null && mFloatingView.getParent() == getContainer()) {
getContainer().removeView(mFloatingView);
}
mContainer = new WeakReference<>(container);
container.addView(mFloatingView);
return this;
}
@Override
public FloatingView detach(Activity activity) {
detach(getActivityRoot(activity));
return this;
}
@Override
public FloatingView detach(FrameLayout container) {
if (mFloatingView != null && container != null && ViewCompat.isAttachedToWindow(mFloatingView)) {
container.removeView(mFloatingView);
}
if (getContainer() == container) {
mContainer = null;
}
return this;
}
@Override
public View getView() {
return mFloatingView;
}
@Override
public FloatingView customView(ViewGroup viewGroup) {
mFloatingView = viewGroup;
return this;
}
@Override
public FloatingView customView(@LayoutRes int resource) {
mLayoutId = resource;
return this;
}
@Override
public FloatingView layoutParams(ViewGroup.LayoutParams params) {
mLayoutParams = params;
if (mFloatingView != null) {
mFloatingView.setLayoutParams(params);
}
return this;
}
private void addViewToWindow(final View view) {
if (getContainer() == null) {
return;
}
getContainer().addView(view);
}
private FrameLayout getContainer() {
if (mContainer == null) {
return null;
}
return mContainer.get();
}
private FrameLayout.LayoutParams getParams() {
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM | Gravity.START;
params.setMargins(13, params.topMargin, params.rightMargin, 500);
return params;
}
private FrameLayout getActivityRoot(Activity activity) {
if (activity == null) {
return null;
}
try {
return (FrameLayout) activity.getWindow().getDecorView().findViewById(android.R.id.content);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private boolean isExpand = true;
/**
* 设置展开或者收起
*
* @param expand
*/
public void setExpand(boolean expand) {
isExpand = expand;
}
private int orderId;
}

View File

@@ -0,0 +1,33 @@
package com.qxcm.moduleutil.widget.floatingView;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.LayoutRes;
public interface IFloatingView {
FloatingView remove();
FloatingView add();
FloatingView attach(Activity activity);
FloatingView attach(FrameLayout container);
FloatingView detach(Activity activity);
FloatingView detach(FrameLayout container);
View getView();
FloatingView customView(ViewGroup viewGroup);
FloatingView customView(@LayoutRes int resource);
FloatingView layoutParams(ViewGroup.LayoutParams params);
}

View File

@@ -0,0 +1,195 @@
package com.qxcm.moduleutil.widget.floatingView;
import android.app.Activity;
import android.os.Handler;
import android.os.Looper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import androidx.annotation.LayoutRes;
import androidx.core.view.ViewCompat;
import com.qxcm.moduleutil.base.CommonAppContext;
import java.lang.ref.WeakReference;
/**
* @ClassName FloatingView
* @Description 悬浮窗管理器
*/
public class NotifyFloatingView {
private View mFloatingView;
private static volatile NotifyFloatingView mInstance;
private WeakReference<FrameLayout> mContainer;
@LayoutRes
private int mLayoutId;
private ViewGroup.LayoutParams mLayoutParams = getParams();
private NotifyFloatingView() {
}
public static NotifyFloatingView get() {
if (mInstance == null) {
synchronized (NotifyFloatingView.class) {
if (mInstance == null) {
mInstance = new NotifyFloatingView();
}
}
}
return mInstance;
}
public NotifyFloatingView remove() {
if (mFloatingView == null) {
return this;
}
if (ViewCompat.isAttachedToWindow(mFloatingView) && getContainer() != null) {
getContainer().removeView(mFloatingView);
}
mFloatingView = null;
return this;
}
private void ensureFloatingView() {
synchronized (this) {
if (mFloatingView != null) {
addViewToWindow(mFloatingView);
return;
}
View view = LayoutInflater.from(CommonAppContext.getInstance()).inflate(mLayoutId, null);
mFloatingView = view;
view.setLayoutParams(mLayoutParams);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
addViewToWindow(view);
}
}
public NotifyFloatingView add() {
ensureFloatingView();
handler.removeCallbacks(action);
handler.postDelayed(action, 3000);
return this;
}
public NotifyFloatingView attach(Activity activity) {
attach(getActivityRoot(activity));
return this;
}
public NotifyFloatingView attach(FrameLayout container) {
if (container == null || mFloatingView == null) {
mContainer = new WeakReference<>(container);
return this;
}
if (mFloatingView.getParent() == container) {
return this;
}
if (getContainer() != null && mFloatingView.getParent() == getContainer()) {
getContainer().removeView(mFloatingView);
}
mContainer = new WeakReference<>(container);
container.addView(mFloatingView);
return this;
}
public NotifyFloatingView detach(Activity activity) {
detach(getActivityRoot(activity));
return this;
}
public NotifyFloatingView detach(FrameLayout container) {
if (mFloatingView != null && container != null && ViewCompat.isAttachedToWindow(mFloatingView)) {
container.removeView(mFloatingView);
}
if (getContainer() == container) {
mContainer = null;
}
return this;
}
public View getView() {
return mFloatingView;
}
public NotifyFloatingView customView(ViewGroup viewGroup) {
mFloatingView = viewGroup;
return this;
}
public NotifyFloatingView customView(@LayoutRes int resource) {
mLayoutId = resource;
return this;
}
public NotifyFloatingView layoutParams(ViewGroup.LayoutParams params) {
mLayoutParams = params;
if (mFloatingView != null) {
mFloatingView.setLayoutParams(params);
}
return this;
}
private void addViewToWindow(final View view) {
if (getContainer() == null) {
return;
}
getContainer().addView(view);
}
private FrameLayout getContainer() {
if (mContainer == null) {
return null;
}
return mContainer.get();
}
private FrameLayout.LayoutParams getParams() {
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM | Gravity.START;
params.setMargins(13, params.topMargin, params.rightMargin, 500);
return params;
}
private FrameLayout getActivityRoot(Activity activity) {
if (activity == null) {
return null;
}
try {
return (FrameLayout) activity.getWindow().getDecorView().findViewById(android.R.id.content);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Handler handler = new Handler(Looper.getMainLooper());
private Runnable action = new Runnable() {
@Override
public void run() {
NotifyFloatingView.get().remove();
}
};
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<rotate
android:duration="3000"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:repeatMode="restart"
android:startOffset="-1"
android:toDegrees="+360" />
</set>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="200"
android:fromAlpha="0.0"
android:interpolator="@android:anim/decelerate_interpolator"
android:toAlpha="1.0" />
<translate
android:duration="200"
android:fromXDelta="100%"
android:toXDelta="10%" />
<translate
android:duration="2000"
android:fromXDelta="10%"
android:startOffset="200"
android:toXDelta="0" />
<translate
android:duration="200"
android:fromXDelta="0"
android:startOffset="2200"
android:toXDelta="-120%" />
</set>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="10dp" />
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#33ffffff" />
<corners android:topLeftRadius="73dp" android:topRightRadius="73dp" android:bottomLeftRadius="73dp" android:bottomRightRadius="73dp" />
</shape>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#F8F8F8" />
<stroke
android:width="@dimen/height_line"
android:color="#f0f0f0" />
<corners
android:bottomLeftRadius="2dp"
android:bottomRightRadius="2dp"
android:topLeftRadius="2dp"
android:topRightRadius="2dp" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="99dp" />
<solid android:color="@color/color_636363" />
</shape>

View File

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

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#66000000" />
<corners android:radius="30dp" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#33ffffff" />
<corners android:radius="@dimen/dp_53" />
</shape>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#80000000" />
<corners android:topLeftRadius="0dp"
android:topRightRadius="15dp"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="15dp" />
</shape>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- <gradient-->
<!-- android:angle="180"-->
<!-- android:endColor="#ffff6e7b"-->
<!-- android:startColor="#ffff4c79"-->
<!-- android:type="linear"-->
<!-- android:useLevel="true" />-->
<solid android:color="@color/color_FF6765FF"/>
<corners android:radius="40dp" />
</shape>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<solid android:color="#33FFFFFF" />
</shape>
</item>
<!--第二进度颜色-->
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<solid android:color="#33FFFFFF" />
</shape>
</clip>
</item>
<!--第1进度颜色-->
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="@color/color_FFFFBC00"/>
</shape>
</clip>
</item>
</layer-list>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<stroke android:width="1.5dp" android:color="#FFA1C8" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<stroke android:width="1.5dp" android:color="#5A80FF" />
</shape>

View File

@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fl_parent"
android:paddingTop="@dimen/dp_110">
<RelativeLayout
android:id="@+id/rl_play_region"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/dp_90"
android:background="@drawable/room_dialog_music_window_bg"
android:padding="@dimen/dp_16">
<com.qxcm.moduleutil.widget.MarqueeTextView
android:id="@+id/tv_music_title"
android:layout_width="@dimen/dp_200"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="红色凉鞋"
android:textColor="@color/white"
android:textSize="@dimen/sp_16" />
<com.qxcm.moduleutil.widget.MarqueeTextView
android:id="@+id/tv_singer"
android:layout_width="@dimen/dp_200"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_music_title"
android:layout_marginTop="@dimen/dp_5"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:text="蔡文姬"
android:textColor="#CCFFFFFF"
android:textSize="@dimen/sp_14" />
<ImageView
android:id="@+id/iv_minx"
android:layout_width="@dimen/dp_24"
android:layout_height="@dimen/dp_24"
android:layout_alignParentEnd="true"
android:padding="@dimen/dp_4"
android:src="@mipmap/room_music_win_fold" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_music_btn_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_singer"
android:layout_marginTop="@dimen/dp_20">
<ImageView
android:id="@+id/iv_pattern"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/room_music_win_singlecircle"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_last"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/dp_21"
android:src="@mipmap/room_music_win_last"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@+id/iv_music_play_state"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_music_play_state"
android:layout_width="@dimen/dp_50"
android:layout_height="@dimen/dp_50"
android:layout_centerHorizontal="true"
android:src="@mipmap/room_music_win_puase"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_21"
android:src="@mipmap/room_music_win_next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/iv_music_play_state"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/room_music_win_list"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/cl_music_btn_layout"
android:layout_marginTop="@dimen/dp_15">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="@mipmap/room_music_win_sound_off" />
<SeekBar
android:id="@+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/dp_45"
android:layout_marginRight="@dimen/dp_45"
android:max="100"
android:maxHeight="@dimen/dp_2"
android:minHeight="@dimen/dp_2"
android:paddingStart="@dimen/dp_5"
android:paddingEnd="@dimen/dp_5"
android:progress="50"
android:progressDrawable="@drawable/room_style_dialog_volume_seekbar"
android:thumb="@mipmap/room_dialog_music_seebar_thumb" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@mipmap/room_music_win_volumeup" />
</RelativeLayout>
</RelativeLayout>
</FrameLayout>
</layout>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/white">
<View
android:id="@+id/view_input"
android:layout_width="0dp"
android:layout_height="34dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="84dp"
android:layout_marginBottom="8dp"
android:background="@drawable/room_bg_detail_comment"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="@+id/et_content"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="@null"
android:hint="说点什么吧(50字以内)"
android:maxLength="50"
android:paddingLeft="8dp"
android:paddingTop="8dp"
android:paddingRight="8dp"
android:paddingBottom="8dp"
android:textColor="@color/color_text"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/view_input"
app:layout_constraintStart_toStartOf="@id/view_input" />
<Button
android:id="@+id/tv_send"
android:layout_width="60dp"
android:layout_height="34dp"
android:layout_marginRight="12dp"
android:background="@drawable/room_input_btn_bg"
android:text="发送"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -0,0 +1,226 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false">
<!--说话动态图-->
<com.opensource.svgaplayer.SVGAImageView
android:id="@+id/iv_ripple"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleX="0.9"
android:scaleY="0.9"
app:autoPlay="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:loopCount="0"
app:source="ripple.svga" />
<com.qxcm.moduleutil.widget.GifAvatarOvalView
android:id="@+id/riv"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@mipmap/room_ic_wheat_default"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.70154"
/>
<ImageView
android:id="@+id/iv_sex"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@mipmap/common_ic_headportriat_base"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/riv"
app:layout_constraintEnd_toEndOf="@id/riv"
app:layout_constraintStart_toStartOf="@id/riv"
app:layout_constraintTop_toTopOf="@id/riv"
tools:visibility="visible" />
<View
android:id="@+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
app:layout_constraintEnd_toEndOf="@id/riv"
app:layout_constraintStart_toStartOf="@id/riv"
app:layout_constraintTop_toTopOf="@id/riv" />
<ImageView
android:id="@+id/iv_tag_boos"
android:layout_width="32dp"
android:layout_height="14dp"
android:src="@mipmap/room_ic_wheat_tag_boss"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/view2"
app:layout_constraintEnd_toEndOf="@id/riv"
app:layout_constraintStart_toStartOf="@id/riv"
tools:visibility="visible" />
<TextView
android:id="@+id/tv_time"
android:layout_width="@dimen/dp_35"
android:layout_height="17.5dp"
android:background="@drawable/room_bg_wheat_time"
android:gravity="center"
android:text="00:00"
android:textColor="@color/white"
android:textSize="@dimen/sp_9"
android:visibility="gone"
android:layout_marginBottom="@dimen/dp_6"
app:layout_constraintBottom_toBottomOf="@id/riv"
app:layout_constraintEnd_toEndOf="@id/riv"
app:layout_constraintStart_toStartOf="@id/riv"
tools:visibility="visible" />
<com.opensource.svgaplayer.SVGAImageView
android:id="@+id/iv_frame"
android:layout_width="0dp"
android:layout_height="0dp"
android:contentDescription="@null"
android:scaleType="fitXY"
app:autoPlay="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:loopCount="0" />
<View
android:id="@+id/view_riv_bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="7dp"
app:layout_constraintBottom_toBottomOf="@id/riv"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/cl_guide1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.2" />
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="@dimen/sp_12"
android:paddingLeft="@dimen/dp_5"
android:paddingRight="@dimen/dp_5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_frame"
tools:text="麦位1"
tools:textColor="@color/color_FF333333" />
<com.qxcm.moduleutil.widget.WheatCharmView
android:id="@+id/charm_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
app:layout_constraintEnd_toEndOf="@id/riv"
app:layout_constraintStart_toStartOf="@id/riv"
app:layout_constraintTop_toBottomOf="@id/tv_name" />
<ImageView
android:id="@+id/iv_shutup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_marginBottom="4dp"
android:src="@mipmap/room_ic_wheat_shutup"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@id/riv"
app:layout_constraintStart_toStartOf="@id/riv"
tools:visibility="visible" />
<ImageView
android:id="@+id/iv_online"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/room_ic_owner_offline"
android:visibility="gone"
tools:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/riv"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="@id/riv"
app:loopCount="0"/>
<com.qxcm.moduleutil.widget.ExpressionImgView
android:id="@+id/iv_face"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="@id/riv"
app:layout_constraintEnd_toEndOf="@id/riv"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="@id/riv"
app:layout_constraintTop_toTopOf="@id/riv"
app:layout_constraintVertical_bias="0.0" />
<ImageView
android:id="@+id/iv_gift"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.8"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/iv_maozi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:scaleType="centerInside"
android:src="@mipmap/ic_room_huangguan"
android:layout_marginTop="@dimen/dp_1"
android:layout_marginLeft="@dimen/dp_10"
tools:visibility="visible"
app:layout_constraintStart_toStartOf="@id/iv_frame"
app:layout_constraintTop_toTopOf="@id/iv_frame" />
<TextView
android:id="@+id/tv_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/ic_room_xq_wno_male"
android:gravity="center"
android:text="1"
android:textColor="#fff"
android:textSize="@dimen/sp_10"
android:visibility="gone"
android:layout_marginBottom="@dimen/dp_6"
app:layout_constraintBottom_toBottomOf="@id/iv_frame"
app:layout_constraintEnd_toEndOf="@id/riv"
app:layout_constraintStart_toStartOf="@id/riv"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<RelativeLayout
android:layout_width="@dimen/dp_55"
android:layout_height="@dimen/dp_46"
android:background="@mipmap/room_dialog_min_player_btn">
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/riv_avatar"
android:layout_width="@dimen/dp_38"
android:layout_height="@dimen/dp_38"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/dp_5"
android:src="@mipmap/room_musicplayer_min_pic"
app:riv_oval="true" />
</RelativeLayout>
</layout>

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_user_into"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="375:51"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@mipmap/room_user_go_into_anim"
tools:visibility="visible" />
<LinearLayout
android:id="@+id/ll_info"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:layout_marginStart="@dimen/dp_75"
android:background="@drawable/room_bg_welcome_anim"
android:gravity="center"
android:orientation="horizontal"
android:paddingLeft="10dp"
android:paddingRight="10dp"
app:layout_constraintBottom_toBottomOf="@id/iv_user_into"
app:layout_constraintStart_toStartOf="@id/iv_user_into"
app:layout_constraintTop_toTopOf="@id/iv_user_into">
<com.qxcm.moduleutil.widget.NobilityView
android:id="@+id/iv_nobility"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginRight="8dp"
android:visibility="gone" />
<com.qxcm.moduleutil.widget.RoleView
android:id="@+id/iv_role"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
<com.qxcm.moduleutil.widget.NewView
android:id="@+id/iv_new"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
<ImageView
android:id="@+id/iv_rank"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_24"
android:layout_marginRight="8dp" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名"
android:textColor="@color/white"
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_end_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="7dp"
android:text="进场了"
android:textColor="@color/white"
android:textSize="12sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<RelativeLayout
android:id="@+id/bg"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_26"
android:clipChildren="false"
android:clipToPadding="false">
<TextView
android:id="@+id/tv_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/room_bg_wheat_charm"
android:drawableStart="@mipmap/room_ic_wheat_charm"
android:drawablePadding="@dimen/dp_2"
android:ellipsize="none"
android:gravity="center"
android:minWidth="@dimen/dp_36"
android:paddingHorizontal="@dimen/dp_2"
android:paddingTop="@dimen/dp_3"
android:paddingBottom="@dimen/dp_3"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="@dimen/sp_10" />
</RelativeLayout>
</layout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

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