From 96e3c86cd45f9736bef33da4ac1a7e4c5eb1eb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=B0=8F=E6=B1=9F?= <461355754@qq.com> Date: Wed, 13 Aug 2025 17:31:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=83=8C=E6=99=AF=E5=9B=BE=E5=92=8C=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E6=8C=89=E9=92=AE=20=E4=BF=AE=E6=94=B9=E4=BA=86?= =?UTF-8?q?=E9=A3=98=E5=B1=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qxcm/qxlive/PasswordLoginActivity.java | 8 +- .../activity/ForgetPasswordActivity.java | 6 + .../modulelogin/activity/LoginActivity.java | 6 + .../activity/SwitchAccountsActivity.java | 6 + .../modulelogin/present/LoginContacter.java | 5 + .../modulelogin/present/LoginPresenter.java | 17 ++ moduleUtil/build.gradle | 15 +- .../activity/BaseAppCompatActivity.java | 105 ++++++- .../moduleutil/base/CommonAppContext.java | 8 +- .../com/qxcm/moduleutil/bean/ThemeBean.java | 25 ++ .../com/qxcm/moduleutil/http/ApiServer.java | 4 + .../qxcm/moduleutil/http/RetrofitClient.java | 23 ++ .../moduleutil/service/MyMqttService.java | 5 +- .../moduleutil/utils/BackgroundManager.java | 112 +++++++ .../qxcm/moduleutil/utils/ColorManager.java | 279 ++++++++++++++++++ .../moduleutil/widget/AvatarFrameView.java | 92 ++++-- .../qxcm/moduleutil/widget/BaseWheatView.java | 6 + .../com/qxcm/moduleutil/widget/Constants.java | 1 + .../moduleutil/widget/PiaoPingManager.java | 78 ++--- .../moduleutil/widget/RoomKtvWheatView.java | 254 ++++++++++++++++ .../moduleutil/widget/RoomMakeWheatView.java | 5 - .../main/res/layout/room_view_ktv_wheat.xml | 273 +++++++++++++++++ .../modulemain/activity/MainActivity.java | 218 ++++++++++++-- .../modulemain/contacts/HomeContacts.java | 6 + .../modulemain/presenter/HomePresenter.java | 17 ++ .../src/main/res/layout/activity_main.xml | 7 + .../moduleroom/activity/RoomActivity.java | 1 + .../moduleroom/adapter/EaseChatAdapter.java | 16 +- .../moduleroom/adapter/RoomOnlineAdapter.java | 11 +- .../dialog/RoomUserInfoFragment.java | 2 +- .../fragment/RoomAuctionFragment.java | 2 +- .../moduleroom/fragment/RoomFragment.java | 9 +- .../moduleroom/fragment/RoomKtvFragment.java | 31 +- .../main/res/layout/fragment_room_auction.xml | 3 - .../src/main/res/layout/fragment_room_ktv.xml | 6 +- .../main/res/layout/item_room_charm_rank.xml | 2 +- .../modulevocal/activity/SettingActivity.java | 1 - .../modulevocal/adapter/MyCreateAdapter.java | 7 +- 38 files changed, 1507 insertions(+), 165 deletions(-) create mode 100644 moduleUtil/src/main/java/com/qxcm/moduleutil/bean/ThemeBean.java create mode 100644 moduleUtil/src/main/java/com/qxcm/moduleutil/utils/BackgroundManager.java create mode 100644 moduleUtil/src/main/java/com/qxcm/moduleutil/utils/ColorManager.java create mode 100644 moduleUtil/src/main/java/com/qxcm/moduleutil/widget/RoomKtvWheatView.java create mode 100644 moduleUtil/src/main/res/layout/room_view_ktv_wheat.xml diff --git a/app/src/main/java/com/qxcm/qxlive/PasswordLoginActivity.java b/app/src/main/java/com/qxcm/qxlive/PasswordLoginActivity.java index 4bf597d6..ecb59d30 100644 --- a/app/src/main/java/com/qxcm/qxlive/PasswordLoginActivity.java +++ b/app/src/main/java/com/qxcm/qxlive/PasswordLoginActivity.java @@ -34,6 +34,7 @@ import com.qxcm.modulelogin.present.LoginPresenter; import com.qxcm.modulemain.activity.MainActivity; import com.qxcm.moduleutil.activity.BaseMvpActivity; import com.qxcm.moduleutil.base.CommonAppContext; +import com.qxcm.moduleutil.bean.ThemeBean; import com.qxcm.moduleutil.bean.UserBean; import com.qxcm.moduleutil.utils.BarUtils; import com.qxcm.moduleutil.utils.PreferencesUtils; @@ -97,7 +98,7 @@ public class PasswordLoginActivity extends BaseMvpActivity implement }); } + @Override + public void getThemeData() { + api.getThemeData(new BaseObserver() { + + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(ThemeBean themeBean) { + MvpRef.get().getThemeData(themeBean); + } + }); + } + @Override public void detachView() { diff --git a/moduleUtil/build.gradle b/moduleUtil/build.gradle index 8a6c9284..a3426803 100644 --- a/moduleUtil/build.gradle +++ b/moduleUtil/build.gradle @@ -51,7 +51,7 @@ android { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar','*.aar']) + implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) // implementation fileTree(dir: 'libs', include: ['*.jar']) implementation libs.appcompat @@ -103,8 +103,8 @@ dependencies { // api(libs.pictureselector.picture.library) api('io.github.lucksiege:pictureselector:v3.11.2') - ///图片裁剪 (按需引入) - api ('io.github.lucksiege:ucrop:v3.11.2') + ///图片裁剪 (按需引入) + api('io.github.lucksiege:ucrop:v3.11.2') api(libs.com.github.bumptech.glide.glide) // api(libs.glide.compiler) @@ -187,7 +187,8 @@ dependencies { // api project(':LocalAar') - api 'com.tencent.bugly:crashreport:latest.release' //其中latest.release指代最新Bugly SDK版本号,也可以指定明确的版本号,例如4.0.3 + api 'com.tencent.bugly:crashreport:latest.release' + //其中latest.release指代最新Bugly SDK版本号,也可以指定明确的版本号,例如4.0.3 // api 'com.tencent.rqd:nativecrashreport:latest.release' //其中latest.release指代最新Bugly NDK版本号,也可以指定明确的版本号,例如3.9.2 // 房间引擎 api "io.trtc.uikit:rtc_room_engine:latest.release" @@ -200,12 +201,6 @@ dependencies { api 'io.github.petterpx:floatingx-compose:2.3.5' api 'com.github.princekin-f:EasyFloat:2.0.4' - //MQTT -// api 'org.eclipse.paho:org.eclipse.paho.mqttv5.client:1.2.5' -// api 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1' -// api 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1' -// api 'com.github.hannesa2:paho.mqtt.android:3.3.5' -// api 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5' api 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5' api 'io.github.mayzs:paho.mqtt.android:1.2.1' diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/activity/BaseAppCompatActivity.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/activity/BaseAppCompatActivity.java index 3d09c185..5a4a4258 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/activity/BaseAppCompatActivity.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/activity/BaseAppCompatActivity.java @@ -1,8 +1,11 @@ package com.qxcm.moduleutil.activity; +import static com.liulishuo.okdownload.OkDownloadProvider.context; + import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -20,18 +23,28 @@ import androidx.databinding.ViewDataBinding; import com.alibaba.android.arouter.launcher.ARouter; import com.blankj.utilcode.util.BarUtils; +import com.petterp.floatingx.FloatingX; +import com.petterp.floatingx.assist.helper.FxAppHelper; import com.qxcm.moduleutil.R; +import com.qxcm.moduleutil.event.MqttBean; +import com.qxcm.moduleutil.utils.BackgroundManager; +import com.qxcm.moduleutil.utils.ColorManager; import com.qxcm.moduleutil.utils.DisplayUtil; import com.qxcm.moduleutil.utils.LanguageUtil; +import com.qxcm.moduleutil.widget.PiaoPingManager; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.Map; + +public abstract class BaseAppCompatActivity extends AppCompatActivity + implements BackgroundManager.BackgroundUpdateListener , ColorManager.OnColorChangeListener { -public abstract class BaseAppCompatActivity extends AppCompatActivity { @Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(LanguageUtil.attachBaseContext(newBase)); @@ -60,6 +73,14 @@ public abstract class BaseAppCompatActivity extends initData(); initCompleted(); + // 注册背景更新监听器 + BackgroundManager.getInstance().addListener(this); + // 尝试加载网络背景 + loadNetworkBackground(); + // 注册颜色变化监听器 + ColorManager.getInstance().addColorChangeListener(this); + // 应用当前颜色 + applyCurrentColors(); // 动态判断是否包含 @Subscribe 注解的方法 @@ -94,7 +115,78 @@ public abstract class BaseAppCompatActivity extends } } } + /** + * 应用当前颜色设置 + */ + protected void applyCurrentColors() { + onColorChanged(ColorManager.getInstance()); + } + + /** + * 颜色变化回调 + */ @Override + public void onColorChanged(ColorManager colorManager) { + // 子类可以重写此方法来处理颜色变化 + // 默认实现为空,由子类决定如何应用颜色 + } + /** + * 更新主题颜色(从服务器获取数据后调用) + * @param serverColorMap 服务器返回的颜色配置 + */ + protected void updateThemeColors(Map serverColorMap) { + ColorManager.getInstance().updateColors(serverColorMap); + } + /** + * 更新单个颜色 + * @param colorKey 颜色键名 + * @param colorHex 颜色值(HEX格式) + */ + protected void updateThemeColor(String colorKey, String colorHex) { + ColorManager.getInstance().updateColor(colorKey, colorHex); + } + + + protected void loadNetworkBackground() { + // 只有当已经有背景URL时才加载 + String backgroundUrl = BackgroundManager.getInstance().getBackgroundUrl(); + if (backgroundUrl != null && !backgroundUrl.isEmpty()) { + // 检查是否有已加载的drawable + Drawable cachedDrawable = BackgroundManager.getInstance().getBackgroundDrawable(); + if (cachedDrawable != null) { + getWindow().getDecorView().setBackground(cachedDrawable); + } else { + // 加载网络背景 + BackgroundManager.getInstance().loadBackgroundDrawable(this, new BackgroundManager.BackgroundLoadCallback() { + @Override + public void onLoadSuccess(Drawable drawable) { + getWindow().getDecorView().setBackground(drawable); + } + + @Override + public void onLoadFailed() { + // 加载失败时使用默认背景 + getWindow().getDecorView().setBackgroundResource(R.mipmap.activity_bj); + } + }); + } + } + } + + @Override + public void onBackgroundUpdated(Drawable drawable) { + // 当背景更新时,更新当前Activity的背景 + if (drawable != null) { + getWindow().getDecorView().setBackground(drawable); + } + } + + // 提供一个方法供子类调用,用于设置背景URL + protected void setNetworkBackgroundUrl(String url) { + BackgroundManager.getInstance().setBackgroundUrl(url); + } + + @Override public Resources getResources() {//禁止app字体大小跟随系统字体大小调节 Resources resources = super.getResources(); if (resources != null && resources.getConfiguration().fontScale != 1.0f) { @@ -130,6 +222,10 @@ public abstract class BaseAppCompatActivity extends @Override protected void onDestroy() { + // 移除背景更新监听器 + BackgroundManager.getInstance().removeListener(this); + // 移除颜色变化监听器 + ColorManager.getInstance().removeColorChangeListener(this); if (mBinding != null) { mBinding.unbind(); } @@ -201,4 +297,11 @@ public abstract class BaseAppCompatActivity extends } return false; } + +// @Subscribe(threadMode = ThreadMode.MAIN) +// public void onMessageReceived(MqttBean mqttBean) { +//// PiaoPingManager.getInstance(this).showPiaoPingMessage(mqttBean); +// FxAppHelper fxAppHelper = FxAppHelper.builder().setContext(this).setLayout(R.layout.item_piaoping).build(); +// FloatingX.install(fxAppHelper).show(); +// } } diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/base/CommonAppContext.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/base/CommonAppContext.java index 78045a18..321d3ace 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/base/CommonAppContext.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/base/CommonAppContext.java @@ -113,8 +113,9 @@ public class CommonAppContext extends MultiDexApplication { super.onCreate(); sInstance = this; sMainThreadHandler = new Handler(); - - + EnvironmentPrefs prefs = new EnvironmentPrefs(this); + currentEnvironment = prefs.getSelectedEnvironment(); + initialization(); } public void initialization(){ @@ -128,8 +129,7 @@ public class CommonAppContext extends MultiDexApplication { UtilConfig.checkInEmulator(); } } - EnvironmentPrefs prefs = new EnvironmentPrefs(this); - currentEnvironment = prefs.getSelectedEnvironment(); + piaoPingManager = PiaoPingManager.getInstance(this); piaoPingManager.subscribe(); AgoraManager.getInstance(this).init(currentEnvironment.getSwSdkAppId()); diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/bean/ThemeBean.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/bean/ThemeBean.java new file mode 100644 index 00000000..a9b70566 --- /dev/null +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/bean/ThemeBean.java @@ -0,0 +1,25 @@ +package com.qxcm.moduleutil.bean; + +import lombok.Data; + +/** + * @author qx + * @data 2025/8/12 + * @description: 主题接口,修改主题返回的值 + */ +@Data +public class ThemeBean { + private String theme_color;//主题颜色 + private String file_url;// + private String auxiliary_color;// + private String btn_text_color;//按钮文字颜色 + private String app_bg;//app背景图 + private String home_sel;//首页选中 + private String home_nor;//首页未选中 + private String find_sel;//广场选中 + private String find_nor;//广场未选中 + private String msg_sel;//消息选中 + private String msg_nor;//消息未选中 + private String mine_sel;//我的选中 + private String mine_nor;//我的未选中 +} diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/http/ApiServer.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/http/ApiServer.java index b757a1fb..32cf6023 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/http/ApiServer.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/http/ApiServer.java @@ -47,6 +47,7 @@ import com.qxcm.moduleutil.bean.RoomTime; import com.qxcm.moduleutil.bean.RoomTypeModel; import com.qxcm.moduleutil.bean.RoonGiftModel; import com.qxcm.moduleutil.bean.SongMusicBean; +import com.qxcm.moduleutil.bean.ThemeBean; import com.qxcm.moduleutil.bean.TopRoom; import com.qxcm.moduleutil.bean.UserBean; import com.qxcm.moduleutil.bean.UserInfo; @@ -236,6 +237,9 @@ public interface ApiServer { @POST(Constants.URL_LOGIN) Call>> oauthLogin(@Field("login_token") String login_token); + @GET(Constants.GET_THEME_DATA) + Call> getThemeData(); + @FormUrlEncoded @POST(Constants.URL_AUTH_CODE) Observable>> authCode(@Field("auth_code") String login_token); diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/http/RetrofitClient.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/http/RetrofitClient.java index 17f45a3e..fc09ad4f 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/http/RetrofitClient.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/http/RetrofitClient.java @@ -64,6 +64,7 @@ import com.qxcm.moduleutil.bean.RoomTime; import com.qxcm.moduleutil.bean.RoomTypeModel; import com.qxcm.moduleutil.bean.RoonGiftModel; import com.qxcm.moduleutil.bean.SongMusicBean; +import com.qxcm.moduleutil.bean.ThemeBean; import com.qxcm.moduleutil.bean.TopRoom; import com.qxcm.moduleutil.bean.UserBean; import com.qxcm.moduleutil.bean.UserFollowBean; @@ -717,6 +718,28 @@ public class RetrofitClient { }); } + public void getThemeData(BaseObserver observer){ + sApiServer.getThemeData().enqueue(new Callback>() { + + @Override + public void onResponse(Call> call, Response> response) { + if (response.code() == 200){ + BaseModel baseModel = response.body(); + if (baseModel.getData()!=null){ + observer.onNext(baseModel.getData()); + }else { + observer.onNext(null); + } + } + } + + @Override + public void onFailure(Call> call, Throwable t) { + t.printStackTrace(); + } + }); + } + public void authCode(String netease_token, int type, BaseObserver> observer) { if (type == 1) { sApiServer.authCode1(netease_token).compose(new DefaultTransformer<>()).subscribe(observer); diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/service/MyMqttService.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/service/MyMqttService.java index 285b80aa..72d88c3d 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/service/MyMqttService.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/service/MyMqttService.java @@ -44,9 +44,8 @@ public class MyMqttService extends Service implements MyEmqttConnectListener,MyE private final static String TAG = "lxj"; private static int qos = 2; - private static String HOST = CommonAppContext.getInstance().getCurrentEnvironment().getMqttUrl(); - // private static String USERNAME = BuildConfig.EMQTT_USER;//用户名 -// private static String PASSWORD = BuildConfig.EMQTT_PASSWORD;//密码 + private static String HOST ="tcp://81.70.45.221";//正式 +// private static String HOST ="tcp://47.120.21.132";//测试 private static MqttAndroidClient mqttAndroidClient; private MqttConnectOptions mMqttConnectOptions; private static boolean b = true; diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/utils/BackgroundManager.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/utils/BackgroundManager.java new file mode 100644 index 00000000..88f5b2ec --- /dev/null +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/utils/BackgroundManager.java @@ -0,0 +1,112 @@ +// 在 moduleUtil 中创建 BackgroundManager.java +package com.qxcm.moduleutil.utils; + +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.ImageView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.target.CustomTarget; +import com.bumptech.glide.request.transition.Transition; + +import java.util.ArrayList; +import java.util.List; +/** + *@author qx + *@data 2025/8/12 + *@description: 背景图片的单例类 + */ +public class BackgroundManager { + private static BackgroundManager instance; + private String backgroundUrl; + private Drawable backgroundDrawable; + private List listeners = new ArrayList<>(); + + public static BackgroundManager getInstance() { + if (instance == null) { + synchronized (BackgroundManager.class) { + if (instance == null) { + instance = new BackgroundManager(); + } + } + } + return instance; + } + + public void setBackgroundUrl(String url) { + this.backgroundUrl = url; + loadBackground(); + } + + public String getBackgroundUrl() { + return backgroundUrl; + } + + public Drawable getBackgroundDrawable() { + return backgroundDrawable; + } + + private void loadBackground() { + if (backgroundUrl == null || backgroundUrl.isEmpty()) { + return; + } + // 这里使用一个临时的 ImageView 来加载图片 + // 实际项目中可能需要使用 Application Context + // 为简化,这里直接加载到 drawable + } + + public void loadBackgroundDrawable(android.content.Context context, BackgroundLoadCallback callback) { + if (backgroundUrl == null || backgroundUrl.isEmpty()) { + callback.onLoadFailed(); + return; + } + + Glide.with(context) + .asDrawable() + .load(backgroundUrl) + .into(new CustomTarget() { + @Override + public void onResourceReady(Drawable resource, Transition transition) { + backgroundDrawable = resource; + callback.onLoadSuccess(resource); + notifyBackgroundUpdated(resource); + } + + @Override + public void onLoadCleared(Drawable placeholder) { + callback.onLoadFailed(); + } + + @Override + public void onLoadFailed(Drawable errorDrawable) { + super.onLoadFailed(errorDrawable); + callback.onLoadFailed(); + } + }); + } + + public void addListener(BackgroundUpdateListener listener) { + if (!listeners.contains(listener)) { + listeners.add(listener); + } + } + + public void removeListener(BackgroundUpdateListener listener) { + listeners.remove(listener); + } + + private void notifyBackgroundUpdated(Drawable drawable) { + for (BackgroundUpdateListener listener : listeners) { + listener.onBackgroundUpdated(drawable); + } + } + + public interface BackgroundLoadCallback { + void onLoadSuccess(Drawable drawable); + void onLoadFailed(); + } + + public interface BackgroundUpdateListener { + void onBackgroundUpdated(Drawable drawable); + } +} diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/utils/ColorManager.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/utils/ColorManager.java new file mode 100644 index 00000000..a2303e82 --- /dev/null +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/utils/ColorManager.java @@ -0,0 +1,279 @@ +package com.qxcm.moduleutil.utils; + +import android.graphics.Color; + +import androidx.annotation.ColorInt; +import androidx.annotation.Nullable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author qx + * @data 2025/8/13 + * @description: 颜色的管理器,从服务器获取的颜色数据,进行更改, + * 这里是两个颜色,一个主题色,一个是按钮文字颜色 + */ +public class ColorManager { + // 单例实例 + private static volatile ColorManager instance; + + // 存储颜色值的Map + private Map colorMap; + + // 默认颜色值 + private Map defaultColors; + + // 颜色变化监听器列表 + private List colorChangeListeners; + + // 私有构造函数 + private ColorManager() { + colorMap = new HashMap<>(); + defaultColors = new HashMap<>(); + colorChangeListeners = new ArrayList<>(); + + // 初始化默认颜色值 + initDefaultColors(); + } + + /** + * 获取单例实例 + */ + public static ColorManager getInstance() { + if (instance == null) { + synchronized (ColorManager.class) { + if (instance == null) { + instance = new ColorManager(); + } + } + } + return instance; + } + + /** + * 初始化默认颜色值 + */ + private void initDefaultColors() { + // 主题色 + defaultColors.put("theme_color", Color.parseColor("#4CAF50")); // 绿色(按您的需求) + defaultColors.put("btn_text_color", Color.parseColor("#FFFFFF")); // 白色 + } + + /** + * 根据服务器返回的数据更新颜色 + * + * @param colorKey 颜色键名 + * @param colorHex 颜色HEX值 (#FFFFFF格式) + */ + public void updateColor(String colorKey, @Nullable String colorHex) { + boolean changed = false; + if (colorHex != null && !colorHex.isEmpty()) { + try { + int color = Color.parseColor(colorHex); + Integer oldColor = colorMap.get(colorKey); + if (oldColor == null || oldColor != color) { + colorMap.put(colorKey, color); + changed = true; + } + } catch (Exception e) { + // 解析失败时移除该颜色,使用默认值 + if (colorMap.containsKey(colorKey)) { + colorMap.remove(colorKey); + changed = true; + } + e.printStackTrace(); + } + } else { + // 如果返回空值,则移除该颜色,使用默认值 + if (colorMap.containsKey(colorKey)) { + colorMap.remove(colorKey); + changed = true; + } + } + + // 如果颜色发生了变化,通知监听器 + if (changed) { + notifyColorChanged(); + } + } + + /** + * 批量更新颜色 + * + * @param colorMap 服务器返回的颜色Map + */ + public void updateColors(Map colorMap) { + boolean changed = false; + if (colorMap != null) { + for (Map.Entry entry : colorMap.entrySet()) { + String colorKey = entry.getKey(); + String colorHex = entry.getValue(); + + if (colorHex != null && !colorHex.isEmpty()) { + try { + int color = Color.parseColor(colorHex); + Integer oldColor = this.colorMap.get(colorKey); + if (oldColor == null || oldColor != color) { + this.colorMap.put(colorKey, color); + changed = true; + } + } catch (Exception e) { + // 解析失败时移除该颜色 + if (this.colorMap.containsKey(colorKey)) { + this.colorMap.remove(colorKey); + changed = true; + } + e.printStackTrace(); + } + } else { + // 如果返回空值,则移除该颜色 + if (this.colorMap.containsKey(colorKey)) { + this.colorMap.remove(colorKey); + changed = true; + } + } + } + } + + // 如果有任何颜色发生了变化,通知监听器 + if (changed) { + notifyColorChanged(); + } + } + + /** + * 获取颜色值 + * + * @param colorKey 颜色键名 + * @return 颜色值,如果未设置则返回默认值 + */ + @ColorInt + public int getColor(String colorKey) { + // 先从服务器设置的颜色中查找 + if (colorMap.containsKey(colorKey)) { + return colorMap.get(colorKey); + } + + // 如果没有设置,则返回默认颜色 + if (defaultColors.containsKey(colorKey)) { + return defaultColors.get(colorKey); + } + + // 如果默认颜色也没有定义,则返回黑色 + return Color.BLACK; + } + + /** + * 获取颜色值,带默认返回值 + * + * @param colorKey 颜色键名 + * @param defaultColor 默认颜色 + * @return 颜色值 + */ + @ColorInt + public int getColor(String colorKey, @ColorInt int defaultColor) { + if (colorMap.containsKey(colorKey)) { + return colorMap.get(colorKey); + } + return defaultColor; + } + + /** + * 检查是否设置了指定颜色 + * + * @param colorKey 颜色键名 + * @return 是否设置了该颜色 + */ + public boolean hasColor(String colorKey) { + return colorMap.containsKey(colorKey); + } + + /** + * 获取默认颜色 + * + * @param colorKey 颜色键名 + * @return 默认颜色值 + */ + @ColorInt + public int getDefaultColor(String colorKey) { + if (defaultColors.containsKey(colorKey)) { + return defaultColors.get(colorKey); + } + return Color.BLACK; + } + + /** + * 重置所有颜色为默认值 + */ + public void resetToDefault() { + if (!colorMap.isEmpty()) { + colorMap.clear(); + notifyColorChanged(); + } + } + + /** + * 移除指定颜色设置,恢复为默认值 + * + * @param colorKey 颜色键名 + */ + public void removeColor(String colorKey) { + if (colorMap.containsKey(colorKey)) { + colorMap.remove(colorKey); + notifyColorChanged(); + } + } + + /** + * 获取所有当前设置的颜色(不包括默认颜色) + * + * @return 当前设置的颜色Map + */ + public Map getCurrentColors() { + return new HashMap<>(colorMap); + } + + /** + * 获取所有默认颜色 + * + * @return 默认颜色Map + */ + public Map getDefaultColors() { + return new HashMap<>(defaultColors); + } + + /** + * 添加颜色变化监听器 + */ + public void addColorChangeListener(OnColorChangeListener listener) { + if (!colorChangeListeners.contains(listener)) { + colorChangeListeners.add(listener); + } + } + + /** + * 移除颜色变化监听器 + */ + public void removeColorChangeListener(OnColorChangeListener listener) { + colorChangeListeners.remove(listener); + } + + /** + * 通知颜色变化 + */ + private void notifyColorChanged() { + for (OnColorChangeListener listener : colorChangeListeners) { + listener.onColorChanged(this); + } + } + + /** + * 颜色变化监听器接口 + */ + public interface OnColorChangeListener { + void onColorChanged(ColorManager colorManager); + } +} diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/AvatarFrameView.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/AvatarFrameView.java index 7d96f480..88d56aeb 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/AvatarFrameView.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/AvatarFrameView.java @@ -156,9 +156,17 @@ public class AvatarFrameView extends FrameLayout implements IAnimListener { return ""; } private void playNextFromQueue() { + + // 检查特效是否开启 + if (SpUtil.getOpenEffect() != 1) { + clearQueue(); + return; + } + PlayItem item = playQueue.poll(); if (item != null) { - isPlaying = false; + isPlaying = true; + Logger.d("AvatarFrameView", "Playing item, remaining queue size: " + playQueue.size()); RenderType type = null; String ext = getFileExtension(item.url); if ("svga".equalsIgnoreCase(ext)) { @@ -190,43 +198,63 @@ public class AvatarFrameView extends FrameLayout implements IAnimListener { } } else { isPlaying = false; + Logger.d("AvatarFrameView", "Queue is empty, stop playing"); + } + } + public void setSource(String url, int type2) { + // 检查特效是否开启 + if (SpUtil.getOpenEffect() != 1) { + // 特效关闭时清空队列并停止播放 + clearQueue(); + return; + } + + // 添加到播放队列 +// playQueue.offer(new PlayItem(url, type2)); + playQueue.add(new PlayItem(url, type2)); + Logger.d("AvatarFrameView", "Added to queue, queue size: " + playQueue.size() + ", url: " + url); + + // 如果当前没有在播放,则开始播放 + if (!isPlaying) { + playNextFromQueue(); } } - public void setSource(String url, int type2) { - if (SpUtil.getOpenEffect()==1) { - playQueue.offer(new PlayItem(url, type2)); - if (!isPlaying) { - playNextFromQueue(); - } - }else { - playQueue.clear(); - isPlaying = false; - } -// RenderType type = null; -// if ("svga".equalsIgnoreCase(getFileExtension(url))){ -// type = RenderType.SVGA; -// }else if ("mp4".equalsIgnoreCase(getFileExtension(url))){ -// type = RenderType.MP4; +// public void setSource(String url, int type2) { +// if (SpUtil.getOpenEffect()==1) { +// playQueue.offer(new PlayItem(url, type2)); +// if (!isPlaying) { +// playNextFromQueue(); +// } +// }else { +// playQueue.clear(); +// isPlaying = false; // } // -// clearPrevious(); -// renderType = type; -// mType = type2; -// switch (type) { -// case SVGA: -// mBinding.playView.stopPlay(); -// mBinding.playView.setVisibility(View.GONE); -// loadSVGA(url); -// break; -// case MP4: -//// loadMP4(url); -// mBinding.playView.setVisibility(View.VISIBLE); -// downloadAndPlayMp4(url); -// break; -// } - } +//// RenderType type = null; +//// if ("svga".equalsIgnoreCase(getFileExtension(url))){ +//// type = RenderType.SVGA; +//// }else if ("mp4".equalsIgnoreCase(getFileExtension(url))){ +//// type = RenderType.MP4; +//// } +//// +//// clearPrevious(); +//// renderType = type; +//// mType = type2; +//// switch (type) { +//// case SVGA: +//// mBinding.playView.stopPlay(); +//// mBinding.playView.setVisibility(View.GONE); +//// loadSVGA(url); +//// break; +//// case MP4: +////// loadMP4(url); +//// mBinding.playView.setVisibility(View.VISIBLE); +//// downloadAndPlayMp4(url); +//// break; +//// } +// } private void downloadAndPlayMp4(String url) { String filePath = PathUtils.getInternalAppCachePath() + Md5Utils.getStringMD5(url) + ".mp4"; diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/BaseWheatView.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/BaseWheatView.java index f9d7baa5..da4c5659 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/BaseWheatView.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/BaseWheatView.java @@ -295,10 +295,16 @@ public abstract class BaseWheatView extends ConstraintLayout implements IBaseWhe if (pitBean.getUser_id().equals(userId + "")) { iv_on_line.setVisibility(VISIBLE); } + }else if (pitBean.getUser_id()==null || pitBean.getUser_id().equals("0") || pitBean.getUser_id().equals("")){ + iv_on_line.setVisibility(GONE); } } }); + if (pitBean.getUser_id()==null || pitBean.getUser_id().equals("0") || pitBean.getUser_id().equals("") ){ + iv_on_line.setVisibility(GONE); + } + } diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/Constants.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/Constants.java index 7716c55a..4b72efe5 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/Constants.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/Constants.java @@ -369,6 +369,7 @@ public class Constants { public static final String postRoomSwToken = "/api/Room/update_user_sw_token";//获取用户声网token public static final String dailyTasksComplete = "/api/Dailytasks/dailyTasksComplete";//领取每日任务奖励 public static final String POST_CANCEL_USER_DECORATE = "/api/Decorate/cancel_user_decorate";//取消装扮 + public static final String GET_THEME_DATA = "/api/Theme/get_theme_data";//主题接口 diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/PiaoPingManager.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/PiaoPingManager.java index 7c0db8e8..9b63eeee 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/PiaoPingManager.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/PiaoPingManager.java @@ -2,15 +2,19 @@ package com.qxcm.moduleutil.widget; import static com.liulishuo.okdownload.OkDownloadProvider.context; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; import android.content.Context; -import android.graphics.PixelFormat; -import android.os.Build; -import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; +import android.widget.FrameLayout; import android.widget.TextView; +import com.petterp.floatingx.FloatingX; +import com.petterp.floatingx.assist.FxGravity; +import com.petterp.floatingx.assist.helper.FxAppHelper; import com.qxcm.moduleutil.R; import com.qxcm.moduleutil.event.MqttBean; import com.qxcm.moduleutil.utils.ImageUtils; @@ -18,6 +22,7 @@ import com.qxcm.moduleutil.utils.ImageUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; + /** * @Author * @Time 2025/7/18 21:52 @@ -46,42 +51,44 @@ public class PiaoPingManager { } public void showPiaoPingMessage(MqttBean mqttBean) { - if (isPiaoPingShown || piaoPingView == null || windowManager == null) return; + // 创建 FloatingX 配置 - // 设置布局参数 - WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams( - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.WRAP_CONTENT, - Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : - WindowManager.LayoutParams.TYPE_PHONE, - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, - PixelFormat.TRANSLUCENT); - layoutParams.gravity = Gravity.TOP; - layoutParams.y = 100; // 设置垂直位置 - - // 设置消息内容 - View piaoPingView = LayoutInflater.from(context.getApplicationContext()).inflate(R.layout.item_piaoping, null); - TextView textView = piaoPingView.findViewById(R.id.tv_name); - TextView textView2 = piaoPingView.findViewById(R.id.tv_to_name); - textView2.setText("送给"+mqttBean.getList().getToUserName()); + // 获取悬浮窗视图并设置内容 +// 替换第72行及后续对 layoutView 的直接访问 + View floatingView = LayoutInflater.from(context).inflate(R.layout.item_piaoping, new FrameLayout(context), false); + TextView textView = floatingView.findViewById(R.id.tv_name); + TextView textView2 = floatingView.findViewById(R.id.tv_to_name); + textView2.setText("送给" + mqttBean.getList().getToUserName()); textView.setText(mqttBean.getList().getFromUserName()); - ImageUtils.loadHeadCC(mqttBean.getList().getGift_picture(), piaoPingView.findViewById(R.id.iv_piaoping)); - TextView tv_time = piaoPingView.findViewById(R.id.tv_num); - tv_time.setText("x"+mqttBean.getList().getNumber()); + ImageUtils.loadHeadCC(mqttBean.getList().getGift_picture(), floatingView.findViewById(R.id.iv_piaoping)); + TextView tv_time = floatingView.findViewById(R.id.tv_num); + tv_time.setText("x" + mqttBean.getList().getNumber()); - // 添加到窗口管理器 - windowManager.addView(piaoPingView, layoutParams); - isPiaoPingShown = true; + // 3秒后执行左侧滑动关闭动画 + floatingView.postDelayed(() -> { + // 实现左侧滑出动画 + ObjectAnimator animator = ObjectAnimator.ofFloat(floatingView, "translationX", 0f, -floatingView.getWidth()); + animator.setDuration(300); // 300ms 动画时间 + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + // 动画结束后移除悬浮窗 + FloatingX.uninstallAll(); + } + }); + animator.start(); + }, 3000); - // 设置定时任务,一段时间后移除飘屏消息 - piaoPingView.postDelayed(() -> { - if (piaoPingView != null) { - windowManager.removeView(piaoPingView); - isPiaoPingShown = false; - } - }, 3000); // 3秒后移除 + assert floatingView != null; + FxAppHelper fxAppHelper = FxAppHelper.builder() + .setContext(context) + .setLayoutView(floatingView) + .setGravity(FxGravity.LEFT_OR_TOP) + .setY(100) + .build(); + + FloatingX.install(fxAppHelper).show(); } public void subscribe() { @@ -95,6 +102,9 @@ public class PiaoPingManager { @Subscribe(threadMode = ThreadMode.MAIN) public void onMessageReceived(MqttBean mqttBean) { showPiaoPingMessage(mqttBean); + +// FxAppHelper fxAppHelper = FxAppHelper.builder().setContext( context).setLayout(R.layout.item_piaoping).build(); +// FloatingX.install(fxAppHelper).show(); } } diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/RoomKtvWheatView.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/RoomKtvWheatView.java new file mode 100644 index 00000000..e7c199f8 --- /dev/null +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/RoomKtvWheatView.java @@ -0,0 +1,254 @@ +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 com.qxcm.moduleutil.R; +import com.qxcm.moduleutil.bean.UserInfo; +import com.qxcm.moduleutil.bean.room.RoomPitBean; +import com.qxcm.moduleutil.utils.ImageUtils; +import com.qxcm.moduleutil.utils.SpUtil; +/** + *@author qx + *@data 2025/8/13 + *@description: K歌模式下的视图 + */ +public class RoomKtvWheatView extends BaseWheatView { + public ImageView mIvTagBoss; + public TextView mTvTime; + public TextView tv_time_pk; + + private boolean showBoss;//显示老板标识 + + public RoomKtvWheatView(Context context) { + this(context, null, 0); + } + + public RoomKtvWheatView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RoomKtvWheatView(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); + tv_time_pk = findViewById(R.id.tv_time_pk); + } + + @Override + protected int getLayoutId() { + return R.layout.room_view_ktv_wheat; + } + + @Override + protected void setPitData(RoomPitBean bean) { + sex = bean.getSex(); + if (isOn()) { + //开启声浪 + mIvRipple.stopAnimation(); + mIvRipple.setVisibility(VISIBLE); + mTvName.setText(bean.getNickname()); + ImageUtils.loadHeadCC(bean.getAvatar(), mRiv); + if (TextUtils.isEmpty(pitBean.getDress())) { + mIvFrame.setVisibility(INVISIBLE); + } else { + mIvFrame.setVisibility(VISIBLE); + mIvFrame.setSource(pitBean.getDress(), 1); +// ImageUtils.loadDecorationAvatar(pitBean.getDress_picture(), mIvFrame); + } + if (showBoss && WHEAT_BOSS.equals(pitNumber)) { + mIvTagBoss.setVisibility(GONE); + } + } else { + mTvName.setText( + "-1".equals(pitNumber) ? "" : + "9".equals(pitNumber) ? "主持位" : + "10".equals(pitNumber) ? "嘉宾位" : + pitNumber + "号麦位" + ); + //麦位上锁 + 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); + mRiv.setImageResource(bean.getIs_lock() == 1 ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default); +// ImageUtils.loadRes(isLocked() ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default, mRiv); + } + if (isMute()) { + ImageUtils.loadRes(R.mipmap.room_microphone_off, mIvSex); + } + mIvFrame.setVisibility(INVISIBLE); + mIvFace.remove(); + //停止声浪 + mIvRipple.stopAnimation(); + mIvRipple.setVisibility(GONE); + } + if (showSexIcon) { + checkSex(); + } + if (pitBean.getNickname() == null || pitBean.getNickname().isEmpty()) { + mCharmView.setVisibility(GONE); + } else { + mCharmView.setVisibility(VISIBLE); + } + + if (pitBean.is_pk() ){ + if (pitBean.getUser_id()!=null && !pitBean.getUser_id().equals("0") && !pitBean.getUser_id().isEmpty()) { + tv_time_pk.setVisibility(VISIBLE); + setSex(pitBean.getCharm(),false); + mCharmView.setVisibility(GONE); + }else { + tv_time_pk.setVisibility(GONE); + } +// ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mCharmView.getLayoutParams(); +// params.width = 35; +// mCharmView.setLayoutParams(params); + + }else { + tv_time_pk.setVisibility(GONE); + mCharmView.setVisibility(VISIBLE); +// ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mCharmView.getLayoutParams(); +// params.width = 52; +// mCharmView.setLayoutParams(params); + } + +// setCardiac(pitBean.getPit_number(), 0.0f); + } + public void setSex( String value, boolean format) { + if (format) { + tv_time_pk.setText(value); + } else { + try { + long xd = Long.parseLong(value); + if (xd > 9999 || xd < -9999) { + tv_time_pk.setText(String.format("%.2fw", xd / 10000.0f)); +// mBinding.tvValue.setText(String.valueOf(xd)); + } else { + tv_time_pk.setText(value); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + 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); + } + + + @Override + public void onRemoteSoundLevelUpdate(String userId, int soundLevel) { + + } + + @Override + public void onLocalSoundLevelUpdate(int volume) { + if (volume==0){ + mIvRipple.stopAnimation(); + } else { + if (pitBean.getUser_id().equals(SpUtil.getUserId()) && closePhone) { + mIvRipple.stopAnimation(); + }else { + mIvRipple.post(() -> { + if (!mIvRipple.isAnimating()) { + mIvRipple.startAnimation(); + } + mIvRipple.setVisibility(VISIBLE); + }); + } + } + } + + @Override + public void userJoined(int userId, int elapsd) { + if (pitBean != null && pitBean.getUser_id() != null && !pitBean.getUser_id().equals("0")) { + if (pitBean.getUser_id().equals(userId + "")) { + iv_on_line.setVisibility(GONE); + } + } + } + + @Override + public void userOffline(int userId, int reason) { + if (pitBean != null && pitBean.getUser_id() != null && !pitBean.getUser_id().equals("0")) { + if (pitBean.getUser_id().equals(userId + "")) { + iv_on_line.setVisibility(VISIBLE); + } + } + } + +} \ No newline at end of file diff --git a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/RoomMakeWheatView.java b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/RoomMakeWheatView.java index 57cf9720..982dedde 100644 --- a/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/RoomMakeWheatView.java +++ b/moduleUtil/src/main/java/com/qxcm/moduleutil/widget/RoomMakeWheatView.java @@ -90,12 +90,7 @@ public class RoomMakeWheatView extends BaseWheatView { 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); mRiv.setImageResource(bean.getIs_lock()==1 ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default); -// ImageUtils.loadRes(isLocked() ? R.mipmap.room_ic_wheat_default_suo : R.mipmap.room_ic_wheat_default, mRiv); } if (isMute()){ ImageUtils.loadRes(R.mipmap.room_microphone_off, mIvSex); diff --git a/moduleUtil/src/main/res/layout/room_view_ktv_wheat.xml b/moduleUtil/src/main/res/layout/room_view_ktv_wheat.xml new file mode 100644 index 00000000..4ba08d8d --- /dev/null +++ b/moduleUtil/src/main/res/layout/room_view_ktv_wheat.xml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modulemain/src/main/java/com/qxcm/modulemain/activity/MainActivity.java b/modulemain/src/main/java/com/qxcm/modulemain/activity/MainActivity.java index 1421bbe6..d750c440 100644 --- a/modulemain/src/main/java/com/qxcm/modulemain/activity/MainActivity.java +++ b/modulemain/src/main/java/com/qxcm/modulemain/activity/MainActivity.java @@ -5,6 +5,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.graphics.Color; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -28,6 +29,7 @@ import com.blankj.utilcode.util.ActivityUtils; import com.blankj.utilcode.util.FragmentUtils; import com.blankj.utilcode.util.ServiceUtils; import com.blankj.utilcode.util.ToastUtils; +import com.bumptech.glide.Glide; import com.example.modulecircle.fragment.CircleFragment; import com.example.modulenews.fragment.NewsFragment; import com.example.moduleroom.activity.RoomActivity; @@ -43,12 +45,14 @@ import com.qxcm.moduleutil.base.CommonAppContext; import com.qxcm.moduleutil.bean.AppUpdateModel; import com.qxcm.moduleutil.bean.FirstChargeBean; import com.qxcm.moduleutil.bean.FirstChargeGiftBean; +import com.qxcm.moduleutil.bean.ThemeBean; import com.qxcm.moduleutil.dialog.FirstChargeDialog; import com.qxcm.moduleutil.dialog.HeavenGiftDialog; import com.qxcm.moduleutil.dialog.RechargeDialogFragment; import com.qxcm.moduleutil.event.RoomOutEvent; import com.qxcm.moduleutil.event.UnreadCountEvent; import com.qxcm.moduleutil.utils.ARouteConstants; +import com.qxcm.moduleutil.utils.BackgroundManager; import com.qxcm.moduleutil.utils.ImageLoader; import com.qxcm.moduleutil.utils.SpUtil; import com.qxcm.moduleutil.utils.logger.Logger; @@ -60,10 +64,12 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; +import java.util.HashMap; +import java.util.Map; + @Route(path = ARouteConstants.ME) public class MainActivity extends BaseMvpActivity implements HomeContacts.View, View.OnClickListener { private static int index = -1; -// private AppUpdateDialog appUpdateDialog; public static boolean isShortsShowing() { return index == 1; @@ -74,6 +80,22 @@ public class MainActivity extends BaseMvpActivity= Build.VERSION_CODES.M) { -// if (!Settings.canDrawOverlays(this)) { -// Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, -// Uri.parse("package:" + getPackageName())); -// startActivityForResult(intent, 100); -// } -// } else { -// // 对于低于 Android 6.0 的设备,无需请求悬浮窗权限 -// // 可在此处添加针对旧版本的处理逻辑(如果需要) -// } - - - // 每11秒执行一次飘屏消息 -// new android.os.Handler().postDelayed(new Runnable() { -// @Override -// public void run() { - - // 通过递归调用实现循环定时 -// new android.os.Handler().postDelayed(this, 1000); -// } -// }, 1000); -// } @Override @@ -175,6 +176,9 @@ public class MainActivity extends BaseMvpActivity colorMap = new HashMap<>(); + colorMap.put("theme_color", themeBean.getTheme_color()); + colorMap.put("btn_text_color", themeBean.getBtn_text_color()); + updateThemeColors(colorMap); + // 更新 UI + updateAllTabUI(); + if (themeBean.getApp_bg()!=null) { + BackgroundManager.getInstance().setBackgroundUrl(themeBean.getApp_bg()); + loadNetworkBackground(); + } + } + + } + + private void updateAllTabUI() { + index = 0; + // 更新图标 + updateMediaIcon(); + updateTrendIcon(); + updateNewsIcon(); + updateMeIcon(); + + // 更新文字 + updateTabTextColors(); + } + + private void updateTrendIcon() { + String imageUrl = (index == 1) ? selectedTrendUrl : unselectedTrendUrl; + + if (!TextUtils.isEmpty(imageUrl)) { + Glide.with(this) + .load(imageUrl) + .placeholder(com.qxcm.moduleutil.R.mipmap.icon_me_trend_unselect) + .into(mBinding.imTrend); + } else { + // 如果没有网络图标,使用默认的选中/未选中状态 + int resId = (index == 1) ? + com.qxcm.moduleutil.R.mipmap.icon_me_trend_select : + com.qxcm.moduleutil.R.mipmap.icon_me_trend_unselect; + mBinding.imTrend.setImageResource(resId); + } + } + + private void updateNewsIcon() { + String imageUrl = (index == 2) ? selectedNewsUrl : unselectedNewsUrl; + + if (!TextUtils.isEmpty(imageUrl)) { + Glide.with(this) + .load(imageUrl) + .placeholder(com.qxcm.moduleutil.R.mipmap.icon_news_un_select) + .into(mBinding.ivNews); + } else { + // 如果没有网络图标,使用默认的选中/未选中状态 + int resId = (index == 2) ? + com.qxcm.moduleutil.R.mipmap.icon_news_select : + com.qxcm.moduleutil.R.mipmap.icon_news_un_select; + mBinding.ivNews.setImageResource(resId); + } + } + + private void updateMeIcon() { + String imageUrl = (index == 3) ? selectedMeUrl : unselectedMeUrl; + + if (!TextUtils.isEmpty(imageUrl)) { + Glide.with(this) + .load(imageUrl) + .placeholder(com.qxcm.moduleutil.R.mipmap.icon_my_un_select) + .into(mBinding.imMe); + } else { + // 如果没有网络图标,使用默认的选中/未选中状态 + int resId = (index == 3) ? + com.qxcm.moduleutil.R.mipmap.icon_my_select : + com.qxcm.moduleutil.R.mipmap.icon_my_un_select; + mBinding.imMe.setImageResource(resId); + } + } + + + private void updateTabTextColors() { + // 更新声播 tab 文字颜色 + if (selectedTextColor != 0 && unselectedTextColor != 0) { + int mediaTextColor = (index == 0) ? selectedTextColor : unselectedTextColor; + mBinding.tvMedia.setTextColor(mediaTextColor); + } + + // 更新语圈 tab 文字颜色 + if (selectedTextColor != 0 && unselectedTextColor != 0) { + int trendTextColor = (index == 1) ? selectedTextColor : unselectedTextColor; + mBinding.tvTrend.setTextColor(trendTextColor); + } + + // 更新消息 tab 文字颜色 + if (selectedTextColor != 0 && unselectedTextColor != 0) { + int newsTextColor = (index == 2) ? selectedTextColor : unselectedTextColor; + mBinding.tvNews.setTextColor(newsTextColor); + } + + // 更新我的 tab 文字颜色 + if (selectedTextColor != 0 && unselectedTextColor != 0) { + int meTextColor = (index == 3) ? selectedTextColor : unselectedTextColor; + mBinding.tvMe.setTextColor(meTextColor); + } + } + + + // @Override // protected void onPause() { // super.onPause(); diff --git a/modulemain/src/main/java/com/qxcm/modulemain/contacts/HomeContacts.java b/modulemain/src/main/java/com/qxcm/modulemain/contacts/HomeContacts.java index 0f77f815..f470bbeb 100644 --- a/modulemain/src/main/java/com/qxcm/modulemain/contacts/HomeContacts.java +++ b/modulemain/src/main/java/com/qxcm/modulemain/contacts/HomeContacts.java @@ -6,6 +6,7 @@ import com.qxcm.moduleutil.activity.IPresenter; import com.qxcm.moduleutil.activity.IView; import com.qxcm.moduleutil.bean.AppUpdateModel; import com.qxcm.moduleutil.bean.FirstChargeBean; +import com.qxcm.moduleutil.bean.ThemeBean; public final class HomeContacts { @@ -24,6 +25,8 @@ public final class HomeContacts { void quitSuccess(String roomId); void myInfoSuccess(FirstChargeBean data); + + void getThemeData(ThemeBean themeBean); } public interface IHomePre extends IPresenter { @@ -46,5 +49,8 @@ public final class HomeContacts { void address_ip(String ip); void getMyInfo(String userId); + + void getThemeData();//主题接口 + } } diff --git a/modulemain/src/main/java/com/qxcm/modulemain/presenter/HomePresenter.java b/modulemain/src/main/java/com/qxcm/modulemain/presenter/HomePresenter.java index 53089d01..992d776c 100644 --- a/modulemain/src/main/java/com/qxcm/modulemain/presenter/HomePresenter.java +++ b/modulemain/src/main/java/com/qxcm/modulemain/presenter/HomePresenter.java @@ -17,6 +17,7 @@ import com.blankj.utilcode.util.ThreadUtils; import com.qxcm.modulemain.contacts.HomeContacts; import com.qxcm.moduleutil.bean.AppUpdateModel; import com.qxcm.moduleutil.bean.FirstChargeBean; +import com.qxcm.moduleutil.bean.ThemeBean; import com.qxcm.moduleutil.bean.UserBean; import com.qxcm.moduleutil.http.BaseObserver; import com.qxcm.moduleutil.presenter.BasePresenter; @@ -360,4 +361,20 @@ public class HomePresenter extends BasePresenter implements H } }); } + + @Override + public void getThemeData() { + api.getThemeData(new BaseObserver() { + + @Override + public void onSubscribe(Disposable d) { + addDisposable(d); + } + + @Override + public void onNext(ThemeBean themeBean) { + MvpRef.get().getThemeData(themeBean); + } + }); + } } diff --git a/modulemain/src/main/res/layout/activity_main.xml b/modulemain/src/main/res/layout/activity_main.xml index bd45198f..a710358c 100644 --- a/modulemain/src/main/res/layout/activity_main.xml +++ b/modulemain/src/main/res/layout/activity_main.xml @@ -45,6 +45,7 @@ android:orientation="vertical"> 0) { for (RoomPitBean roomPitBean : roomInfoResp.getRoom_info().getPit_list()) { if (roomPitBean.getPit_number().equals("9")) { - RoomDefaultWheatView roomDefaultWheatView = mBinding.muZc; + RoomKtvWheatView roomDefaultWheatView = mBinding.muZc; roomDefaultWheatView.setData(roomPitBean); if (roomPitBean.getUser_id().equals(SpUtil.getUserId() + "")) { if (parentFragment != null) { @@ -187,7 +188,7 @@ public class RoomKtvFragment extends BaseMvpFragment @@ -430,7 +429,6 @@ android:id="@+id/avatar_5" android:layout_width="@dimen/dp_36" android:layout_height="@dimen/dp_36" - android:src="@mipmap/room_ic_wheat_default" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -460,7 +458,6 @@ android:id="@+id/avatar_6" android:layout_width="@dimen/dp_36" android:layout_height="@dimen/dp_36" - android:src="@mipmap/room_ic_wheat_default" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/moduleroom/src/main/res/layout/fragment_room_ktv.xml b/moduleroom/src/main/res/layout/fragment_room_ktv.xml index ccdf0c5e..934db8c3 100644 --- a/moduleroom/src/main/res/layout/fragment_room_ktv.xml +++ b/moduleroom/src/main/res/layout/fragment_room_ktv.xml @@ -160,7 +160,7 @@ app:layout_constraintTop_toTopOf="@+id/mu_x_title" tools:text="歌曲名称" /> - - -