1、个人信息完善
2、集成聊天功能 3、完成登录
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
package com.qxcm.moduleutil.activity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
@@ -38,6 +42,18 @@ public abstract class BaseAppCompatActivity<VDB extends ViewDataBinding> extends
|
||||
initView();
|
||||
initData();
|
||||
initCompleted();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 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 的设备,无需请求悬浮窗权限
|
||||
// 可在此处添加针对旧版本的处理逻辑(如果需要)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,32 @@
|
||||
package com.qxcm.moduleutil.activity;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
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.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.qxcm.moduleutil.R;
|
||||
import com.qxcm.moduleutil.base.CommonAppContext;
|
||||
import com.qxcm.moduleutil.bean.UserBean;
|
||||
import com.qxcm.moduleutil.utils.LanguageUtil;
|
||||
import com.tencent.qcloud.tuicore.TUILogin;
|
||||
import com.tencent.qcloud.tuicore.interfaces.TUICallback;
|
||||
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
public abstract class BaseMvpActivity<P extends IPresenter, VDB extends ViewDataBinding> extends BaseAppCompatActivity<VDB> implements IView<Activity> {
|
||||
|
||||
@@ -50,4 +71,106 @@ public abstract class BaseMvpActivity<P extends IPresenter, VDB extends ViewData
|
||||
protected void attachBaseContext(Context newBase) {
|
||||
super.attachBaseContext(LanguageUtil.attachBaseContext(newBase));
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void logOutEvent(UserBean userBean) {
|
||||
// 在用户 UI 点击登录的时候调用
|
||||
TUILogin.login(getBaseContext(), CommonAppContext.getInstance().getCurrentEnvironment().getSdkAppId(), String.valueOf(userBean.getUser_code()), userBean.getTencent_im(), new TUICallback() {
|
||||
@Override
|
||||
public void onError(final int code, final String desc) {
|
||||
LogUtils.e("@@@",code,"描述:",desc);
|
||||
}
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
LogUtils.e("@@@","成功");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示全局飘屏消息(支持任意位置飘过)
|
||||
*
|
||||
* @param message 漂浮内容
|
||||
* @param duration 动画时间(毫秒)
|
||||
*/
|
||||
public void showPiaoPingMessage(String message, long duration) {
|
||||
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||
if (windowManager == null) return;
|
||||
|
||||
int screenWidth = getResources().getDisplayMetrics().widthPixels;
|
||||
int screenHeight = getResources().getDisplayMetrics().heightPixels;
|
||||
|
||||
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_SYSTEM_OVERLAY,
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
|
||||
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
|
||||
// 设置 Gravity 为左上角
|
||||
layoutParams.gravity = Gravity.TOP | Gravity.START;
|
||||
|
||||
// Y 轴随机位置
|
||||
layoutParams.y = (int) ((Math.random() * (screenHeight - 200)));
|
||||
|
||||
// 初始 X 设为负值,确保 View 在屏幕左侧外
|
||||
layoutParams.x = -200;
|
||||
|
||||
View piaoPingView = LayoutInflater.from(this).inflate(R.layout.item_piaoping, null);
|
||||
TextView textView = piaoPingView.findViewById(R.id.tv_content);
|
||||
textView.setText(message);
|
||||
|
||||
windowManager.addView(piaoPingView, layoutParams);
|
||||
|
||||
piaoPingView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
piaoPingView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
|
||||
int viewWidth = piaoPingView.getWidth();
|
||||
|
||||
// 设置锚点为左上角,避免偏移干扰
|
||||
piaoPingView.setPivotX(0);
|
||||
piaoPingView.setPivotY(0);
|
||||
|
||||
// 更新 x 坐标为 -screenWidth,确保 View 完全在屏幕左侧外
|
||||
layoutParams.x = -screenWidth;
|
||||
windowManager.updateViewLayout(piaoPingView, layoutParams);
|
||||
|
||||
// 启动动画:从左外滑入 -> 右外滑出
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(
|
||||
piaoPingView,
|
||||
"translationX",
|
||||
0f, // 初始偏移为 0(此时 View 在左侧外)
|
||||
screenWidth + viewWidth // 向右移动整个屏幕宽度 + View 宽度
|
||||
);
|
||||
animator.setDuration(duration);
|
||||
animator.addUpdateListener(animation -> {
|
||||
float value = (float) animation.getAnimatedValue();
|
||||
LogUtils.d("PiaoPing", "translationX = " + value);
|
||||
});
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
windowManager.removeView(piaoPingView);
|
||||
}
|
||||
});
|
||||
|
||||
// 强制 GPU 渲染
|
||||
piaoPingView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
|
||||
animator.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.qxcm.moduleutil.adapter;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.qxcm.moduleutil.R;
|
||||
import com.qxcm.moduleutil.bean.UserImgList;
|
||||
import com.qxcm.moduleutil.utils.ImageUtils;
|
||||
|
||||
public class UserPhotoWallAdapter extends BaseQuickAdapter<UserImgList, BaseViewHolder> {
|
||||
private boolean b = false;
|
||||
private int longClickPos = -1;
|
||||
|
||||
public UserPhotoWallAdapter() {
|
||||
super(R.layout.me_item_user_photo_wall);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, UserImgList item) {
|
||||
if (helper.getAdapterPosition() == 5) {
|
||||
helper.setVisible(R.id.riv_user_head, false);
|
||||
helper.setVisible(R.id.iv_close, false);
|
||||
} else {
|
||||
helper.setVisible(R.id.riv_user_head, true);
|
||||
if (!"0".equals(item.getId())) {
|
||||
ImageUtils.loadCenterCrop(item.getUrl(), helper.getView(R.id.riv_user_head));
|
||||
if (longClickPos == helper.getAdapterPosition()) {
|
||||
helper.setVisible(R.id.iv_close, true);
|
||||
} else {
|
||||
helper.setVisible(R.id.iv_close, false);
|
||||
}
|
||||
} else {
|
||||
helper.setImageResource(R.id.riv_user_head, com.qxcm.moduleutil.R.mipmap.add_img);
|
||||
helper.setGone(R.id.iv_close, false);
|
||||
}
|
||||
}
|
||||
helper.addOnClickListener(R.id.iv_close);
|
||||
helper.addOnClickListener(R.id.riv_user_head);
|
||||
helper.addOnLongClickListener(R.id.riv_user_head);
|
||||
}
|
||||
|
||||
|
||||
public void setDelete(boolean b) {
|
||||
this.b = b;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setLongClickPos(int pos) {
|
||||
this.longClickPos = pos;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public boolean getDelete() {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.qxcm.moduleutil.bean;
|
||||
|
||||
import com.stx.xhb.xbanner.entity.SimpleBannerInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class BannerModel extends SimpleBannerInfo {
|
||||
|
||||
|
||||
/**
|
||||
* ad_id : 11
|
||||
* type : 2
|
||||
* title : 鱼糖语音·开服送好礼
|
||||
* item_id : 9
|
||||
* link_url : null
|
||||
* content : https://gudao-prod.oss-cn-hangzhou.aliyuncs.com/user-dir/YZrsGTJR5F.jpg
|
||||
* detail_pictures : null
|
||||
*/
|
||||
|
||||
private String ad_id;
|
||||
private String type;
|
||||
private String title;
|
||||
private String item_id;
|
||||
private String link_url;
|
||||
private String content;
|
||||
private ArrayList<String> detail_pictures;
|
||||
|
||||
public String getAd_id() {
|
||||
return ad_id;
|
||||
}
|
||||
|
||||
public void setAd_id(String ad_id) {
|
||||
this.ad_id = ad_id;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getItem_id() {
|
||||
return item_id;
|
||||
}
|
||||
|
||||
public void setItem_id(String item_id) {
|
||||
this.item_id = item_id;
|
||||
}
|
||||
|
||||
public String getLink_url() {
|
||||
return link_url;
|
||||
}
|
||||
|
||||
public void setLink_url(String link_url) {
|
||||
this.link_url = link_url;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public ArrayList<String> getDetail_pictures() {
|
||||
return detail_pictures;
|
||||
}
|
||||
|
||||
public void setDetail_pictures(ArrayList<String> detail_pictures) {
|
||||
this.detail_pictures = detail_pictures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getXBannerUrl() {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.qxcm.moduleutil.bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
/**
|
||||
*@author qx
|
||||
*@data 2025/5/27
|
||||
*@description: 礼盒数据
|
||||
*/
|
||||
@Data
|
||||
public class GiftBoxBean {
|
||||
private String newDataJinbi;
|
||||
private List<GiftBean> giftList;
|
||||
@Data
|
||||
public static class GiftBean {
|
||||
private String giftName; //初级礼盒、高级礼盒
|
||||
private String giftTitle; //最高可以获得的金币数
|
||||
private String getGiftTypeName; //满多少个金币
|
||||
private String giftTypeNumber; //当前的百分比
|
||||
private String giftTypeStatus; //是否已经可以
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.qxcm.moduleutil.bean;
|
||||
|
||||
import lombok.Data;
|
||||
/**
|
||||
*@author qx
|
||||
*@data 2025/5/27
|
||||
*@description: 实名认证点击获取返回的参数
|
||||
*/
|
||||
@Data
|
||||
public class RealNameBean {
|
||||
private String userid;
|
||||
private String nonce;
|
||||
private String sign;
|
||||
private String appid;
|
||||
private String orderNo;
|
||||
private String apiVersion;
|
||||
private String licence;
|
||||
private String faceId;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.qxcm.moduleutil.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RevenueBean {
|
||||
private String title;
|
||||
private String time;
|
||||
private String money;
|
||||
private String type;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.qxcm.moduleutil.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TaskDataBean {
|
||||
private String taskName;//任务名称
|
||||
private String taskNumber;//对应的数量
|
||||
private String taskType;//类型,展示不同的按钮:1.观看,2.完成,3.送礼,4.邀请,5.充值,6.任务
|
||||
private String taskPictureUrl;//任务不同的图片地址
|
||||
private String taskReward;//奖励
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.qxcm.moduleutil.http;
|
||||
|
||||
|
||||
import com.qxcm.moduleutil.bean.RealNameBean;
|
||||
import com.qxcm.moduleutil.bean.UserBean;
|
||||
import com.qxcm.moduleutil.widget.Constants;
|
||||
|
||||
@@ -53,6 +54,9 @@ public interface ApiServer {
|
||||
@POST(Constants.CHANGE_PASSWORD)
|
||||
Call<BaseModel<String>> getPostData(@Field("new_password") String new_password,@Field("mobile") String mobile,@Field("sms_code") String code,@Field("user_id") String userId);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.REAL_NAME_RESULT)
|
||||
Call<BaseModel<String>> getRealNameResult(@Field("orderNo") String order_no);
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.URL_LOGIN)
|
||||
Observable<BaseModel<List<UserBean>>> oauthLogin(@Field("login_token") String login_token);
|
||||
@@ -64,6 +68,10 @@ public interface ApiServer {
|
||||
@POST(Constants.URL_WX_CODE)
|
||||
Observable<BaseModel<List<UserBean>>> authCode1(@Field("code") String login_token);
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(Constants.REAL_NAME)
|
||||
Observable<BaseModel<RealNameBean>> realName(@Field("real_name") String real_name, @Field("card_number") String card_number);
|
||||
|
||||
|
||||
// @FormUrlEncoded
|
||||
// @POST(Constant.URL.ADDBANK)
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.franmontiel.persistentcookiejar.PersistentCookieJar;
|
||||
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
|
||||
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
|
||||
import com.qxcm.moduleutil.base.CommonAppContext;
|
||||
import com.qxcm.moduleutil.bean.RealNameBean;
|
||||
import com.qxcm.moduleutil.bean.UserBean;
|
||||
import com.qxcm.moduleutil.presenter.BasePresenter;
|
||||
import com.qxcm.moduleutil.utils.SystemUtils;
|
||||
@@ -195,4 +196,8 @@ public class RetrofitClient {
|
||||
sApiServer.authCode(netease_token).compose(new DefaultTransformer<>()).subscribe(observer);
|
||||
}
|
||||
}
|
||||
|
||||
public void realName(String real_name, String card_number,BaseObserver<RealNameBean> observer){
|
||||
sApiServer.realName(real_name,card_number).compose(new DefaultTransformer<>()).subscribe(observer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ public enum EnvironmentEnum {
|
||||
"DhpCS82gaigZljYqsWsUWUAZ20dREz",
|
||||
"qx-yusheng",
|
||||
"https://qx-yusheng.oss-cn-hangzhou.aliyuncs.com/",
|
||||
"wx9b6db036ca1073a2"),
|
||||
"wx9b6db036ca1073a2",
|
||||
1600086675),
|
||||
TEST(
|
||||
"http://chat.qxmier.com/",
|
||||
"6rdWuz058oq5OahdbFiGEybUcdahd12J83L34Uc7MrPIrxtFG+rXiwDvRcqNvjwbClbbmvMrmxKVkIysFByBsl0Qe9kqd2w8T/nhK5G6eXXlk2V9AjYCieIU+jRnjZBB+Cfechr6rCGJ2aeBARIsXcRPW7wm9WFK9euh5T+v6Pyte68yNaNdcYCll3+U4/uCEog7HygCnMIbAU+kqoPdmn2H+51YOHW+VsnsHd4w1+I3f8Tt0xLIXGM4GWnQueZ5GR46GTWiSYMy8dCIh9SPIMRyC91GosVcfGPMJSdcXqc=",
|
||||
@@ -17,7 +18,8 @@ public enum EnvironmentEnum {
|
||||
"DhpCS82gaigZljYqsWsUWUAZ20dREz",
|
||||
"qx-yusheng",
|
||||
"https://qx-yusheng.oss-cn-hangzhou.aliyuncs.com/",
|
||||
"wx9b6db036ca1073a2");
|
||||
"wx9b6db036ca1073a2",
|
||||
1600086675);
|
||||
|
||||
private final String serverUrl;
|
||||
private final String ALI_AUTH_KEY;//阿里云授权key
|
||||
@@ -30,7 +32,11 @@ public enum EnvironmentEnum {
|
||||
|
||||
private final String wxAppId;
|
||||
|
||||
EnvironmentEnum(String serverUrl, String ALI_AUTH_KEY, String ossEndPoint, String ossaAcessKeyId, String ossAccessKeySecret, String ossBucketName, String ossBaseUrl,String wxAppId) {
|
||||
private final int sdkAppId;//腾讯云sdkAppId im
|
||||
|
||||
EnvironmentEnum(String serverUrl, String ALI_AUTH_KEY, String ossEndPoint, String ossaAcessKeyId,
|
||||
String ossAccessKeySecret, String ossBucketName, String ossBaseUrl,String wxAppId,
|
||||
int sdkAppId) {
|
||||
this.serverUrl = serverUrl;
|
||||
this.ALI_AUTH_KEY = ALI_AUTH_KEY;
|
||||
this.ossEndPoint = ossEndPoint;
|
||||
@@ -39,6 +45,11 @@ public enum EnvironmentEnum {
|
||||
this.ossBucketName = ossBucketName;
|
||||
this.ossBaseUrl = ossBaseUrl;
|
||||
this.wxAppId=wxAppId;
|
||||
this.sdkAppId=sdkAppId;
|
||||
}
|
||||
|
||||
public int getSdkAppId() {
|
||||
return sdkAppId;
|
||||
}
|
||||
|
||||
public String getWxAppId() {
|
||||
|
||||
@@ -361,4 +361,7 @@ public class Constants {
|
||||
|
||||
public static final String AUTHORIZATION = "/api/Login/AlipayUserInfo";
|
||||
|
||||
public static final String REAL_NAME = "/api/UserData/real_name";//调用实名认证接口
|
||||
public static final String REAL_NAME_RESULT = "/api/UserData/real_name_result";//调用实名认证接口
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.qxcm.moduleutil.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
|
||||
public class CustomBottomSheetDialog extends BottomSheetDialog {
|
||||
public CustomBottomSheetDialog(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.qxcm.moduleutil.widget;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import com.qxcm.moduleutil.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class DoubleTimePickerBottomSheet extends BottomSheetDialogFragment {
|
||||
|
||||
private OnTimeRangeSelectedListener listener;
|
||||
|
||||
public interface OnTimeRangeSelectedListener {
|
||||
void onTimeRangeSelected(Date startDate, Date endDate);
|
||||
}
|
||||
|
||||
public void setOnTimeRangeSelectedListener(OnTimeRangeSelectedListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
return new CustomBottomSheetDialog(requireContext());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.dialog_double_time_picker, container, false);
|
||||
|
||||
// 初始化 TabHost
|
||||
TabHost tabHost = view.findViewById(R.id.tabHost);
|
||||
tabHost.setup();
|
||||
|
||||
tabHost.addTab(tabHost.newTabSpec("start").setIndicator("开始时间").setContent(R.id.start_time_tab));
|
||||
tabHost.addTab(tabHost.newTabSpec("end").setIndicator("结束时间").setContent(R.id.end_time_tab));
|
||||
|
||||
// 初始化 Wheel Views
|
||||
WheelDatePicker wheelStartDate = view.findViewById(R.id.wheel_start_date);
|
||||
WheelTimePicker wheelStartTime = view.findViewById(R.id.wheel_start_time);
|
||||
WheelDatePicker wheelEndDate = view.findViewById(R.id.wheel_end_date);
|
||||
WheelTimePicker wheelEndTime = view.findViewById(R.id.wheel_end_time);
|
||||
|
||||
// 默认设置当前时间
|
||||
Calendar startCal = Calendar.getInstance();
|
||||
wheelStartDate.init(startCal.get(Calendar.YEAR), startCal.get(Calendar.MONTH), startCal.get(Calendar.DAY_OF_MONTH));
|
||||
wheelStartTime.init(startCal.get(Calendar.HOUR_OF_DAY), startCal.get(Calendar.MINUTE),startCal.get(Calendar.SECOND));
|
||||
|
||||
// 设置默认结束时间略晚于开始时间
|
||||
Calendar endCal = (Calendar) startCal.clone();
|
||||
endCal.add(Calendar.HOUR, 1);
|
||||
wheelEndDate.init(endCal.get(Calendar.YEAR), endCal.get(Calendar.MONTH), endCal.get(Calendar.DAY_OF_MONTH));
|
||||
wheelEndTime.init(endCal.get(Calendar.HOUR_OF_DAY), endCal.get(Calendar.MINUTE),endCal.get(Calendar.SECOND));
|
||||
|
||||
// 取消按钮
|
||||
view.findViewById(R.id.btn_cancel).setOnClickListener(v -> dismiss());
|
||||
|
||||
// 确定按钮
|
||||
view.findViewById(R.id.btn_sure).setOnClickListener(v -> {
|
||||
Calendar start = Calendar.getInstance();
|
||||
start.set(wheelStartDate.getYear(), wheelStartDate.getMonth(), wheelStartDate.getDay(),
|
||||
wheelStartTime.getHour(), wheelStartTime.getMinute(), wheelStartTime.getSecond());
|
||||
|
||||
Calendar end = Calendar.getInstance();
|
||||
end.set(wheelEndDate.getYear(), wheelEndDate.getMonth(), wheelEndDate.getDay(),
|
||||
wheelEndTime.getHour(), wheelEndTime.getMinute(), wheelEndTime.getSecond());
|
||||
|
||||
if (end.getTime().before(start.getTime())) {
|
||||
Toast.makeText(requireContext(), "结束时间不能早于开始时间", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (listener != null) {
|
||||
listener.onTimeRangeSelected(start.getTime(), end.getTime());
|
||||
}
|
||||
dismiss();
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,4 +56,5 @@ public class ScrollViewPager extends ViewPager {
|
||||
public void setCurrentItem(int item) {
|
||||
super.setCurrentItem(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.qxcm.moduleutil.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.NumberPicker;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
public class WheelDatePicker extends LinearLayout {
|
||||
|
||||
private NumberPicker yearPicker, monthPicker, dayPicker;
|
||||
private int maxDay = 31;
|
||||
|
||||
public WheelDatePicker(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public WheelDatePicker(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
setOrientation(HORIZONTAL);
|
||||
|
||||
yearPicker = new NumberPicker(context);
|
||||
monthPicker = new NumberPicker(context);
|
||||
dayPicker = new NumberPicker(context);
|
||||
|
||||
LayoutParams params = new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1);
|
||||
yearPicker.setLayoutParams(params);
|
||||
monthPicker.setLayoutParams(params);
|
||||
dayPicker.setLayoutParams(params);
|
||||
|
||||
addView(yearPicker);
|
||||
addView(monthPicker);
|
||||
addView(dayPicker);
|
||||
|
||||
// 初始化年份范围
|
||||
int currentYear = Calendar.getInstance().get(Calendar.YEAR);
|
||||
yearPicker.setMinValue(currentYear - 50);
|
||||
yearPicker.setMaxValue(currentYear + 50);
|
||||
|
||||
// 月份从 1 到 12
|
||||
monthPicker.setMinValue(1);
|
||||
monthPicker.setMaxValue(12);
|
||||
monthPicker.setOnValueChangedListener((picker, oldVal, newVal) -> updateDays());
|
||||
|
||||
// 默认天数范围
|
||||
dayPicker.setMinValue(1);
|
||||
dayPicker.setMaxValue(maxDay);
|
||||
}
|
||||
|
||||
private void updateDays() {
|
||||
int year = yearPicker.getValue();
|
||||
int month = monthPicker.getValue();
|
||||
|
||||
int daysInMonth;
|
||||
if (month == 4 || month == 6 || month == 9 || month == 11) {
|
||||
daysInMonth = 30;
|
||||
} else if (month == 2) {
|
||||
daysInMonth = isLeapYear(year) ? 29 : 28;
|
||||
} else {
|
||||
daysInMonth = 31;
|
||||
}
|
||||
|
||||
int currentDay = dayPicker.getValue();
|
||||
dayPicker.setMaxValue(daysInMonth);
|
||||
if (currentDay > daysInMonth) {
|
||||
dayPicker.setValue(daysInMonth);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isLeapYear(int year) {
|
||||
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
|
||||
}
|
||||
|
||||
public void init(int year, int month, int day) {
|
||||
yearPicker.setValue(year);
|
||||
monthPicker.setValue(month + 1); // Calendar 是 0-based
|
||||
dayPicker.setValue(day);
|
||||
updateDays();
|
||||
}
|
||||
|
||||
public int getYear() {
|
||||
return yearPicker.getValue();
|
||||
}
|
||||
|
||||
public int getMonth() {
|
||||
return monthPicker.getValue() - 1; // 转回 Calendar 的 0-based
|
||||
}
|
||||
|
||||
public int getDay() {
|
||||
return dayPicker.getValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.qxcm.moduleutil.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.NumberPicker;
|
||||
|
||||
public class WheelTimePicker extends LinearLayout {
|
||||
|
||||
private NumberPicker hourPicker, minutePicker, secondPicker;
|
||||
|
||||
public WheelTimePicker(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public WheelTimePicker(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
setOrientation(HORIZONTAL);
|
||||
|
||||
hourPicker = new NumberPicker(context);
|
||||
minutePicker = new NumberPicker(context);
|
||||
secondPicker= new NumberPicker(context);
|
||||
|
||||
LayoutParams params = new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1);
|
||||
hourPicker.setLayoutParams(params);
|
||||
minutePicker.setLayoutParams(params);
|
||||
secondPicker.setLayoutParams(params);
|
||||
|
||||
addView(hourPicker);
|
||||
addView(minutePicker);
|
||||
addView(secondPicker);
|
||||
|
||||
// 设置小时范围
|
||||
hourPicker.setMinValue(0);
|
||||
hourPicker.setMaxValue(23);
|
||||
|
||||
// 设置分钟范围
|
||||
minutePicker.setMinValue(0);
|
||||
minutePicker.setMaxValue(59);
|
||||
|
||||
// 秒范围
|
||||
secondPicker.setMinValue(0);
|
||||
secondPicker.setMaxValue(59);
|
||||
}
|
||||
|
||||
public void init(int hour, int minute, int second) {
|
||||
hourPicker.setValue(hour);
|
||||
minutePicker.setValue(minute);
|
||||
secondPicker.setValue(second);
|
||||
}
|
||||
|
||||
public int getHour() {
|
||||
return hourPicker.getValue();
|
||||
}
|
||||
|
||||
public int getMinute() {
|
||||
return minutePicker.getValue();
|
||||
}
|
||||
|
||||
public int getSecond() {
|
||||
return secondPicker.getValue();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user