张波

添加basefragment。后续业务待梳理,拆解

Showing 44 changed files with 2937 additions and 2 deletions

Too many changes to show.

To preserve performance only 44 of 44+ files are displayed.

@@ -44,8 +44,10 @@ android { @@ -44,8 +44,10 @@ android {
44 dependencies { 44 dependencies {
45 implementation 'androidx.appcompat:appcompat:1.2.0' 45 implementation 'androidx.appcompat:appcompat:1.2.0'
46 implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' 46 implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
47 - implementation 'com.wd:log:1.0.0'  
48 - implementation 'com.wd:wdkitcore:1.0.0' 47 + implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
  48 + implementation 'com.wd:log:1.0.1'
  49 + implementation 'com.wd:wdkitcore:1.0.5'
  50 + implementation 'com.airbnb.android:lottie:5.2.0'
49 } 51 }
50 52
51 uploadArchives { 53 uploadArchives {
  1 +
  2 +package com.wd.foundation.wdkit.animator;
  3 +
  4 +import android.view.View;
  5 +
  6 +import com.airbnb.lottie.LottieAnimationView;
  7 +import com.airbnb.lottie.LottieComposition;
  8 +import com.wd.foundation.wdkitcore.tools.AppContext;
  9 +
  10 +public class AnimUtil {
  11 +
  12 + /**
  13 + * 从本地查找lottie动画
  14 + *
  15 + * @param interactCode 特效name
  16 + */
  17 + public static void showLocalLottieEffects(LottieAnimationView animationView, String interactCode,
  18 + boolean needpaly) {
  19 + try {
  20 + // json文件的路径根据具体需求修改
  21 + LottieComposition composition =
  22 + LottieComposition.Factory.fromFileSync(AppContext.getContext(), interactCode);
  23 + animationView.cancelAnimation();
  24 + animationView.setProgress(0);
  25 + animationView.setComposition(composition);
  26 + if (needpaly) {
  27 + animationView.playAnimation();
  28 + }
  29 + animationView.setVisibility(View.VISIBLE);
  30 + } catch (Exception e) {
  31 + }
  32 + }
  33 +}
  1 +
  2 +package com.wd.foundation.wdkit.base;
  3 +
  4 +import java.util.List;
  5 +
  6 +import android.annotation.TargetApi;
  7 +import android.app.Activity;
  8 +import android.app.Dialog;
  9 +import android.content.Context;
  10 +import android.os.Build;
  11 +import android.os.Bundle;
  12 +import android.util.Log;
  13 +import android.view.KeyEvent;
  14 +import android.view.LayoutInflater;
  15 +import android.view.View;
  16 +import android.view.ViewGroup;
  17 +import android.widget.FrameLayout;
  18 +
  19 +import androidx.annotation.NonNull;
  20 +import androidx.annotation.Nullable;
  21 +import androidx.fragment.app.Fragment;
  22 +import androidx.fragment.app.FragmentManager;
  23 +import androidx.lifecycle.ViewModel;
  24 +import androidx.lifecycle.ViewModelProviders;
  25 +
  26 +import com.wd.base.log.Logger;
  27 +import com.wd.foundation.wdkit.R;
  28 +import com.wd.foundation.wdkit.dialog.DialogUtils;
  29 +import com.wd.foundation.wdkit.statusbar.StatusBarStyleEnum;
  30 +import com.wd.foundation.wdkit.utils.ToolsUtil;
  31 +import com.wd.foundation.wdkit.widget.DefaultView;
  32 +
  33 +/**
  34 + * fragment基类<BR>
  35 + *
  36 + * @author baozhaoxin
  37 + * @version [V1.0.0, 2023/1/28]
  38 + * @since V1.0.0
  39 + */
  40 +public abstract class BaseFragment extends Fragment {
  41 + private boolean isUserVisible = true;
  42 +
  43 + private boolean isViewCreated = false;
  44 +
  45 + private Dialog mLoadingDialog;
  46 +
  47 + protected Activity activity;
  48 +
  49 + /**
  50 + * true java布局,false xml布局
  51 + */
  52 + private boolean isjava;
  53 +
  54 + private Activity mActivity;
  55 +
  56 + FrameLayout layout;
  57 +
  58 + @Override
  59 + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  60 + this.perCreate();
  61 + View rootView;
  62 + if (isjava) {
  63 + rootView = getJavaLayout();
  64 + } else {
  65 + rootView = inflater.inflate(getLayout(), container, false);
  66 + }
  67 + mActivity = getActivity();
  68 + initView(rootView);
  69 + return rootView;
  70 + }
  71 +
  72 + @Override
  73 + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
  74 + super.onViewCreated(view, savedInstanceState);
  75 + isViewCreated = true;
  76 + }
  77 +
  78 + /**
  79 + * 获取指定类型的VM实例<BR>
  80 + * 获取Activity对象的vm
  81 + *
  82 + * @param viewModelClazz VM的类实例
  83 + * @param <T> VM类型
  84 + * @return VM对象
  85 + */
  86 + protected <T extends ViewModel> T getViewModel(Class<T> viewModelClazz) {
  87 + if (null != getActivity()) {
  88 + return ViewModelProviders.of(getActivity()).get(viewModelClazz);
  89 + } else {
  90 + return ViewModelProviders.of(this).get(viewModelClazz);
  91 + }
  92 + }
  93 +
  94 + /**
  95 + * 获取指定类型的VM实例<BR>
  96 + * 获取fragment自己的vm
  97 + *
  98 + * @param viewModelClazz VM的类实例
  99 + * @param <T> VM类型
  100 + * @return VM对象
  101 + */
  102 + protected <T extends ViewModel> T getViewModelThis(Class<T> viewModelClazz) {
  103 + return ViewModelProviders.of(this).get(viewModelClazz);
  104 + }
  105 +
  106 + @Override
  107 + public void onDestroy() {
  108 + super.onDestroy();
  109 + // 在fragment destroy的时候重置isUserVisible
  110 + isUserVisible = true;
  111 + }
  112 +
  113 + /**
  114 + * 获取日志tag
  115 + *
  116 + * @return 日志tag
  117 + */
  118 + protected abstract String getLogTag();
  119 +
  120 + /**
  121 + * 获取当前Fragment布局
  122 + *
  123 + * @return 布局文件
  124 + */
  125 + protected abstract int getLayout();
  126 +
  127 + /**
  128 + * 初始化View<BR>
  129 + * 不要有耗时操作,否则页面加载慢
  130 + *
  131 + * @param rootView 布局根视图
  132 + */
  133 + protected abstract void initView(View rootView);
  134 +
  135 + /**
  136 + * onKeyDown回调<BR>
  137 + * 需要Activity主动触发
  138 + *
  139 + * @param keyCode 按键类型
  140 + * @param event 按键事件
  141 + * @return 是否消费事件
  142 + */
  143 + public boolean onKeyDown(int keyCode, KeyEvent event) {
  144 + return false;
  145 + }
  146 +
  147 + /**
  148 + * onKeyUp 回调<BR>
  149 + * 需要Activity主动触发
  150 + *
  151 + * @param keyCode 按键类型
  152 + * @param event 按键事件
  153 + * @return 是否消费事件
  154 + */
  155 + public boolean onKeyUp(int keyCode, KeyEvent event) {
  156 + return false;
  157 + }
  158 +
  159 + // 标记onResume是否被刚刚调用
  160 + private boolean mResume = false;
  161 +
  162 + /**
  163 + * 用于判断fragment真实展现,不要用其提供的isVisible()方法
  164 + *
  165 + * @return true 可见 false不可见
  166 + */
  167 + public boolean isRealVisible() {
  168 + return getUserVisibleHint() && mResume;
  169 + }
  170 +
  171 + @Override
  172 + public void onResume() {
  173 + super.onResume();
  174 + mResume = true;
  175 + }
  176 +
  177 + @Override
  178 + public void onPause() {
  179 + super.onPause();
  180 + mResume = false;
  181 + }
  182 +
  183 + @Override
  184 + public void onStop() {
  185 + super.onStop();
  186 + mResume = false;
  187 + }
  188 +
  189 + /**
  190 + * 判断是否对用户可见
  191 + */
  192 + public boolean isUserVisible() {
  193 + return /* isVisible() */ isAdded() && getUserVisibleHint() && isUserVisible && parentUserVisible(this);
  194 + }
  195 +
  196 + @Override
  197 + public void setUserVisibleHint(boolean isVisibleToUser) {
  198 + super.setUserVisibleHint(isVisibleToUser);
  199 + if (!isViewCreated) {
  200 + isUserVisible = isVisibleToUser;
  201 + return;
  202 + }
  203 +
  204 + if (isVisibleToUser) {
  205 + userVisible(false);
  206 + } else {
  207 + userInvisible(false);
  208 + }
  209 +
  210 + Log.d("BaseFragment", this.getClass().getName());
  211 + }
  212 +
  213 + /**
  214 + * 判断父Fragment是否可见
  215 + */
  216 + private static boolean parentUserVisible(Fragment fragment) {
  217 + Fragment f = fragment.getParentFragment();
  218 + if (f instanceof BaseFragment) {
  219 + return ((BaseFragment) f).isUserVisible();
  220 + }
  221 +
  222 + while (f != null) {
  223 + if (!f.isVisible() || !f.getUserVisibleHint()) {
  224 + return false;
  225 + }
  226 + f = f.getParentFragment();
  227 + }
  228 +
  229 + return true;
  230 + }
  231 +
  232 + void userVisible(boolean fromActivity) {
  233 + // 父Fragment不可见则不做处理
  234 + if (isUserVisible || (fromActivity && (!getUserVisibleHint() || !parentUserVisible(this)))) {
  235 + return;
  236 + }
  237 +
  238 + isUserVisible = true;
  239 +
  240 + FragmentManager fragmentManager;
  241 + try {
  242 + fragmentManager = getChildFragmentManager();
  243 + } catch (Exception e) {
  244 + onUserVisible(fromActivity);
  245 + return;
  246 + }
  247 +
  248 + List<Fragment> fragments = fragmentManager.getFragments();
  249 + if (fragments == null || fragments.isEmpty()) {
  250 + onUserVisible(fromActivity);
  251 + return;
  252 + }
  253 +
  254 + for (Fragment f : fragments) {
  255 + /*
  256 + * if (!f.isVisible()) {
  257 + * continue;
  258 + * }
  259 + */
  260 +
  261 + if (!(f instanceof BaseFragment)) {
  262 + if (f.getUserVisibleHint() || (fromActivity && parentUserVisible(f))) {
  263 + f.setUserVisibleHint(true);
  264 + }
  265 + continue;
  266 + }
  267 +
  268 + BaseFragment lazy = (BaseFragment) f;
  269 + // 忽略子fragment中有对用户不可见的fragment
  270 + if (!lazy.getUserVisibleHint()) {
  271 + continue;
  272 + }
  273 +
  274 + lazy.userVisible(fromActivity);
  275 + }
  276 + onUserVisible(fromActivity);
  277 + }
  278 +
  279 + void userInvisible(boolean fromActivity) {
  280 + // 已经不可见则无需再调用
  281 + if (!isUserVisible) {
  282 + return;
  283 + }
  284 +
  285 + isUserVisible = false;
  286 +
  287 + FragmentManager fragmentManager;
  288 + try {
  289 + fragmentManager = getChildFragmentManager();
  290 + } catch (Exception e) {
  291 + onUserInvisible(getUserVisibleHint(), fromActivity);
  292 + return;
  293 + }
  294 +
  295 + List<Fragment> fragments = fragmentManager.getFragments();
  296 + if (fragments == null || fragments.isEmpty()) {
  297 + onUserInvisible(getUserVisibleHint(), fromActivity);
  298 + return;
  299 + }
  300 +
  301 + for (Fragment f : fragments) {
  302 + /*
  303 + * if (!f.isVisible()) {
  304 + * continue;
  305 + * }
  306 + */
  307 +
  308 + if (!(f instanceof BaseFragment)) {
  309 + f.setUserVisibleHint(false);
  310 + continue;
  311 + }
  312 +
  313 + BaseFragment lazy = (BaseFragment) f;
  314 + // 忽略子fragment中有对用户不可见的fragment
  315 + if (!lazy.getUserVisibleHint()) {
  316 + continue;
  317 + }
  318 +
  319 + lazy.userInvisible(fromActivity);
  320 + }
  321 + onUserInvisible(getUserVisibleHint(), fromActivity);
  322 + }
  323 +
  324 + /**
  325 + * 进入用户可见壮状态
  326 + *
  327 + * @param callFromActivity 是否是从activity层调用
  328 + */
  329 + protected void onUserVisible(boolean callFromActivity) {
  330 + if (getLogTag() == null) {
  331 + Logger.d("onUserVisible");
  332 + } else {
  333 + Logger.t(getLogTag()).d("onUserVisible");
  334 + }
  335 + }
  336 +
  337 + /**
  338 + * 进入用户不可见状态, app进入后台,或者新的activity被启动时
  339 + *
  340 + * @param userVisibleHint 表示在进入不可见状态时,是否是对用户可见状态,一般情况下在ViewPager里才起作用
  341 + * @param callFromActivity 是否是从activity层调用
  342 + */
  343 + protected void onUserInvisible(boolean userVisibleHint, boolean callFromActivity) {
  344 + if (getLogTag() == null) {
  345 + Logger.d("onUserInvisible");
  346 + } else {
  347 + Logger.t(getLogTag()).d("onUserInvisible");
  348 + }
  349 + }
  350 +
  351 + /**
  352 + * loading 按返回键loading默认消失
  353 + */
  354 + public void startLoading() {
  355 + startLoading(true);
  356 + }
  357 +
  358 + /**
  359 + * loading
  360 + *
  361 + * @param allowCancel 按返回键loading是否消失
  362 + */
  363 + protected void startLoading(boolean allowCancel) {
  364 + if (mActivity == null || mActivity.isFinishing() || mActivity.isDestroyed()) {
  365 + return;
  366 + }
  367 + if (mLoadingDialog == null) {
  368 + createLoadingDialog(allowCancel);
  369 + }
  370 +
  371 + if (mLoadingDialog != null && !mLoadingDialog.isShowing()) {
  372 + mLoadingDialog.show();
  373 + }
  374 + }
  375 +
  376 + protected void stopLoading() {
  377 + if (mActivity == null || mActivity.isFinishing() || mActivity.isDestroyed()) {
  378 + return;
  379 + }
  380 + if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
  381 + mLoadingDialog.dismiss();
  382 + }
  383 + }
  384 +
  385 + private void createLoadingDialog(boolean allowCancel) {
  386 + mLoadingDialog = DialogUtils.creatRequestDialog(mActivity, allowCancel);
  387 + }
  388 +
  389 + /**
  390 + * 增加空布局
  391 + */
  392 + protected View addEmptyView(int emptyType) {
  393 + return addEmptyView(emptyType, null);
  394 + }
  395 +
  396 + /**
  397 + * 增加空布局
  398 + *
  399 + * @return
  400 + */
  401 + protected View addEmptyView(int type, DefaultView.RetryClickListener listener) {
  402 + return addEmptyViewWithWeight(type, null, listener);
  403 + }
  404 +
  405 + /**
  406 + * 增加空布局
  407 + *
  408 + * @return
  409 + */
  410 + protected View addEmptyViewWithWeight(int type, Integer[] weight, DefaultView.RetryClickListener listener) {
  411 + View emptyView = LayoutInflater.from(getContext()).inflate(R.layout.wdkit_empty_view_layout, null);
  412 + DefaultView mDefaultView = emptyView.findViewById(R.id.default_view);
  413 + if (listener != null) {
  414 + mDefaultView.setRetryBtnClickListener(listener);
  415 + }
  416 + if (weight == null || weight.length != 2) {
  417 + mDefaultView.show(type);
  418 + } else {
  419 + mDefaultView.showWithWeight(type, weight[0], weight[1]);
  420 + }
  421 + return emptyView;
  422 + }
  423 +
  424 + @SuppressWarnings({"deprecation"})
  425 + @Override
  426 + public void onAttach(@NonNull Activity activity) {
  427 + super.onAttach(activity);
  428 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
  429 + this.activity = activity;
  430 + }
  431 + }
  432 +
  433 + @TargetApi(23)
  434 + @Override
  435 + public void onAttach(@NonNull Context context) {
  436 + super.onAttach(context);
  437 + if (context instanceof Activity) {
  438 + this.activity = (Activity) context;
  439 + }
  440 + }
  441 +
  442 + public void setStatusBarStyle(@NonNull StatusBarStyleEnum statusBarStyle) {
  443 + ToolsUtil.setStatusBarStyle(statusBarStyle, getActivity());
  444 + }
  445 +
  446 + protected void perCreate() {
  447 +
  448 + }
  449 +
  450 + protected View getJavaLayout() {
  451 + return null;
  452 + }
  453 +
  454 + /**
  455 + * 设置java布局标识
  456 + */
  457 + public void setIsjava(boolean isjava) {
  458 + this.isjava = isjava;
  459 + }
  460 +
  461 + public void onUserLeaveHint() {
  462 +
  463 + }
  464 +
  465 +}
  1 +package com.wd.foundation.wdkit.base;
  2 +
  3 +import com.wd.foundation.wdkit.statusbar.StatusBarStyleEnum;
  4 +import com.wd.foundation.wdkit.widget.DefaultView;
  5 +
  6 +/**
  7 + * 懒加载fragment
  8 + *
  9 + * @author baozhaoxin
  10 + * @version [V1.0.0, 2023/1/28]
  11 + * @since V1.0.0
  12 + */
  13 +public abstract class BaseLazyFragment extends BaseFragment {
  14 +
  15 + /**
  16 + * 记录开启页面时间
  17 + */
  18 + private long startTime;
  19 + /**
  20 + * 浏览时长
  21 + */
  22 + public int duration;
  23 +
  24 + /**
  25 + * 是否第一次加载
  26 + */
  27 + protected boolean isFirstLoad = true;
  28 +
  29 + /**
  30 + * 页面id
  31 + */
  32 + public String mPageId;
  33 +
  34 + // 记录当前页面的原头信息的objectType,目前只用在专题中
  35 + public int objectType = 0;
  36 +
  37 + /**
  38 + * 国殇标记(true:开启了国殇)
  39 + */
  40 + public boolean contryGrayFlag = false;
  41 +
  42 + @Override
  43 + public void setUserVisibleHint(boolean isVisibleToUser) {
  44 + super.setUserVisibleHint(isVisibleToUser);
  45 + }
  46 +
  47 + @Override
  48 + public void onDestroyView() {
  49 + super.onDestroyView();
  50 + isFirstLoad = true;
  51 + long endTime = System.currentTimeMillis();
  52 + duration = (int) (endTime - startTime);
  53 + }
  54 +
  55 + @Override
  56 + public void onResume() {
  57 + super.onResume();
  58 + if (isFirstLoad) {
  59 + startTime = System.currentTimeMillis();
  60 + lazyLoadData();
  61 + isFirstLoad = false;
  62 + }
  63 + }
  64 +
  65 + @Override
  66 + public void onDestroy() {
  67 + super.onDestroy();
  68 + long endTime = System.currentTimeMillis();
  69 + duration = (int) (endTime - startTime);
  70 +
  71 + }
  72 +
  73 + /**
  74 + * viewModel 进入页面加载数据
  75 + */
  76 + protected abstract void lazyLoadData();
  77 +
  78 +
  79 + /**
  80 + * 修改手机顶部状态,只支持白色和黑色
  81 + * @param isWhite
  82 + */
  83 + public void changePhoneStatusBarWhiteOrBlack(boolean isWhite){
  84 + if(isWhite){
  85 + setStatusBarStyle(StatusBarStyleEnum.FULLSCREEN_LIGHT_ENUM);
  86 + }else {
  87 + setStatusBarStyle(StatusBarStyleEnum.FULLSCREEN_DARK_ENUM);
  88 + }
  89 + }
  90 +
  91 + public String getmPageId() {
  92 + return mPageId;
  93 + }
  94 +
  95 + protected void showDefaultView(int type, DefaultView.RetryClickListener listener) {
  96 + addEmptyView(type, listener);
  97 + }
  98 +}
  1 +package com.wd.foundation.wdkit.constant;
  2 +
  3 +/**
  4 + * 缺省页常量
  5 + *
  6 + * @author baozhaoxin
  7 + * @version [V1.0.0, 2023/4/3]
  8 + * @since V1.0.0
  9 + */
  10 +public class DefaultViewConstant {
  11 +
  12 + /**
  13 + * 页面接口报错,用于列表类及其他页面(带重试按钮)
  14 + */
  15 + public static final int TYPE_GET_CONTENT_ERROR = 1;
  16 +
  17 + /**
  18 + * 内容获取失败,用于内容详情页(带重试按钮)
  19 + */
  20 + public static final int TYPE_GET_CONTENT_FAILED = 2;
  21 +
  22 + /**
  23 + * 暂无网络(带重试按钮)
  24 + */
  25 + public static final int TYPE_NO_NETWORK = 3;
  26 +
  27 + /**
  28 + * 暂无内容
  29 + */
  30 + public static final int TYPE_NO_CONTENT = 4;
  31 +
  32 + /**
  33 + * 暂无收藏内容
  34 + */
  35 + public static final int TYPE_NO_COLLECTED = 5;
  36 +
  37 + /**
  38 + * 暂无消息
  39 + */
  40 + public static final int TYPE_NO_RECORDS_MESSAGE = 6;
  41 +
  42 + /**
  43 + * 暂无浏览历史
  44 + */
  45 + public static final int TYPE_NO_RECORDS_BROWSE = 7;
  46 +
  47 + /**
  48 + * 没有找到相关内容
  49 + */
  50 + public static final int TYPE_NO_CONTENT_FOUND = 8;
  51 +
  52 +
  53 + /**
  54 + * 直播结束
  55 + */
  56 + public static final int TYPE_LIVE_END = 10;
  57 +
  58 + /**
  59 + * 暂无评论
  60 + */
  61 + public static final int TYPE_NO_COMMENT = 11;
  62 +
  63 + /**
  64 + * 暂无作品
  65 + */
  66 + public static final int TYPE_NO_WORKS = 12;
  67 + /**
  68 + * 暂无预约
  69 + */
  70 + public static final int TYPE_NO_RESERVATION = 13;
  71 +
  72 + /**
  73 + * 限流
  74 + */
  75 + public static final int TYPE_CURRENT_LIMITING = 14;
  76 + /**
  77 + * 该号主暂时无法访问
  78 + * */
  79 + public static final int TYPE_NO_PERMISSION = 15;
  80 + /**
  81 + * 主播暂时离开,马上回来
  82 + * */
  83 + public static final int TYPE_ANCHOR_LEAVING = 16;
  84 +
  85 + public static final int TYPE_NO_RELEVANT_CONTENT_FOUND = 17;
  86 +
  87 + /**
  88 + * 号主页-暂无作品
  89 + */
  90 + public static final int TYPE_PERSONAL_CENTER_WORKS = 18;
  91 +
  92 + /**
  93 + * 号主页-暂无评论
  94 + */
  95 + public static final int TYPE_PERSONAL_CENTER_COMMENT = 19;
  96 +
  97 + /**
  98 + * 关注列表-暂无关注
  99 + */
  100 + public static final int TYPE_PERSONAL_CENTER_FOCUS = 20;
  101 +
  102 + /**
  103 + * 内容获取失败,用于视频详情页(带重试按钮)
  104 + */
  105 + public static final int TYPE_GET_CONTENT_FAILED_VIDEO = 21;
  106 +
  107 + /**
  108 + * 号主页-暂无关注-有更多点击
  109 + */
  110 + public static final int TYPE_PERSONAL_CENTER_FOCUS_TOP_VIEW = 22;
  111 +}
  1 +
  2 +/*
  3 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2022. All rights reserved.
  4 + */
  5 +
  6 +package com.wd.foundation.wdkit.dialog;
  7 +
  8 +import android.app.Dialog;
  9 +import android.content.Context;
  10 +import android.view.Window;
  11 +import android.view.WindowManager;
  12 +
  13 +import com.airbnb.lottie.LottieAnimationView;
  14 +import com.wd.foundation.wdkit.R;
  15 +import com.wd.foundation.wdkit.widget.progress.PageLoadingView;
  16 +
  17 +/**
  18 + * @author yzm
  19 + * @date 2022/6/27
  20 + * @time 9:34.
  21 + */
  22 +public class DialogUtils {
  23 +
  24 + /**
  25 + * 构造方法
  26 + * @param context
  27 + * @return Dialog
  28 + */
  29 + public static Dialog creatRequestDialog(final Context context) {
  30 + return creatRequestDialog(context, true);
  31 + }
  32 +
  33 +
  34 + /**
  35 + * 创建请求弹窗
  36 + * @param context
  37 + * @param allowCancel
  38 + * @return Dialog
  39 + */
  40 + public static Dialog creatRequestDialog(final Context context, boolean allowCancel) {
  41 + final Dialog dialog = new Dialog(context, R.style.CustomDialog);
  42 + dialog.setContentView(R.layout.wdkit_pdialog_layout);
  43 + Window window = dialog.getWindow();
  44 + WindowManager.LayoutParams lp = window.getAttributes();
  45 + int width = context.getResources().getDisplayMetrics().widthPixels;
  46 + final double scaleFlag = 0.5;
  47 + lp.width = (int) (scaleFlag * width);
  48 + dialog.setCanceledOnTouchOutside(allowCancel);
  49 + dialog.setCancelable(allowCancel);
  50 +
  51 + PageLoadingView loadingView = (PageLoadingView) dialog.findViewById(R.id.channelSmallLoading);
  52 + loadingView.showLoading();
  53 + // dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
  54 + // @Override
  55 + // public void onDismiss(DialogInterface dialogInterface) {
  56 + // loadingView.stopLoading();
  57 + // }
  58 + // });
  59 + return dialog;
  60 + }
  61 +
  62 + /**
  63 + * 一键登录的loading
  64 + * @param context
  65 + * @param allowCancel
  66 + * @return Dialog
  67 + */
  68 + public static Dialog createOneKeyAuthLoading(final Context context, boolean allowCancel) {
  69 + final Dialog dialog = new Dialog(context, R.style.CustomDialog);
  70 + dialog.setContentView(R.layout.wdkit_one_key_auth_login_loading);
  71 + Window window = dialog.getWindow();
  72 + WindowManager.LayoutParams lp = window.getAttributes();
  73 + int width = context.getResources().getDisplayMetrics().widthPixels;
  74 + int height = context.getResources().getDisplayMetrics().heightPixels;
  75 + lp.width = width;
  76 + lp.height = height;
  77 + dialog.setCanceledOnTouchOutside(false);
  78 + dialog.setCancelable(allowCancel);
  79 +
  80 +// RelativeLayout loadingBtn = dialog.findViewById(R.id.loading_btn);
  81 +// RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) loadingBtn.getLayoutParams();
  82 +// layoutParams.topMargin = UiUtils.dp2px(295);
  83 +
  84 + LottieAnimationView loadingView = dialog.findViewById(R.id.one_key_loading);
  85 + loadingView.setAnimation("login_loading.json");
  86 + loadingView.playAnimation();
  87 +
  88 + return dialog;
  89 + }
  90 +
  91 +
  92 + public interface DialogOneButtonClickListener {
  93 + /**
  94 + * 确定
  95 + */
  96 + void okButtonClick();
  97 + }
  98 +
  99 +
  100 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkit.statusbar;
  6 +
  7 +import java.lang.reflect.Field;
  8 +import java.lang.reflect.Method;
  9 +
  10 +import android.annotation.TargetApi;
  11 +import android.app.Activity;
  12 +import android.content.Context;
  13 +import android.content.res.Resources;
  14 +import android.graphics.Color;
  15 +import android.os.Build;
  16 +import android.view.View;
  17 +import android.view.ViewGroup;
  18 +import android.view.Window;
  19 +import android.view.WindowManager;
  20 +
  21 +import androidx.core.content.ContextCompat;
  22 +
  23 +import com.wd.foundation.wdkit.R;
  24 +import com.wd.foundation.wdkitcore.tools.ResUtils;
  25 +
  26 +/**
  27 + * description:状态栏工具类
  28 + *
  29 + * @author lvjinhui
  30 + * @version [V1.0.0, 2022/5/10]
  31 + * @since V1.0.0
  32 + */
  33 +public class StatusBarCompat {
  34 +
  35 + public static final int NOMENU = -20221114;
  36 +
  37 + private static final int MIUI = 1;
  38 +
  39 + private static final int FLYME = 2;
  40 +
  41 + private static final int ANDROID_M = 3;
  42 +
  43 + private static boolean labelIsBlack = true;
  44 +
  45 + private static int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
  46 +
  47 + private StatusBarCompat() {
  48 +
  49 + }
  50 +
  51 + /**
  52 + * Activity全屏显示,但是状态栏不会被覆盖掉,而是正常显示,只是Activity顶端布局会被状态栏覆盖
  53 + *
  54 + * @param activity Activity页面
  55 + * @param statusBarColor 状态栏颜色
  56 + * @param blackLabel 是否深色
  57 + */
  58 + public static void fullScreenStatusBar(Activity activity, int statusBarColor, boolean... blackLabel) {
  59 + if (blackLabel != null && blackLabel.length > 0) {
  60 + labelIsBlack = blackLabel[0];
  61 + }
  62 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  63 + setStatusBarLollipop(activity, false, statusBarColor);
  64 + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  65 + setStatusBarKitkat(activity, false, statusBarColor);
  66 + }
  67 + }
  68 +
  69 + /**
  70 + * Activity全屏显示,但是状态栏不会被覆盖掉,而是正常显示,只是Activity顶端布局会被状态栏覆盖
  71 + *
  72 + * @param activity Activity页面
  73 + */
  74 + public static void fullScreenNoStatusBar(Activity activity) {
  75 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  76 + setStatusBarLollipop(activity, false, NOMENU);
  77 + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  78 + setStatusBarKitkat(activity, false, NOMENU);
  79 + }
  80 + }
  81 +
  82 + /**
  83 + * 设置状态栏全透明
  84 + *
  85 + * @param activity 需要设置的activity
  86 + */
  87 + public static void setTransparent(Activity activity) {
  88 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  89 + return;
  90 + }
  91 + transparentStatusBar(activity);
  92 + setRootView(activity);
  93 + }
  94 +
  95 + /**
  96 + * 使状态栏透明
  97 + */
  98 + @TargetApi(Build.VERSION_CODES.KITKAT)
  99 + private static void transparentStatusBar(Activity activity) {
  100 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  101 + activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  102 + activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  103 + // 需要设置这个flag contentView才能延伸到状态栏
  104 + activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
  105 + // 状态栏覆盖在contentView上面,设置透明使contentView的背景透出来
  106 + activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
  107 + } else {
  108 + // 让contentView延伸到状态栏并且设置状态栏颜色透明
  109 + activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  110 + }
  111 + }
  112 +
  113 + /**
  114 + * 设置根布局参数
  115 + */
  116 + private static void setRootView(Activity activity) {
  117 + ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);
  118 + for (int i = 0, count = parent.getChildCount(); i < count; i++) {
  119 + View childView = parent.getChildAt(i);
  120 + if (childView instanceof ViewGroup) {
  121 + childView.setFitsSystemWindows(true);
  122 + ((ViewGroup) childView).setClipToPadding(true);
  123 + }
  124 + }
  125 + }
  126 +
  127 + /**
  128 + * 状态栏和Activity共存,Activity不全屏显示,应用平常的显示画面
  129 + * 4.4以上可以设置状态栏颜色
  130 + *
  131 + * @param activity Activity页面
  132 + * @param statusBarColor 状态栏颜色
  133 + * @param blackLabel 是否深色
  134 + */
  135 + public static void normalStatusBar(Activity activity, int statusBarColor, boolean... blackLabel) {
  136 + if (blackLabel != null && blackLabel.length > 0) {
  137 + labelIsBlack = blackLabel[0];
  138 + }
  139 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  140 + setStatusBarLollipop(activity, true, statusBarColor);
  141 + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  142 + setStatusBarKitkat(activity, true, statusBarColor);
  143 + }
  144 + }
  145 +
  146 + /**
  147 + * 获取状态栏高度
  148 + *
  149 + * @param activity Activity页面
  150 + * @return 状态栏高度
  151 + */
  152 + public static int getStatusBarHeight(Activity activity) {
  153 + int statusBarHeight = 0;
  154 + int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
  155 + if (resourceId > 0) {
  156 + // 根据资源ID获取响应的尺寸值
  157 + statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
  158 + }
  159 +
  160 + if (statusBarHeight == 0) {
  161 + statusBarHeight = (int) ResUtils.getDimension(R.dimen.wdkit_dp25);
  162 + }
  163 + return statusBarHeight;
  164 +
  165 + }
  166 +
  167 + /**
  168 + * 获取状态栏高度
  169 + * 兼容Android 12及其以上
  170 + *
  171 + * @param activity Activity页面
  172 + * @return 状态栏高度
  173 + */
  174 + public static int getStatusBarHeightNew(Activity activity) {
  175 + int statusBarHeight = 0;
  176 + try {
  177 + Class<?> c = Class.forName("com.android.internal.R$dimen");
  178 + Object object = c.newInstance();
  179 + Field field = c.getField("status_bar_height");
  180 + int x = (Integer) field.get(object);
  181 + statusBarHeight = activity.getResources().getDimensionPixelSize(x);
  182 + } catch (Exception e) {
  183 + e.printStackTrace();
  184 + }
  185 + return statusBarHeight;
  186 + }
  187 +
  188 + /**
  189 + * 获取状态栏高度
  190 + *
  191 + * @param context 上下文
  192 + * @return 状态栏高度
  193 + */
  194 + public static int getStatusBarHeight(Context context) {
  195 + Resources resources = context.getResources();
  196 + int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
  197 + int height = resources.getDimensionPixelSize(resourceId);
  198 + return height;
  199 + }
  200 +
  201 + @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  202 + private static void setStatusBarLollipop(Activity activity, boolean isNormalMode, int statusBarColor) {
  203 + Window window = activity.getWindow();
  204 + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  205 + // isNormalMode 不是全屏
  206 + if (isNormalMode) {
  207 + window.setStatusBarColor(statusBarColor);
  208 + if (labelIsBlack) {
  209 + // 文字黑色
  210 + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
  211 + } else {
  212 + // 文字白色
  213 + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
  214 + }
  215 + } else {
  216 + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  217 + if (NOMENU == statusBarColor) {
  218 + // 全屏无状态栏
  219 + window.getDecorView()
  220 + .setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
  221 + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
  222 + } else {
  223 + window.setStatusBarColor(statusBarColor);
  224 + if (labelIsBlack) {
  225 + // 全屏、文字黑色
  226 + window.getDecorView()
  227 + .setSystemUiVisibility(
  228 + View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
  229 + } else {
  230 + // 全屏、文字白色
  231 + window.getDecorView()
  232 + .setSystemUiVisibility(
  233 + View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
  234 + }
  235 + }
  236 +
  237 + }
  238 + }
  239 +
  240 + @TargetApi(Build.VERSION_CODES.KITKAT)
  241 + private static void setStatusBarKitkat(Activity activity, boolean isNormalMode, int statusBarColor) {
  242 + Window window = activity.getWindow();
  243 + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  244 +
  245 + ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
  246 + if (isNormalMode) {
  247 + contentView.setPadding(0, getStatusBarHeight(activity), 0, 0);
  248 + } else {
  249 + contentView.setPadding(0, 0, 0, 0);
  250 + }
  251 +
  252 + ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
  253 + View statusBarView = decorView.findViewById(R.id.status_view);
  254 + if (statusBarView != null) {
  255 + decorView.removeView(statusBarView);
  256 + }
  257 +
  258 + statusBarView = new View(activity);
  259 + ViewGroup.LayoutParams lp =
  260 + new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
  261 + statusBarView.setBackgroundColor(statusBarColor);
  262 + statusBarView.setId(R.id.status_view);
  263 + decorView.addView(statusBarView, lp);
  264 + }
  265 +
  266 + /**
  267 + * 状态栏亮色模式,设置状态栏黑色文字、图标,
  268 + * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
  269 + *
  270 + * @param activity Activity页面
  271 + * @return 1:MIUUI 2:Flyme 3:android6.0
  272 + */
  273 + public static int setStatusBarLightMode(Activity activity) {
  274 + int result = 0;
  275 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  276 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  277 + activity.getWindow()
  278 + .getDecorView()
  279 + .setSystemUiVisibility(
  280 + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
  281 + result = ANDROID_M;
  282 + } else if (flymeSetStatusBarLightMode(activity.getWindow(), true)) {
  283 + result = FLYME;
  284 + } else if (miuiSetStatusBarLightMode(activity, true)) {
  285 + result = MIUI;
  286 + }
  287 + }
  288 + return result;
  289 + }
  290 +
  291 + /**
  292 + * 状态栏暗色模式,清除MIUI、flyme或6.0以上版本状态栏黑色文字、图标
  293 + *
  294 + * @param activity Activity页面
  295 + * @return 1:MIUUI 2:Flyme 3:android6.0
  296 + */
  297 + public static int setStatusBarDarkMode(Activity activity) {
  298 + int result = 0;
  299 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  300 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  301 + activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
  302 + result = ANDROID_M;
  303 + } else if (flymeSetStatusBarLightMode(activity.getWindow(), false)) {
  304 + result = FLYME;
  305 + } else if (miuiSetStatusBarLightMode(activity, false)) {
  306 + result = MIUI;
  307 + }
  308 + }
  309 + return result;
  310 + }
  311 +
  312 + /**
  313 + * 已知系统类型时,设置状态栏黑色文字、图标。
  314 + * 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
  315 + *
  316 + * @param activity Activity页面
  317 + * @param type 1:MIUUI 2:Flyme 3:android6.0
  318 + */
  319 + public static void setStatusBarLightMode(Activity activity, int type) {
  320 + if (type == MIUI) {
  321 + miuiSetStatusBarLightMode(activity, true);
  322 + } else if (type == FLYME) {
  323 + flymeSetStatusBarLightMode(activity.getWindow(), true);
  324 + } else if (type == ANDROID_M) {
  325 + activity.getWindow()
  326 + .getDecorView()
  327 + .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
  328 + }
  329 + }
  330 +
  331 + /**
  332 + * 状态栏暗色模式,清除MIUI、flyme或6.0以上版本状态栏黑色文字、图标
  333 + *
  334 + * @param activity Activity页面
  335 + * @param type 手机类型,这里区分小米、魅族和通用android M版本以上
  336 + */
  337 + public static void setStatusBarDarkMode(Activity activity, int type) {
  338 + if (type == MIUI) {
  339 + miuiSetStatusBarLightMode(activity, false);
  340 + } else if (type == FLYME) {
  341 + flymeSetStatusBarLightMode(activity.getWindow(), false);
  342 + } else if (type == ANDROID_M) {
  343 + activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
  344 + }
  345 + }
  346 +
  347 + /**
  348 + * 设置状态栏图标为深色和魅族特定的文字风格
  349 + * 可以用来判断是否为Flyme用户
  350 + *
  351 + * @param window 需要设置的窗口
  352 + * @param dark 是否把状态栏文字及图标颜色设置为深色
  353 + * @return boolean 成功执行返回true
  354 + */
  355 + private static boolean flymeSetStatusBarLightMode(Window window, boolean dark) {
  356 + boolean result = false;
  357 + if (window != null) {
  358 + try {
  359 + WindowManager.LayoutParams lp = window.getAttributes();
  360 + Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
  361 + Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
  362 + darkFlag.setAccessible(true);
  363 + meizuFlags.setAccessible(true);
  364 + int bit = darkFlag.getInt(null);
  365 + int value = meizuFlags.getInt(lp);
  366 + if (dark) {
  367 + value |= bit;
  368 + } else {
  369 + value &= ~bit;
  370 + }
  371 + meizuFlags.setInt(lp, value);
  372 + window.setAttributes(lp);
  373 + result = true;
  374 + } catch (Exception e) {
  375 + e.printStackTrace();
  376 + }
  377 + }
  378 + return result;
  379 + }
  380 +
  381 + /**
  382 + * 需要MIUIV6以上
  383 + *
  384 + * @param dark 是否把状态栏文字及图标颜色设置为深色
  385 + * @return boolean 成功执行返回true
  386 + */
  387 + private static boolean miuiSetStatusBarLightMode(Activity activity, boolean dark) {
  388 + boolean result = false;
  389 + Window window = activity.getWindow();
  390 + if (window != null) {
  391 + Class clazz = window.getClass();
  392 + try {
  393 + int darkModeFlag = 0;
  394 + Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
  395 + Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
  396 + darkModeFlag = field.getInt(layoutParams);
  397 + Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
  398 + if (dark) {
  399 + /**
  400 + * 状态栏透明且黑色字体
  401 + */
  402 + extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
  403 + } else {
  404 + /**
  405 + * 清除黑色字体
  406 + */
  407 + extraFlagField.invoke(window, 0, darkModeFlag);
  408 + }
  409 + result = true;
  410 + /**
  411 + * 开发版 7.7.13 及以后版本采用了系统API,旧方法无效但不会报错,所以两个方式都要加上
  412 + */
  413 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  414 + if (dark) {
  415 + activity.getWindow()
  416 + .getDecorView()
  417 + .setSystemUiVisibility(
  418 + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
  419 + } else {
  420 + activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
  421 + }
  422 + }
  423 + } catch (Exception e) {
  424 + e.printStackTrace();
  425 + }
  426 + }
  427 + return result;
  428 + }
  429 +
  430 + /**
  431 + * 设置状态栏背景
  432 + *
  433 + * @param activity Activity页面
  434 + * @param state 状态栏值,如{@link View#SYSTEM_UI_FLAG_LIGHT_STATUS_BAR}
  435 + * @param colorId 背景颜色资源id
  436 + */
  437 + public static void setStatusBar(Activity activity, int state, int colorId) {
  438 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  439 + Window mWindow = activity.getWindow();
  440 + mWindow.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  441 + mWindow.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  442 + mWindow.setStatusBarColor(Color.TRANSPARENT);
  443 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  444 + flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
  445 + }
  446 + activity.getWindow().getDecorView().setSystemUiVisibility(flags);
  447 + // 设置暗色,文字为深色背景透明View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
  448 + // 设置亮色,文字为白色背景透明View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
  449 + setUiVisibility(mWindow, state);
  450 + setColor(mWindow, ContextCompat.getColor(activity, colorId));
  451 + }
  452 +
  453 + }
  454 +
  455 + private static void setColor(Window mWindow, int color) {
  456 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  457 + if (mWindow == null) {
  458 + return;
  459 + }
  460 + mWindow.setStatusBarColor(color);
  461 + }
  462 + }
  463 +
  464 + private static void setUiVisibility(Window mWindow, int statue) {
  465 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  466 + mWindow.getDecorView().setSystemUiVisibility(statue);
  467 + }
  468 + }
  469 +
  470 + /**
  471 + * 设置状态栏背景
  472 + *
  473 + * @param activity Activity页面
  474 + * @param state 状态栏值,如{@link View#SYSTEM_UI_FLAG_LIGHT_STATUS_BAR}
  475 + * @param color 背景颜色
  476 + */
  477 + public static void setStatusBar(Activity activity, int state, String color) {
  478 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  479 + Window mWindow = activity.getWindow();
  480 + mWindow.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  481 + mWindow.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  482 + mWindow.setStatusBarColor(Color.TRANSPARENT);
  483 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  484 + flags = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
  485 + }
  486 + activity.getWindow().getDecorView().setSystemUiVisibility(flags);
  487 + // 设置暗色,文字为深色背景透明View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
  488 + // 设置亮色,文字为白色背景透明View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
  489 + setUiVisibility(mWindow, state);
  490 + setColor(mWindow, color);
  491 + }
  492 +
  493 + }
  494 +
  495 + private static void setColor(Window mWindow, String color) {
  496 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  497 + if (mWindow == null) {
  498 + return;
  499 + }
  500 + mWindow.setStatusBarColor(Color.parseColor(color));
  501 + }
  502 + }
  503 +
  504 + // 获取状态栏高度
  505 +
  506 + public static int getStatusBarHeight2(Context context) {
  507 +
  508 + Class<?> c = null;
  509 +
  510 + Object obj = null;
  511 +
  512 + Field field = null;
  513 +
  514 + int x = 0, statusBarHeight = 0;
  515 +
  516 + try {
  517 +
  518 + c = Class.forName("com.android.internal.R$dimen");
  519 +
  520 + obj = c.newInstance();
  521 +
  522 + field = c.getField("status_bar_height");
  523 +
  524 + x = Integer.parseInt(field.get(obj).toString());
  525 +
  526 + statusBarHeight = context.getResources().getDimensionPixelSize(x);
  527 +
  528 + } catch (Exception e1) {
  529 +
  530 + e1.printStackTrace();
  531 +
  532 + }
  533 +
  534 + return statusBarHeight;
  535 +
  536 + }
  537 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkit.statusbar;
  6 +
  7 +import com.wd.foundation.wdkit.R;
  8 +
  9 +/**
  10 + * 状态栏类型枚举值<BR>
  11 + *
  12 + * @author zhangbo
  13 + * @version [V1.0.0, 2022/5/10]
  14 + * @since V1.0.0
  15 + */
  16 +public enum StatusBarStyleEnum {
  17 + /**
  18 + * 默认值
  19 + */
  20 + NONE(0, false, false),
  21 +
  22 + /**
  23 + * 正常状态栏,黑色背景,白字
  24 + */
  25 + NORMAL_BLACK_LIGHT_ENUM(R.color.color_000000, false, false),
  26 +
  27 + /**
  28 + * 正常状态栏,黑色背景,白字
  29 + */
  30 + NORMAL_161827_LIGHT_ENUM(R.color.color_161827, false, false),
  31 +
  32 + /**
  33 + * 正常状态栏,白色背景,黑字
  34 + */
  35 + NORMAL_WHITE_DARK_ENUM(R.color.color_ffffff, true, false),
  36 +
  37 + /**
  38 + * 正常状态栏,F9F9F9背景,黑字
  39 + */
  40 + NORMAL_F9F9F9_DARK_ENUM(R.color.color_F9F9F9, true, false),
  41 +
  42 + /**
  43 + * 全屏,透明,黑字
  44 + */
  45 + FULLSCREEN_DARK_ENUM(0, true, true),
  46 +
  47 + /**
  48 + * 全屏,透明,白字
  49 + */
  50 + FULLSCREEN_LIGHT_ENUM(0, false, true),
  51 +
  52 + /**
  53 + * 全屏,透明
  54 + */
  55 + FULLSCREEN_NO_ENUM(-1, false, true);
  56 +
  57 + private final int colorId;
  58 +
  59 + private final boolean labelIsBlack;
  60 +
  61 + private final boolean fullScreen;
  62 +
  63 + /**
  64 + * 构造函数
  65 + *
  66 + * @param colorId 背景颜色资源id
  67 + * @param labelIsBlack 状态栏文字是否深色(否,则是白色)
  68 + * @param fullScreen 是否沉浸式状态栏
  69 + */
  70 + StatusBarStyleEnum(int colorId, boolean labelIsBlack, boolean fullScreen) {
  71 + this.colorId = colorId;
  72 + this.labelIsBlack = labelIsBlack;
  73 + this.fullScreen = fullScreen;
  74 + }
  75 +
  76 + public int getColorId() {
  77 + return colorId;
  78 + }
  79 +
  80 + public boolean isLabelIsBlack() {
  81 + return labelIsBlack;
  82 + }
  83 +
  84 + public boolean isFullScreen() {
  85 + return fullScreen;
  86 + }
  87 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2021-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkit.utils;
  6 +
  7 +import android.app.Activity;
  8 +import android.graphics.Color;
  9 +import android.view.View;
  10 +
  11 +import androidx.annotation.NonNull;
  12 +
  13 +import com.wd.foundation.wdkit.statusbar.StatusBarCompat;
  14 +import com.wd.foundation.wdkit.statusbar.StatusBarStyleEnum;
  15 +
  16 +//import top.zibin.luban.OnCompressListener;
  17 +
  18 +/**
  19 + * 工具类
  20 + *
  21 + * @author lvjinhui
  22 + */
  23 +public class ToolsUtil {
  24 +
  25 + private static final String IMAGE_DIR = "people_daily_client";
  26 +
  27 + private static final String CROP_DIR = "crop_image";
  28 +
  29 + private static final int CROP_IMG_SIZE = 1024;
  30 +
  31 + /**
  32 + * 默认一次选择最多的数量
  33 + */
  34 + private static int maxNum = 6;
  35 +
  36 + private static final float SCALE = 0.85f;
  37 +
  38 + private static final int MAX_ORIGINAL_SIZE = 10;
  39 +
  40 + private ToolsUtil() {
  41 + }
  42 +
  43 + public static void setMaxNum(int num) {
  44 + maxNum = num;
  45 + }
  46 +
  47 + // /**
  48 + // * onActivityResult 接收选择的图片和视频
  49 + // *
  50 + // * @param activity activity or fragment
  51 + // * @param mItemList 可以同时选择图片和视频
  52 + // * @param requestCode
  53 + // */
  54 + // public static void selectPicsAndVideo(Activity activity, List<Item> mItemList, int requestCode) {
  55 + // Matisse.from(activity)
  56 + // .choose(MimeType.ofAll(), false)
  57 + // .countable(true)
  58 + // // .capture(true)
  59 + // // .captureStrategy(new CaptureStrategy(true, FileUtils.FILEPROVIDER, IMAGE_DIR))
  60 + // .maxSelectable(maxNum)
  61 + // .setSelectionItems(mItemList)
  62 + // .gridExpectedSize(activity.getResources().getDimensionPixelSize(R.dimen.rmrb_dp88))
  63 + // .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
  64 + // .thumbnailScale(SCALE)
  65 + // .imageEngine(new Glide4Engine())
  66 + // .originalEnable(true)
  67 + // .maxOriginalSize(MAX_ORIGINAL_SIZE)
  68 + // .autoHideToolbarOnSingleTap(true)
  69 + // .setSelType(SelectionSpec.SEL_TYPE_ALL)
  70 + // .forResult(requestCode);
  71 + //
  72 + // }
  73 + //
  74 + // /**
  75 + // * 选择多张图片或单个视频
  76 + // * @param activity
  77 + // * @param mItemList
  78 + // * @param requestCode
  79 + // */
  80 + // public static void selectPicsOrVideo(Activity activity, List<Item> mItemList, int requestCode) {
  81 + // Matisse.from(activity)
  82 + // .choose(MimeType.ofAll(), true)
  83 + // .countable(true)
  84 + //// .maxSelectable(maxNum)
  85 + // .maxSelectablePerMediaType(maxNum,1)
  86 + // .setSelectionItems(mItemList)
  87 + // .gridExpectedSize(activity.getResources().getDimensionPixelSize(R.dimen.rmrb_dp88))
  88 + // .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
  89 + // .thumbnailScale(SCALE)
  90 + // //这两行要连用 是否在选择图片中展示照相 和适配安卓7.0 FileProvider
  91 + // .capture(true)
  92 + // .isVideoAndPic(true)
  93 + // .captureStrategy(new CaptureStrategy(true, BaseConstants.FILE_PROVIDER))
  94 + // .imageEngine(new Glide4Engine())
  95 + // .originalEnable(true)
  96 + // .autoHideToolbarOnSingleTap(true)
  97 + // .showSingleMediaType(true)
  98 + // .setSelType(SelectionSpec.SEL_TYPE_ALL)
  99 + // .forResult(requestCode);
  100 + // }
  101 + //
  102 + // /**
  103 + // * 选择照片
  104 + // *
  105 + // * @param activity
  106 + // * @param mItemList
  107 + // * @param requestCode
  108 + // */
  109 + // public static void selectPhotos(Activity activity, List<Item> mItemList, int requestCode) {
  110 + // Matisse.from(activity)
  111 + // .choose(EnumSet.of(MimeType.JPEG, MimeType.PNG, MimeType.GIF, MimeType.BMP), true)
  112 + // .countable(true)
  113 + // .maxSelectable(maxNum)
  114 + // .setSelectionItems(mItemList)
  115 + // .gridExpectedSize(activity.getResources().getDimensionPixelSize(R.dimen.rmrb_dp88))
  116 + // .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
  117 + // .thumbnailScale(SCALE)
  118 + // .imageEngine(new Glide4Engine())
  119 + // .originalEnable(true)
  120 + // .maxOriginalSize(MAX_ORIGINAL_SIZE)
  121 + // .autoHideToolbarOnSingleTap(true)
  122 + // .showSingleMediaType(true)
  123 + // .setSelType(SelectionSpec.SEL_TYPE_IMG)
  124 + // .forResult(requestCode);
  125 + // }
  126 + //
  127 + // /**
  128 + // * 仅选择视频,多个
  129 + // *
  130 + // * @param activity
  131 + // * @param mItemList
  132 + // * @param requestCode
  133 + // */
  134 + // public static void selectVideos(Activity activity, List<Item> mItemList, int requestCode) {
  135 + // Matisse.from(activity)
  136 + // .choose(MimeType.ofVideo(), true)
  137 + // .countable(true)
  138 + // .maxSelectable(maxNum)
  139 + // .setSelectionItems(mItemList)
  140 + // .gridExpectedSize(activity.getResources().getDimensionPixelSize(R.dimen.rmrb_dp88))
  141 + // .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
  142 + // .thumbnailScale(SCALE)
  143 + // .imageEngine(new Glide4Engine())
  144 + // .originalEnable(true)
  145 + // .maxOriginalSize(MAX_ORIGINAL_SIZE)
  146 + // .autoHideToolbarOnSingleTap(true)
  147 + // .showSingleMediaType(true)
  148 + // .setSelType(SelectionSpec.SEL_TYPE_VOD)
  149 + // .forResult(requestCode);
  150 + //
  151 + // }
  152 + //
  153 + // /**
  154 + // * 相机
  155 + // *
  156 + // * @param activity
  157 + // * @param requestCode
  158 + // * @return 拍照保存的路径
  159 + // */
  160 + // public static String openCamera(Activity activity, int requestCode) {
  161 + // Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  162 + // PackageManager pm = activity.getPackageManager();
  163 + // // Ensure that there's a camera activity to handle the intent
  164 + // if (takePictureIntent.resolveActivity(pm) != null) {
  165 + // // Create the File where the photo should go
  166 + // File photoFile = null;
  167 + // try {
  168 + // photoFile = createImageFile(activity);
  169 + // } catch (IOException ex) {
  170 + // // Error occurred while creating the File
  171 + // }
  172 + // // Continue only if the File was successfully created
  173 + // if (photoFile != null) {
  174 + // Uri photoURI;
  175 + // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  176 + // photoURI = FileProvider.getUriForFile(activity, BaseConstants.FILE_PROVIDER, photoFile);
  177 + // } else {
  178 + // photoURI = Uri.fromFile(photoFile);
  179 + // }
  180 + // takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
  181 + // activity.startActivityForResult(takePictureIntent, requestCode);
  182 + // return photoFile.getAbsolutePath();
  183 + // }
  184 + // }
  185 + //
  186 + // return "";
  187 + // }
  188 + //
  189 + // /**
  190 + // * 图片裁剪
  191 + // *
  192 + // * @param activity
  193 + // * @param file 要裁剪的图片
  194 + // */
  195 + // public static void photoCrop(Activity activity, File file) {
  196 + // File cropFile = MyFileUtils.createFileInDownload(CROP_DIR, MyFileUtils.getFileNameByTime("IMG", "jpg"));
  197 + // String pickCropPath = cropFile.getAbsolutePath();
  198 + // UCrop.Options options = new UCrop.Options();
  199 + // options.setShowCropGrid(false);
  200 + // // 隐藏底部工具
  201 + // options.setHideBottomControls(true);
  202 + // options.setToolbarColor(ContextCompat.getColor(activity, R.color.res_color_common_C9));
  203 + // options.setStatusBarColor(ContextCompat.getColor(activity, R.color.res_color_common_C9));
  204 + //// options.setActiveWidgetColor(ContextCompat.getColor(activity, R.color.res_color_common_C9));
  205 + // options.setToolbarWidgetColor(ContextCompat.getColor(activity, R.color.res_color_common_C8));
  206 + // // 设置图片压缩质量
  207 + // options.setCompressionQuality(100);
  208 + // UCrop.of(Uri.fromFile(file), Uri.parse(pickCropPath))
  209 + // .withMaxResultSize(CROP_IMG_SIZE, CROP_IMG_SIZE)
  210 + // .withAspectRatio(1, 1)
  211 + // .withOptions(options)
  212 + // .start(activity);
  213 + // }
  214 + //
  215 + // /**
  216 + // * 图片裁剪 Options 定义
  217 + // *
  218 + // * @param activity
  219 + // * @param file 要裁剪的图片
  220 + // */
  221 + // public static void photoCropCustom(Activity activity, File file, boolean type) {
  222 + // File cropFile = MyFileUtils.createFileInDownload(CROP_DIR, MyFileUtils.getFileNameByTime("IMG", "jpg"));
  223 + // String pickCropPath = cropFile.getAbsolutePath();
  224 + //
  225 + // UCrop.Options options = new UCrop.Options();
  226 + // // 修改标题栏颜色
  227 + // options.setToolbarColor(ContextCompat.getColor(activity, R.color.color_000000));
  228 + // // 修改状态栏颜色
  229 + // options.setStatusBarColor(ContextCompat.getColor(activity, R.color.color_000000));
  230 + // // 隐藏底部工具
  231 + // options.setHideBottomControls(true);
  232 + // // 图片格式
  233 + // // options.setCompressionFormat(Bitmap.CompressFormat.JPEG);
  234 + // // 设置图片压缩质量
  235 + // options.setCompressionQuality(100);
  236 + // // 是否让用户调整范围(默认false),如果开启,可能会造成剪切的图片的长宽比不是设定的
  237 + // // 如果不开启,用户不能拖动选框,只能缩放图片
  238 + // // options.setFreeStyleCropEnabled(true);
  239 + // // 圆
  240 + // // options.setCircleDimmedLayer(true);
  241 + // // 不显示网格线
  242 + // // options.setShowCropGrid(false);
  243 + //
  244 + // // FileUtils.createOrExistsDir(Config.SAVE_REAL_PATH);
  245 + //
  246 + // UCrop of = UCrop.of(Uri.fromFile(file), Uri.parse(pickCropPath));
  247 + // if (type) {
  248 + // of.withMaxResultSize(525, 294).withAspectRatio(16, 9);
  249 + // } else {
  250 + // of.withMaxResultSize(525, 700).withAspectRatio(3, 4);
  251 + // }
  252 + //
  253 + // of.withOptions(options).start(activity);
  254 + //
  255 + // }
  256 + //
  257 + // /**
  258 + // * 图片裁剪
  259 + // * @param activity
  260 + // * @param file
  261 + // * @param ratioType 1-1:1,2-16:9,3-3:4
  262 + // */
  263 + // public static void pictureCrop(Activity activity, File file, int ratioType) {
  264 + // pictureCrop(activity,file,ratioType, ResUtils.getString(R.string.res_str_crop));
  265 + // }
  266 + //
  267 + // /**
  268 + // * 图片裁剪
  269 + // * @param activity
  270 + // * @param file
  271 + // * @param ratioType 1-1:1,2-16:9,3-3:4,4-3:2
  272 + // * @param title 标题
  273 + // */
  274 + // public static void pictureCrop(Activity activity, File file, int ratioType , String title) {
  275 + // File cropFile = MyFileUtils.createFileInDownload(CROP_DIR, MyFileUtils.getFileNameByTime("IMG", "jpg"));
  276 + // String pickCropPath = cropFile.getAbsolutePath();
  277 + // UCrop.Options options = new UCrop.Options();
  278 + // // 不显示网格线
  279 + // options.setShowCropGrid(false);
  280 + // // 隐藏底部工具
  281 + // options.setHideBottomControls(true);
  282 + // options.setToolbarColor(ContextCompat.getColor(activity, R.color.res_color_common_C9));
  283 + // options.setStatusBarColor(ContextCompat.getColor(activity, R.color.res_color_common_C9));
  284 + // options.setToolbarWidgetColor(ContextCompat.getColor(activity, R.color.res_color_general_000000));
  285 + // // 设置图片压缩质量
  286 + // options.setCompressionQuality(100);
  287 + // options.setToolbarTitle(title);
  288 + // // 是否让用户调整范围(默认false),如果开启,可能会造成剪切的图片的长宽比不是设定的
  289 + // // 如果不开启,用户不能拖动选框,只能缩放图片
  290 + // options.setFreeStyleCropEnabled(false);
  291 + // UCrop of = UCrop.of(Uri.fromFile(file), Uri.parse(pickCropPath));
  292 + // if (ratioType == 1) {
  293 + // of.withMaxResultSize(CROP_IMG_SIZE, CROP_IMG_SIZE).withAspectRatio(1, 1);
  294 + // } else if (ratioType == 2){
  295 + // of.withMaxResultSize(CROP_IMG_SIZE, CROP_IMG_SIZE).withAspectRatio(16, 9);
  296 + // }else if (ratioType == 3){
  297 + // of.withMaxResultSize(CROP_IMG_SIZE, CROP_IMG_SIZE).withAspectRatio(3, 4);
  298 + // }else if (ratioType == 4){
  299 + // of.withMaxResultSize(CROP_IMG_SIZE, CROP_IMG_SIZE).withAspectRatio(3, 2);
  300 + // }
  301 + // of.withOptions(options).startPicCropActivity(activity);
  302 + // }
  303 + //
  304 + // /**
  305 + // * 拍照保存的图片
  306 + // *
  307 + // * @param context
  308 + // * @return image File
  309 + // * @throws IOException
  310 + // */
  311 + // public static File createImageFile(Context context) throws IOException {
  312 + // // Create an image file name
  313 + // String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
  314 + // String imageFileName = "JPEG_" + timeStamp + "_";
  315 + // File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
  316 + // File image = File.createTempFile(imageFileName, ".jpg", storageDir);
  317 + // return image;
  318 + // }
  319 + //
  320 + // public static boolean isStrangePhone() {
  321 + // boolean strangePhone = "mx5".equalsIgnoreCase(Build.DEVICE) || "Redmi Note2".equalsIgnoreCase(Build.DEVICE)
  322 + // || "Z00A_1".equalsIgnoreCase(Build.DEVICE) || "hwH60-L02".equalsIgnoreCase(Build.DEVICE)
  323 + // || "hermes".equalsIgnoreCase(Build.DEVICE)
  324 + // || ("V4".equalsIgnoreCase(Build.DEVICE) && "Meitu".equalsIgnoreCase(Build.MANUFACTURER))
  325 + // || ("m1metal".equalsIgnoreCase(Build.DEVICE) && "Meizu".equalsIgnoreCase(Build.MANUFACTURER));
  326 + //
  327 + // return strangePhone;
  328 + // }
  329 + //
  330 + // /**
  331 + // * 提供精确的除法运算
  332 + // *
  333 + // * @param v1 被除数
  334 + // * @param v2 除数
  335 + // * @return 两个参数的商
  336 + // */
  337 + // public static double divNum(double v1, double v2) {
  338 + // try {
  339 + // int v1IntValue = (int) Math.round(v1);
  340 + // int v2IntValue = (int) Math.round(v2);
  341 + // if (0 == v1IntValue || 0 == v2IntValue) {
  342 + // return 0;
  343 + // }
  344 + // BigDecimal b1 = BigDecimal.valueOf(v1);
  345 + // BigDecimal b2 = BigDecimal.valueOf(v2);
  346 + // return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP).doubleValue();
  347 + // } catch (IllegalArgumentException e) {
  348 + // e.printStackTrace();
  349 + // }
  350 + // return 0;
  351 + // }
  352 + //
  353 + // /**
  354 + // * 单个图片压缩,替换原图
  355 + // *
  356 + // * @param context
  357 + // * @param photo
  358 + // * @param ignoreBy 小于该值不压缩 KB
  359 + // * @param zipListener 回调
  360 + // */
  361 + // public static void luBanZip(Context context, File photo, int ignoreBy, ILuBanZipListener zipListener) {
  362 + // if (photo != null && photo.exists()) {
  363 + // ThreadPoolUtils.submit(new Runnable() {
  364 + // @Override
  365 + // public void run() {
  366 + // try {
  367 + // if (zipListener != null) {
  368 + // zipListener.onStart();
  369 + // }
  370 + //
  371 + // Bitmap image = BitmapFactory.decodeFile(photo.getAbsolutePath());
  372 + // int degree = FileZipUtils.readPictureDegree(photo.getAbsolutePath());// 读取照片旋转角度
  373 + // if (degree > 0) {
  374 + // image = FileZipUtils.rotateBitmap(image, degree); // 旋转照片
  375 + // }
  376 + // Bitmap bitmap = FileZipUtils.compressScale(image, ignoreBy);
  377 + // File directory = new File(context.getFilesDir() + File.separator + Environment.DIRECTORY_PICTURES);
  378 + // File file = new File(directory, SystemClock.uptimeMillis() + ".jpg");
  379 + // if (!directory.exists()) {
  380 + // directory.mkdirs();
  381 + // }
  382 + // FileOutputStream fileOutputStream = new FileOutputStream(file);
  383 + // Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG;
  384 + // bitmap.compress(compressFormat, 100, fileOutputStream);
  385 + // fileOutputStream.flush();
  386 + // fileOutputStream.close();
  387 + // if (zipListener != null) {
  388 + // zipListener.onSuccess(file);
  389 + // }
  390 + // Logger.t("ToolsUtil").e("压缩图片~");
  391 + // } catch (Exception e) {
  392 + // if (zipListener != null) {
  393 + // zipListener.onError(e.getMessage());
  394 + // }
  395 + // }
  396 + //
  397 + // }
  398 + // });
  399 + // } else {
  400 + // if (zipListener != null) {
  401 + // zipListener.onError("原始文件不存在");
  402 + // }
  403 + // }
  404 + //
  405 + // }
  406 +
  407 + public static void setStatusBarStyle(@NonNull StatusBarStyleEnum statusBarStyle, Activity activity) {
  408 + if (statusBarStyle.isFullScreen()) {
  409 + if (-1 == statusBarStyle.getColorId()) {
  410 + // 全屏,即,沉浸式状态栏。需要自己处理好页面内容,因为部分内容会顶到状态栏底部
  411 + StatusBarCompat.fullScreenNoStatusBar(activity);
  412 + } else {
  413 + // 全屏,即,沉浸式状态栏。需要自己处理好页面内容,因为部分内容会顶到状态栏底部
  414 + StatusBarCompat.fullScreenStatusBar(activity, Color.TRANSPARENT, statusBarStyle.isLabelIsBlack());
  415 + }
  416 +
  417 + } else {
  418 + // 修改状态栏背景色,非全屏
  419 + int state = statusBarStyle.isLabelIsBlack() ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
  420 + : View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
  421 + StatusBarCompat.setStatusBar(activity, state, statusBarStyle.getColorId());
  422 + }
  423 + }
  424 +
  425 + // /**
  426 + // * 直播间点赞样式数据转换
  427 + // * 获取点赞样式
  428 + // * love爱心型 thumb点赞手势 pray 祈福 mourning默哀
  429 + // * 默认爱心
  430 + // * @param likeStyle
  431 + // */
  432 + // public static int dealLiveRoomLikeStyle(String likeStyle) {
  433 + // if (StringUtils.isEqual(Constants.STRING_EMPTY, likeStyle)) {
  434 + // return -1;
  435 + // } else if (StringUtils.isEqual(Constants.STRING_PRAY, likeStyle)) {
  436 + // return R.mipmap.icon_like_selected_pray;
  437 + // } else if (StringUtils.isEqual(Constants.STRING_MOURNING, likeStyle)) {
  438 + // return R.mipmap.icon_like_selected_candle;
  439 + // } else {
  440 + // return R.mipmap.icon_like_selected_redheart;
  441 + // }
  442 + // }
  443 + //
  444 + // /**
  445 + // * 点赞样式库
  446 + // * @param likeStyle 点赞样式 1(默认):红心(点赞) 2:大拇指(祈福) 3:蜡烛(默哀) 4:置空 5视频详情页
  447 + // * @param mode 背景色深浅,0浅色用于评论弹框等白色背景的(默认)、1深色用于视频等黑色背景的、2动态详情页等专属 3视频详情专属 4评论点赞专属
  448 + // * @param selected 点赞状态 false未点赞、true已点赞
  449 + // * */
  450 + // public static int getLikeStyle(int likeStyle, int mode, boolean selected){
  451 + // // 点赞样式 1:红心(点赞) 2:大拇指(祈福) 3:蜡烛(默哀) 4:置空
  452 + // if (2 == likeStyle) {
  453 + // //已点赞 深浅色用同一套图标
  454 + // if(selected){
  455 + // return R.mipmap.icon_like_selected_pray;
  456 + // } else{
  457 + // if(1 == mode) {
  458 + // return R.mipmap.icon_like_unselect_night_pray;
  459 + // } else if(2 == mode) {
  460 + // return R.mipmap.icon_like_unselect_grey_pray;
  461 + // }else if(3 == mode){
  462 + // return R.mipmap.icon_like_unselect_video_pray;
  463 + // }else{
  464 + // return R.mipmap.icon_like_unselect_light_pray;
  465 + // }
  466 + // }
  467 + // }else if (3 == likeStyle) {
  468 + // //已点赞 深浅色用同一套图标
  469 + // if (selected) {
  470 + // return R.mipmap.icon_like_selected_candle;
  471 + // } else {
  472 + // if (1 == mode) {
  473 + // return R.mipmap.icon_like_unselect_night_candle;
  474 + // } else if (2 == mode) {
  475 + // return R.mipmap.icon_like_unselect_grey_candle;
  476 + // }else if(3 == mode){
  477 + // return R.mipmap.icon_like_unselect_video_candle;
  478 + // } else {
  479 + // return R.mipmap.icon_like_unselect_light_candle;
  480 + // }
  481 + // }
  482 + // }else if(4 == likeStyle) {
  483 + // return -1;
  484 + // }else{
  485 + // //已点赞 深浅色用同一套图标
  486 + // if(selected){
  487 + // return R.mipmap.icon_like_selected_redheart;
  488 + // }else{
  489 + // if(1 == mode) {
  490 + // return R.mipmap.icon_like_unselect_night_redheart;
  491 + // } else if(2 == mode) {
  492 + // return R.mipmap.icon_like_unselect_grey_redheart;
  493 + // }else if(3 == mode) {
  494 + // return R.mipmap.icon_like_unselect_video_redheart;
  495 + // }else if(4 == mode){
  496 + // return R.mipmap.icon_like_unselect_grey_redheart_comment;
  497 + // }else{
  498 + // return R.mipmap.icon_like_unselect_light_redheart;
  499 + // }
  500 + // }
  501 + // }
  502 + // }
  503 + //
  504 + // /**
  505 + // * 带圈的点赞样式库
  506 + // * @param likeStyle 点赞样式 1:红心(点赞) 2:大拇指(祈福) 3:蜡烛(默哀) 4:置空
  507 + // * @param selected 点赞状态 false未点赞、true已点赞
  508 + // * */
  509 + // public static int getCircleLikeStyle(int likeStyle, boolean selected){
  510 + // if (2 == likeStyle) {
  511 + // if(selected){
  512 + // return R.mipmap.icon_like_selected_light_pray_circle;
  513 + // }else{
  514 + // return R.mipmap.icon_like_unselect_light_pray_circle;
  515 + // }
  516 + // }else if (3 == likeStyle) {
  517 + // if(selected){
  518 + // return R.mipmap.icon_like_selected_light_candle_circle;
  519 + // }else{
  520 + // return R.mipmap.icon_like_unselect_light_candle_circle;
  521 + // }
  522 + // }else {
  523 + // if(selected){
  524 + // return R.mipmap.icon_like_selected_light_redheart_circle;
  525 + // }else{
  526 + // return R.mipmap.icon_like_unselect_light_redheart_circle;
  527 + // }
  528 + // }
  529 + // }
  530 + //
  531 + // /**
  532 + // * 获取分享点赞名称
  533 + // * @param likeStyle
  534 + // * @return
  535 + // */
  536 + // public static int getCircleLikeName(int likeStyle){
  537 + // if (2 == likeStyle) {
  538 + // //祈祷
  539 + // return R.string.share_to_like_pray;
  540 + // }else if (3 == likeStyle) {
  541 + // //默哀
  542 + // return R.string.share_to_like_silent;
  543 + // }else {
  544 + // //点赞
  545 + // return R.string.share_to_like;
  546 + // }
  547 + // }
  548 + //
  549 + // /**
  550 + // * 收藏样式库
  551 + // * 设置收藏图标
  552 + // * @param mode 背景色深浅,0浅色用于评论弹框等白色背景的(默认)、1深色用于视频等黑色背景的、2分享弹窗里面的收藏(带圈)、 3视频详情页
  553 + // */
  554 + // public static int getCollectStyle(int mode, boolean selected) {
  555 + // if (selected) {
  556 + // if(mode == 2){
  557 + // return R.mipmap.ic_share_collected;
  558 + // }else{
  559 + // return R.mipmap.icon_collect_select;
  560 + // }
  561 + // }else {
  562 + // if(mode == 1) {
  563 + // return R.mipmap.icon_collect_unselect_night;
  564 + // }else if(mode == 2) {
  565 + // return R.mipmap.ic__collect_unselect_pop;
  566 + // }else if(mode == 3){
  567 + // return R.mipmap.ic_collect_unselected_video;
  568 + // }else{
  569 + // return R.mipmap.icon_collect_unselect_light;
  570 + // }
  571 + // }
  572 + // }
  573 + //
  574 + // /**
  575 + // * 点赞动效库
  576 + // * */
  577 + // public static String getLikeStyleAnimation(int likeStyle){
  578 + // // 点赞样式 1:红心(点赞) 2:大拇指(祈福) 3:蜡烛(默哀) 4:置空
  579 + // String selRes = "";
  580 + // if (1 == likeStyle) {
  581 + // selRes = "like_article.json";
  582 + // }else if (2 == likeStyle) {
  583 + // selRes = "like_pray_40.json";
  584 + // }else if (3 == likeStyle) {
  585 + // selRes = "like_candle_40.json";
  586 + // }
  587 + // return selRes;
  588 + // }
  589 + //
  590 + // /**
  591 + // * 收藏成功
  592 + // */
  593 + // public static void showAddCollectLabelDialog(Context context,
  594 + // List<CollectContentBean> contentList
  595 + // , AddFavoriteLabelCallback addFavoriteLabelCallback) {
  596 + // if(context == null)
  597 + // {
  598 + // return;
  599 + // }
  600 + //
  601 + // if(context instanceof Activity)
  602 + // {
  603 + // if(((Activity) context).isFinishing() || ((Activity) context).isDestroyed())
  604 + // {
  605 + // return;
  606 + // }
  607 + // }
  608 + // CollectDialog.createDialog(context, contentList,addFavoriteLabelCallback).show();
  609 + // }
  610 +}
  1 +package com.wd.foundation.wdkit.viewclick;
  2 +
  3 +import java.util.Calendar;
  4 +
  5 +import android.view.View;
  6 +
  7 +/**
  8 + * 防止快速点击
  9 + *
  10 + * @author baozhaoxin
  11 + * @version [V1.0.0, 2023/2/7]
  12 + * @since V1.0.0
  13 + */
  14 +public abstract class BaseClickListener implements View.OnClickListener {
  15 + /**
  16 + * 点击事件间隔 这里设置不能少于多长时间
  17 + */
  18 + public static final int MIN_CLICK_DELAY_TIME = 800;
  19 +
  20 + private long lastClickTime = 0;
  21 +
  22 + /**
  23 + * 连续点击控制
  24 + *
  25 + * @param v
  26 + */
  27 + protected abstract void onNoDoubleClick(View v);
  28 +
  29 + @Override
  30 + public void onClick(View v) {
  31 + long currentTime = Calendar.getInstance().getTimeInMillis();
  32 + if (currentTime - lastClickTime > MIN_CLICK_DELAY_TIME) {
  33 + lastClickTime = currentTime;
  34 + onNoDoubleClick(v);
  35 + }
  36 + }
  37 +}
  1 +
  2 +package com.wd.foundation.wdkit.widget;
  3 +
  4 +import android.content.Context;
  5 +import android.content.res.TypedArray;
  6 +import android.util.AttributeSet;
  7 +import android.util.TypedValue;
  8 +import android.view.LayoutInflater;
  9 +import android.view.View;
  10 +import android.view.ViewGroup;
  11 +import android.widget.ImageView;
  12 +import android.widget.LinearLayout;
  13 +import android.widget.TextView;
  14 +
  15 +import androidx.annotation.Nullable;
  16 +import androidx.constraintlayout.widget.ConstraintLayout;
  17 +
  18 +import com.wd.foundation.wdkit.R;
  19 +import com.wd.foundation.wdkit.constant.DefaultViewConstant;
  20 +import com.wd.foundation.wdkit.viewclick.BaseClickListener;
  21 +import com.wd.foundation.wdkitcore.tools.ResUtils;
  22 +
  23 +/**
  24 + * 缺省页
  25 + * TODO 待拆,往上层业务抛
  26 + * @author baozhaoxin
  27 + * @version [V1.0.0, 2023/3/31]
  28 + * @since V1.0.0
  29 + */
  30 +public class DefaultView extends LinearLayout {
  31 +
  32 + /**
  33 + * 根view
  34 + */
  35 + private View rootView;
  36 +
  37 + /**
  38 + * View 距离top高度
  39 + */
  40 + private View topView, btmView;
  41 +
  42 + /**
  43 + * 根布局
  44 + */
  45 + private LinearLayout defaultRootLayout;
  46 +
  47 + /**
  48 + * 内容布局
  49 + */
  50 + private LinearLayout defaultLayout;
  51 +
  52 + /**
  53 + * 图标
  54 + */
  55 + private ImageView defaultImg;
  56 +
  57 + private ConstraintLayout topMenuView;
  58 +
  59 + /**
  60 + * 文案
  61 + */
  62 + private TextView defaultTv;
  63 +
  64 + /**
  65 + * 重试按钮
  66 + */
  67 + private TextView defaultBtn;
  68 +
  69 + /**
  70 + * 上下文环境
  71 + */
  72 + private Context mContext;
  73 +
  74 + /**
  75 + * 1.页面接口报错,用于列表类及其他页面(带重试按钮):Loading failed, please try again!
  76 + * 2.内容获取失败,用于内容详情页(带重试按钮):An error occurred. Please try again later.
  77 + * 3.暂无网络(带重试按钮):网络出小差了,请检查网络后重试!
  78 + * 4.暂无内容:No content
  79 + * 5.暂无收藏内容:You haven't collected anything yet. Go to the home page.
  80 + * 6.暂无消息:No records
  81 + * 7.暂无浏览历史:No records
  82 + * 8.暂无搜索结果:No content found
  83 + */
  84 + private int mType = -1;// DefaultViewConstant.TYPE_GET_CONTENT_ERROR;
  85 +
  86 + /**
  87 + * 重试按钮点击监听
  88 + */
  89 + private RetryClickListener retryClickListener;
  90 +
  91 + /**
  92 + * 缺省页面布局,true:用带NestedScrollView布局;false:不带带NestedScrollView布局
  93 + */
  94 + private boolean nestedScrollView = false;
  95 +
  96 + public DefaultView(Context context) {
  97 + this(context, null);
  98 + }
  99 +
  100 + public DefaultView(Context context, boolean nestedScrollView) {
  101 + super(context);
  102 + this.nestedScrollView = nestedScrollView;
  103 + initView(context);
  104 +
  105 + }
  106 +
  107 + public DefaultView(Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs) {
  108 + this(context, attrs, 0);
  109 + }
  110 +
  111 + public DefaultView(Context context, @Nullable @org.jetbrains.annotations.Nullable AttributeSet attrs,
  112 + int defStyleAttr) {
  113 + super(context, attrs, defStyleAttr);
  114 + // 获取定义的一些属性
  115 + TypedArray styleAttrs =
  116 + context.getTheme().obtainStyledAttributes(attrs, R.styleable.DefaultView, defStyleAttr, 0);
  117 + // 数一数有多少个属性呢
  118 + int indexCount = styleAttrs.getIndexCount();
  119 + // 循环遍历的方式,找到我们所定义的一些属性
  120 + for (int i = 0; i < indexCount; i++) {
  121 + // 属性的索引值
  122 + int attrIndex = styleAttrs.getIndex(i);
  123 + // 根据索引值给java代码中的成员变量赋值
  124 + if (attrIndex == R.styleable.DefaultView_default_view_type) {
  125 + mType = styleAttrs.getInteger(attrIndex, -1);
  126 + }
  127 + }
  128 + // 资源文件中的属性回收
  129 + styleAttrs.recycle();
  130 + initView(context);
  131 + }
  132 +
  133 + /**
  134 + * 初始化view
  135 + *
  136 + * @param context
  137 + */
  138 + private void initView(Context context) {
  139 + mContext = context;
  140 + if (rootView == null) {
  141 + if (nestedScrollView) {
  142 + rootView = LayoutInflater.from(context).inflate(R.layout.wdkit_default_layout_nested_sc, this);
  143 + } else {
  144 + rootView = LayoutInflater.from(context).inflate(R.layout.wdkit_default_layout, this);
  145 + }
  146 +
  147 + }
  148 + if (rootView != null) {
  149 + defaultRootLayout = rootView.findViewById(R.id.default_root_layout);
  150 + topView = rootView.findViewById(R.id.top_View);
  151 + btmView = rootView.findViewById(R.id.btmspaceview);
  152 + defaultLayout = rootView.findViewById(R.id.default_content_layout);
  153 + defaultImg = rootView.findViewById(R.id.default_img);
  154 + topMenuView = rootView.findViewById(R.id.layout_follow_more_creator);
  155 +
  156 + defaultTv = rootView.findViewById(R.id.default_tv);
  157 + defaultBtn = rootView.findViewById(R.id.default_btn);
  158 + defaultBtn.setOnClickListener(new OnClickListener() {
  159 + @Override
  160 + public void onClick(View v) {
  161 + if (retryClickListener != null) {
  162 + retryClickListener.onRetryClick();
  163 + }
  164 + }
  165 + });
  166 + }
  167 + // 显示默认缺省页面
  168 + show(mType);
  169 + // defaultRootLayout.setVisibility(GONE);
  170 + }
  171 +
  172 + public void show(int type) {
  173 + show(type, false, false);
  174 + }
  175 +
  176 + /**
  177 + * 展示布局,同时设置顶部底部比例
  178 + */
  179 + public void showWithWeight(int type, int topWeight, int btmWeight) {
  180 + setTopBtmWeight(topWeight, btmWeight);
  181 + show(type, false, false);
  182 + }
  183 +
  184 + /**
  185 + * 展示布局,设置top和btm距离,适合容器是wrap_parent
  186 + */
  187 + public void setTopBtmHeight(int type, int topWeight, int btmWeight) {
  188 + setTopBtmHeight(topWeight, btmWeight);
  189 + show(type, false, false);
  190 + }
  191 +
  192 + /**
  193 + * 显示缺省页
  194 + *
  195 + * @param type 1.页面接口报错,用于列表类及其他页面(带重试按钮):Loading failed, please try again!
  196 + * 2.内容获取失败,用于内容详情页(带重试按钮):An error occurred. Please try again later.
  197 + * 3.暂无网络(带重试按钮):网络出小差了,请检查网络后重试!
  198 + * 4.暂无内容:No content
  199 + * 5.暂无收藏内容:You haven't collected anything yet. Go to the home page.
  200 + * 6.暂无消息:No records
  201 + * 7.暂无浏览历史:No records
  202 + * 8.暂无搜索结果:No content found
  203 + * 9.确认提交
  204 + * 10.直播结束
  205 + * 11.没有找到相关内容(2023/11/6 新增 )DefaultViewConstant.TYPE_NO_RELEVANT_CONTENT_FOUND
  206 + * @param hasTry true带重试按钮、false不带重试按钮
  207 + * @param isDark true黑模式、false正常模式
  208 + */
  209 + public void show(int type, boolean hasTry, boolean isDark) {
  210 + if (type == -1) {
  211 + return;
  212 + }
  213 + mType = type;
  214 + if (isDark) {
  215 + // 黑色样式
  216 + setDarkMode();
  217 + }
  218 + // 点击重试按钮
  219 + defaultBtn.setVisibility(hasTry ? VISIBLE : GONE);
  220 + topMenuView.setVisibility(GONE);
  221 + if (type == DefaultViewConstant.TYPE_GET_CONTENT_FAILED) {
  222 + // 内容获取失败,用于内容详情页
  223 + if (isDark) {
  224 + // 灰粉:直播间、视频
  225 + defaultImg.setBackgroundResource(R.mipmap.wdkit_icon_default_get_content_failed_greypink);
  226 + } else {
  227 + // 白粉:通用
  228 + defaultImg.setBackgroundResource(R.mipmap.wdkit_icon_default_get_content_failed_whitepink);
  229 + }
  230 + defaultTv.setText(ResUtils.getString(R.string.default_get_content_failed));
  231 + } else if (type == DefaultViewConstant.TYPE_GET_CONTENT_ERROR) {
  232 + // 内容获取失败,用于内容详情页
  233 + if (isDark) {
  234 + // 灰粉:直播间、视频
  235 + defaultImg.setBackgroundResource(R.mipmap.wdkit_icon_default_get_content_failed_greypink);
  236 + } else {
  237 + // 白粉:通用
  238 + defaultImg.setBackgroundResource(R.mipmap.wdkit_icon_default_get_content_failed_whitepink);
  239 + }
  240 + defaultTv.setText(ResUtils.getString(R.string.default_get_content_failed));
  241 + defaultBtn.setVisibility(VISIBLE);
  242 + } else if (type == DefaultViewConstant.TYPE_NO_NETWORK) {
  243 + // 暂无网络
  244 + defaultImg.setBackgroundResource(R.mipmap.icon_default_no_network);
  245 + defaultTv.setText(ResUtils.getString(R.string.default_no_network));
  246 + } else if (type == DefaultViewConstant.TYPE_NO_COLLECTED) {
  247 + // 暂无收藏
  248 + defaultImg.setBackgroundResource(R.mipmap.icon_default_no_collected);
  249 + defaultTv.setText(ResUtils.getString(R.string.no_collection));
  250 + } else if (type == DefaultViewConstant.TYPE_NO_RECORDS_MESSAGE) {
  251 + // 暂无消息
  252 + defaultImg.setBackgroundResource(R.mipmap.icon_default_no_records_message);
  253 + defaultTv.setText(ResUtils.getString(R.string.default_no_records));
  254 + } else if (type == DefaultViewConstant.TYPE_NO_RECORDS_BROWSE) {
  255 + // 暂无浏览历史
  256 + defaultImg.setBackgroundResource(R.mipmap.icon_default_noworkorreservation);
  257 + defaultTv.setText(ResUtils.getString(R.string.no_browsing_history));
  258 + } else if (type == DefaultViewConstant.TYPE_NO_CONTENT_FOUND) {
  259 + // 没有找到相关内容(搜索)
  260 + defaultImg.setBackgroundResource(R.mipmap.icon_default_no_search_result);
  261 + defaultTv.setText(ResUtils.getString(R.string.default_no_content_found));
  262 + } else if (type == DefaultViewConstant.TYPE_LIVE_END) {
  263 + // 直播结束
  264 + defaultImg.setBackgroundResource(R.mipmap.icon_default_live_end);
  265 + defaultTv.setText(ResUtils.getString(R.string.tips_end_of_live_broadcast));
  266 + } else if (type == DefaultViewConstant.TYPE_NO_COMMENT) {
  267 + // 暂无评论
  268 + defaultImg.setBackgroundResource(R.mipmap.icon_default_nocomment);
  269 + defaultTv.setText(ResUtils.getString(R.string.nocomment));
  270 + } else if (type == DefaultViewConstant.TYPE_NO_WORKS || type == DefaultViewConstant.TYPE_NO_RESERVATION
  271 + || type == DefaultViewConstant.TYPE_NO_CONTENT) {
  272 + // 暂无预约、暂无作品、暂无内容
  273 + defaultImg.setBackgroundResource(R.mipmap.icon_default_noworkorreservation);
  274 + if (type == DefaultViewConstant.TYPE_NO_WORKS) {
  275 + defaultTv.setText(ResUtils.getString(R.string.noworks));
  276 + } else if (type == DefaultViewConstant.TYPE_NO_RESERVATION) {
  277 + defaultTv.setText(ResUtils.getString(R.string.noreservation));
  278 + } else if (type == DefaultViewConstant.TYPE_NO_CONTENT) {
  279 + defaultTv.setText(ResUtils.getString(R.string.default_no_content));
  280 + }
  281 + } else if (type == DefaultViewConstant.TYPE_CURRENT_LIMITING) {
  282 + // 限流
  283 + defaultImg.setBackgroundResource(R.mipmap.icon_currentlimiting);
  284 + defaultTv.setText(ResUtils.getString(R.string.currentlimiting) + "(10s)");
  285 + } else if (type == DefaultViewConstant.TYPE_NO_PERMISSION) {
  286 + // 该号主暂时无法访问
  287 + defaultImg.setBackgroundResource(R.mipmap.icon_no_permission);
  288 + defaultTv.setText(ResUtils.getString(R.string.nopermission));
  289 + } else if (type == DefaultViewConstant.TYPE_ANCHOR_LEAVING) {
  290 + // 主播暂时离开,马上回来
  291 + defaultImg.setBackgroundResource(R.mipmap.icon_anchor_leaving);
  292 + defaultTv.setText(ResUtils.getString(R.string.anchor_leaving));
  293 + } else if (type == DefaultViewConstant.TYPE_NO_RELEVANT_CONTENT_FOUND) {
  294 + // 没有找到相关内容
  295 + defaultImg.setBackgroundResource(R.mipmap.wdkit_icon_no_relevant_content_found);
  296 + defaultTv.setText(ResUtils.getString(R.string.no_relevant_content_found));
  297 + defaultImg.getLayoutParams().height = (int) mContext.getResources().getDimension(R.dimen.wdkit_dp139);
  298 + defaultImg.getLayoutParams().width = (int) mContext.getResources().getDimension(R.dimen.wdkit_dp200);
  299 + } else if (type == DefaultViewConstant.TYPE_PERSONAL_CENTER_WORKS) {
  300 + // 号主页-暂无作品
  301 + defaultImg.setBackgroundResource(R.mipmap.ic_no_works_yet);
  302 + defaultTv.setText(ResUtils.getString(R.string.no_works_yet));
  303 + } else if (type == DefaultViewConstant.TYPE_PERSONAL_CENTER_COMMENT) {
  304 + // 号主页-暂无评论
  305 + defaultImg.setBackgroundResource(R.mipmap.ic_no_comment_yet);
  306 + defaultTv.setText(ResUtils.getString(R.string.no_comment_yet));
  307 + } else if (type == DefaultViewConstant.TYPE_PERSONAL_CENTER_FOCUS) {
  308 + // 号主页-暂无关注
  309 + defaultImg.setBackgroundResource(R.mipmap.ic_no_focus_yet);
  310 + defaultTv.setText(ResUtils.getString(R.string.no_focus_yet));
  311 + } else if (type == DefaultViewConstant.TYPE_PERSONAL_CENTER_FOCUS_TOP_VIEW) {
  312 + defaultImg.setBackgroundResource(R.mipmap.ic_no_focus_yet);
  313 + defaultTv.setText(ResUtils.getString(R.string.no_focus_yet));
  314 + setTopMenuViewShow();
  315 + } else if (type == DefaultViewConstant.TYPE_GET_CONTENT_FAILED_VIDEO) {
  316 + // 内容获取失败,用于视频详情页(带重试按钮)
  317 + defaultImg.setBackgroundResource(R.mipmap.icon_default_get_content_failed_video);
  318 + defaultTv.setText(ResUtils.getString(R.string.default_get_content_failed));
  319 + defaultBtn.setTextColor(ResUtils.getColor(R.color.color_CCCCCC));
  320 + } else {
  321 + // 页面接口报错,用于列表类及其他页面(带重试按钮)
  322 + defaultImg.setBackgroundResource(R.mipmap.wdkit_icon_default_get_content_failed_whitepink);
  323 + defaultTv.setText(ResUtils.getString(R.string.default_get_content_failed));
  324 + }
  325 + defaultRootLayout.setVisibility(VISIBLE);
  326 + }
  327 +
  328 + /**
  329 + * 隐藏缺省页
  330 + */
  331 + public void hide() {
  332 + defaultRootLayout.setVisibility(GONE);
  333 + }
  334 +
  335 + public int getmType() {
  336 + return mType;
  337 + }
  338 +
  339 + public void setmType(int mType) {
  340 + this.mType = mType;
  341 + }
  342 +
  343 + /**
  344 + * 设置暗模式
  345 + */
  346 + public void setDarkMode() {
  347 + // 黑色
  348 + defaultRootLayout.setBackgroundColor(0xff000000);
  349 + defaultTv.setTextColor(0xffB0B0B0);
  350 + defaultBtn.setTextColor(0xffCCCCCC);
  351 + defaultBtn.setBackground(ResUtils.getDrawable(R.drawable.wdkit_bg_text_networkerror_reload_dark));
  352 + }
  353 +
  354 + /**
  355 + * 设置topView 距离top高度
  356 + */
  357 + public void setTopViewHeight(int height) {
  358 + ViewGroup.LayoutParams params = topView.getLayoutParams();
  359 + params.height = height;
  360 + topView.setLayoutParams(params);
  361 + }
  362 +
  363 + /**
  364 + * 在ColumnFragment上设置背景色
  365 + */
  366 + public void setColumnFragmentBackgroundColor() {
  367 +
  368 + defaultRootLayout.setBackgroundResource(R.drawable.wdkit_shape_square_page_top_radius);
  369 + LayoutParams defaultViewLp = (LayoutParams) defaultRootLayout.getLayoutParams();
  370 + defaultViewLp.rightMargin = (int) mContext.getResources().getDimension(R.dimen.wdkit_dp6);
  371 + defaultViewLp.leftMargin = (int) mContext.getResources().getDimension(R.dimen.wdkit_dp6);
  372 + defaultRootLayout.setLayoutParams(defaultViewLp);
  373 +
  374 + }
  375 +
  376 + /**
  377 + * 设置重试按钮点击监听
  378 + *
  379 + * @param retryClickListener
  380 + */
  381 + public void setRetryBtnClickListener(RetryClickListener retryClickListener) {
  382 + this.retryClickListener = retryClickListener;
  383 + }
  384 +
  385 + public interface RetryClickListener {
  386 + void onRetryClick();
  387 + }
  388 +
  389 + /**
  390 + * 设置顶部、底部比例
  391 + */
  392 + public void setTopBtmWeight(int topWeight, int btmWeight) {
  393 + if (topView != null) {
  394 + // 设置顶部比例
  395 + LayoutParams topParams = (LayoutParams) topView.getLayoutParams();
  396 + topParams.weight = topWeight;
  397 + topView.setLayoutParams(topParams);
  398 + }
  399 + if (btmView != null) {
  400 + // 设置底部比例
  401 + LayoutParams btmParams = (LayoutParams) btmView.getLayoutParams();
  402 + btmParams.weight = btmWeight;
  403 + btmView.setLayoutParams(btmParams);
  404 + }
  405 + }
  406 +
  407 + public void showOnlySpace(int type) {
  408 + if (btmView != null) {
  409 + btmView.setVisibility(GONE);
  410 + }
  411 + show(type);
  412 + }
  413 +
  414 + /**
  415 + * 设置顶部、底部高度
  416 + */
  417 + public void setTopBtmHeight(int topWeight, int btmWeight) {
  418 + if (topView != null) {
  419 + // 设置顶部比例
  420 + LayoutParams topParams = (LayoutParams) topView.getLayoutParams();
  421 + topParams.height = topWeight;
  422 + topParams.weight = 0;
  423 + topView.setLayoutParams(topParams);
  424 + }
  425 + if (btmView != null) {
  426 + // 设置底部比例
  427 + LayoutParams btmParams = (LayoutParams) btmView.getLayoutParams();
  428 + btmParams.height = btmWeight;
  429 + btmParams.weight = 0;
  430 + btmView.setLayoutParams(btmParams);
  431 + }
  432 + }
  433 +
  434 + public void setTipTextStyle(int color, float textsize) {
  435 + if (defaultTv != null) {
  436 + defaultTv.setTextColor(color);
  437 + defaultTv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, textsize);
  438 + }
  439 + }
  440 +
  441 + public void setTopMenuViewShow() {
  442 + if (topMenuView != null) {
  443 + topMenuView.setVisibility(VISIBLE);
  444 + }
  445 + }
  446 +
  447 + public void setTopMenuViewClickListen(BaseClickListener clickListen) {
  448 + if (topMenuView != null) {
  449 + topMenuView.setOnClickListener(clickListen);
  450 + }
  451 + }
  452 +}
  1 +
  2 +package com.wd.foundation.wdkit.widget.progress;
  3 +
  4 +import android.content.Context;
  5 +import android.os.Handler;
  6 +import android.os.Looper;
  7 +import android.util.AttributeSet;
  8 +import android.view.LayoutInflater;
  9 +import android.view.View;
  10 +import android.widget.LinearLayout;
  11 +
  12 +import androidx.annotation.Nullable;
  13 +
  14 +import com.airbnb.lottie.LottieAnimationView;
  15 +import com.wd.foundation.wdkit.R;
  16 +import com.wd.foundation.wdkit.animator.AnimUtil;
  17 +
  18 +/**
  19 + * 第一次 视频详情 请求接口 loading 效果
  20 + *
  21 + * @author xujiawei
  22 + */
  23 +public class PageLoadingView extends LinearLayout {
  24 + /**
  25 + * 延迟0.5秒展示loading,如果0.5秒内结束了,则不展示loading
  26 + */
  27 + private boolean needShow;
  28 +
  29 + private Handler handler;
  30 +
  31 + private LottieAnimationView animationView;
  32 +
  33 + private Context context;
  34 +
  35 + public PageLoadingView(Context context) {
  36 + this(context, null);
  37 + }
  38 +
  39 + public PageLoadingView(Context context, @Nullable AttributeSet attrs) {
  40 + this(context, attrs, 0);
  41 + }
  42 +
  43 + public PageLoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  44 + super(context, attrs, defStyleAttr);
  45 + this.context = context;
  46 + init();
  47 + }
  48 +
  49 + private void init() {
  50 + View view = LayoutInflater.from(context).inflate(R.layout.wdkit_small_white_black_loading_view, this, true);
  51 + animationView = view.findViewById(R.id.animation_view);
  52 + handler = new Handler(Looper.getMainLooper());
  53 + }
  54 +
  55 + /**
  56 + * loading
  57 + */
  58 + public void showLoading() {
  59 + // 需要展示loading
  60 + needShow = true;
  61 + // 延时展示loading
  62 + handler.postDelayed(new Runnable() {
  63 + @Override
  64 + public void run() {
  65 + if (needShow) {
  66 + needShow = false;
  67 + AnimUtil.showLocalLottieEffects(animationView, "refreshing_common_loading.json", true);
  68 + }
  69 +
  70 + }
  71 + }, 500);
  72 + }
  73 +
  74 + public void stopLoading() {
  75 + // 已经结束,不需要再展示loading
  76 + needShow = false;
  77 + animationView.pauseAnimation();
  78 + }
  79 +}
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<shape xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <stroke android:width="@dimen/wdkit_dp0_5" android:color="@color/res_color_common_C6" />
  4 + <corners android:radius="@dimen/wdkit_dp3"/>
  5 +</shape>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<shape xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <stroke android:width="@dimen/wdkit_dp0_5" android:color="@color/res_color_common_C2" />
  4 + <corners android:radius="@dimen/wdkit_dp3"/>
  5 +</shape>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<shape xmlns:android="http://schemas.android.com/apk/res/android"
  3 + android:shape="rectangle" >
  4 + <solid android:color="@color/res_color_common_C7" />
  5 + <stroke android:width="@dimen/wdkit_dp0_5" android:color="@color/res_color_common_C6"/>
  6 + <corners android:radius="@dimen/wdkit_dp4"/>
  7 +</shape>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<shape xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <corners
  4 + android:topLeftRadius="@dimen/rmrb_dp6"
  5 + android:topRightRadius="@dimen/rmrb_dp6" />
  6 +
  7 + <solid android:color="@color/res_color_common_C8" />
  8 +</shape>
  1 +<!-- 纯内容布局,中间内容模块 -->
  2 +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:tools="http://schemas.android.com/tools"
  4 + android:id="@+id/default_content_layout"
  5 + android:layout_width="wrap_content"
  6 + android:layout_height="wrap_content"
  7 + android:layout_gravity="center_horizontal"
  8 + android:gravity="center_horizontal"
  9 + android:orientation="vertical"
  10 + >
  11 +
  12 + <ImageView
  13 + android:id="@+id/default_img"
  14 + android:layout_width="@dimen/wdkit_dp160"
  15 + android:layout_height="@dimen/wdkit_dp112"
  16 + android:scaleType="fitXY"
  17 + tools:src="@mipmap/wdkit_icon_no_relevant_content_found"
  18 + />
  19 +
  20 + <TextView
  21 + android:id="@+id/default_tv"
  22 + android:layout_width="wrap_content"
  23 + android:layout_height="wrap_content"
  24 + android:layout_marginTop="@dimen/wdkit_dp6"
  25 + android:gravity="center"
  26 + android:textColor="@color/res_color_common_C3"
  27 + android:textSize="@dimen/wdkit_dp14"
  28 + tools:text="没有找到相关内容"
  29 + />
  30 +
  31 + <TextView
  32 + android:id="@+id/default_btn"
  33 + android:layout_width="wrap_content"
  34 + android:layout_height="wrap_content"
  35 + android:layout_marginTop="@dimen/wdkit_dp16"
  36 + android:background="@drawable/wdkit_bg_text_networkerror_reload"
  37 + android:gravity="center"
  38 + android:paddingLeft="@dimen/wdkit_dp16"
  39 + android:paddingTop="@dimen/wdkit_dp4"
  40 + android:paddingRight="@dimen/wdkit_dp16"
  41 + android:paddingBottom="@dimen/wdkit_dp4"
  42 + android:text="@string/clickretry"
  43 + android:textColor="@color/res_color_common_C2"
  44 + android:textSize="@dimen/wdkit_dp12"
  45 + android:textStyle="bold"
  46 + />
  47 +
  48 + </LinearLayout>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:tools="http://schemas.android.com/tools"
  4 + xmlns:app="http://schemas.android.com/apk/res-auto"
  5 + android:id="@+id/default_root_layout"
  6 + android:layout_width="match_parent"
  7 + android:layout_height="match_parent"
  8 + android:orientation="vertical"
  9 + android:visibility="gone"
  10 + tools:visibility="visible">
  11 +
  12 + <androidx.constraintlayout.widget.ConstraintLayout
  13 + android:id="@+id/layout_follow_more_creator"
  14 + android:layout_width="match_parent"
  15 + android:layout_height="@dimen/wdkit_dp36"
  16 + android:layout_marginHorizontal="@dimen/wdkit_dp16"
  17 + android:layout_marginTop="@dimen/wdkit_dp10"
  18 + android:layout_marginBottom="@dimen/wdkit_dp2"
  19 + android:background="@drawable/wdkit_shape_follow_header_bg"
  20 + android:visibility="gone">
  21 +
  22 + <TextView
  23 + android:id="@+id/tv_more"
  24 + android:layout_width="wrap_content"
  25 + android:layout_height="wrap_content"
  26 + android:text="@string/res_attention_more"
  27 + android:textColor="@color/res_color_common_C1"
  28 + android:textSize="@dimen/wdkit_dp14"
  29 + app:layout_constraintBottom_toBottomOf="parent"
  30 + app:layout_constraintEnd_toStartOf="@id/iv_more"
  31 + app:layout_constraintHorizontal_chainStyle="packed"
  32 + app:layout_constraintStart_toStartOf="parent"
  33 + app:layout_constraintTop_toTopOf="parent" />
  34 +
  35 + <ImageView
  36 + android:id="@+id/iv_more"
  37 + android:layout_width="@dimen/wdkit_dp15"
  38 + android:layout_height="@dimen/wdkit_dp15"
  39 + android:scaleType="centerCrop"
  40 + android:src="@drawable/wdkit_icon_setting_arrow"
  41 + app:layout_constraintBottom_toBottomOf="parent"
  42 + app:layout_constraintEnd_toEndOf="parent"
  43 + app:layout_constraintStart_toEndOf="@id/tv_more"
  44 + app:layout_constraintTop_toTopOf="parent" />
  45 +
  46 + </androidx.constraintlayout.widget.ConstraintLayout>
  47 +
  48 + <View
  49 + android:id="@+id/top_View"
  50 + android:layout_width="match_parent"
  51 + android:layout_height="0px"
  52 + android:layout_weight="180" />
  53 +
  54 +
  55 + <include
  56 + layout="@layout/wdkit_default_item_layout"
  57 + android:layout_width="wrap_content"
  58 + android:layout_height="wrap_content"
  59 + android:layout_gravity="center_horizontal" />
  60 +
  61 + <View
  62 + android:id="@+id/btmspaceview"
  63 + android:layout_width="match_parent"
  64 + android:layout_height="0px"
  65 + android:layout_weight="366" />
  66 +
  67 +</LinearLayout>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:app="http://schemas.android.com/apk/res-auto"
  4 + xmlns:tools="http://schemas.android.com/tools"
  5 + android:id="@+id/default_root_layout"
  6 + android:layout_width="match_parent"
  7 + android:layout_height="match_parent"
  8 + android:orientation="vertical"
  9 + android:visibility="gone"
  10 + tools:visibility="visible">
  11 +
  12 + <androidx.constraintlayout.widget.ConstraintLayout
  13 + android:id="@+id/layout_follow_more_creator"
  14 + android:layout_width="match_parent"
  15 + android:layout_height="@dimen/wdkit_dp36"
  16 + android:layout_marginHorizontal="@dimen/wdkit_dp16"
  17 + android:layout_marginTop="@dimen/wdkit_dp10"
  18 + android:layout_marginBottom="@dimen/wdkit_dp2"
  19 + android:background="@drawable/wdkit_shape_follow_header_bg"
  20 + android:visibility="gone">
  21 +
  22 + <TextView
  23 + android:id="@+id/tv_more"
  24 + android:layout_width="wrap_content"
  25 + android:layout_height="wrap_content"
  26 + android:text="@string/res_attention_more"
  27 + android:textColor="@color/res_color_common_C1"
  28 + android:textSize="@dimen/wdkit_dp14"
  29 + app:layout_constraintBottom_toBottomOf="parent"
  30 + app:layout_constraintEnd_toStartOf="@id/iv_more"
  31 + app:layout_constraintHorizontal_chainStyle="packed"
  32 + app:layout_constraintStart_toStartOf="parent"
  33 + app:layout_constraintTop_toTopOf="parent" />
  34 +
  35 + <ImageView
  36 + android:id="@+id/iv_more"
  37 + android:layout_width="@dimen/wdkit_dp15"
  38 + android:layout_height="@dimen/wdkit_dp15"
  39 + android:scaleType="centerCrop"
  40 + android:src="@drawable/wdkit_icon_setting_arrow"
  41 + app:layout_constraintBottom_toBottomOf="parent"
  42 + app:layout_constraintEnd_toEndOf="parent"
  43 + app:layout_constraintStart_toEndOf="@id/tv_more"
  44 + app:layout_constraintTop_toTopOf="parent" />
  45 +
  46 + </androidx.constraintlayout.widget.ConstraintLayout>
  47 +
  48 + <View
  49 + android:id="@+id/top_View"
  50 + android:layout_width="match_parent"
  51 + android:layout_height="match_parent"
  52 + android:layout_weight="7" />
  53 +
  54 + <androidx.core.widget.NestedScrollView
  55 + android:layout_width="match_parent"
  56 + android:layout_height="match_parent"
  57 + android:layout_weight="1">
  58 +
  59 + <include
  60 + layout="@layout/wdkit_default_item_layout"
  61 + android:layout_width="wrap_content"
  62 + android:layout_height="wrap_content"
  63 + android:layout_gravity="center_horizontal" />
  64 + </androidx.core.widget.NestedScrollView>
  65 +
  66 +
  67 +</LinearLayout>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + android:id="@+id/ll_noData"
  4 + android:layout_width="match_parent"
  5 + android:layout_height="match_parent"
  6 + android:gravity="center"
  7 + android:orientation="vertical"
  8 + >
  9 +
  10 + <com.wd.foundation.wdkit.widget.DefaultView
  11 + android:id="@+id/default_view"
  12 + android:layout_width="match_parent"
  13 + android:layout_height="match_parent"/>
  14 +
  15 +</LinearLayout>
  16 +
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:app="http://schemas.android.com/apk/res-auto"
  4 + android:layout_width="match_parent"
  5 + android:layout_height="match_parent">
  6 +
  7 + <RelativeLayout
  8 + android:id="@+id/loading_btn"
  9 + android:layout_width="match_parent"
  10 + android:layout_height="48dp"
  11 + android:layout_marginTop="324dp"
  12 + android:layout_marginHorizontal="25dp">
  13 +
  14 + <ImageView
  15 + android:layout_width="match_parent"
  16 + android:layout_height="match_parent"
  17 + android:enabled="false"
  18 + android:scaleType="fitXY"
  19 + android:src="@drawable/login_tv_bg_s" />
  20 +
  21 + <com.airbnb.lottie.LottieAnimationView
  22 + android:id="@+id/one_key_loading"
  23 + android:layout_width="18dp"
  24 + android:layout_height="18dp"
  25 + android:layout_centerInParent="true"
  26 + app:lottie_autoPlay="true"
  27 + app:lottie_loop="true" />
  28 + </RelativeLayout>
  29 +</RelativeLayout>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:app="http://schemas.android.com/apk/res-auto"
  4 + android:layout_marginTop="@dimen/rmrb_dp44"
  5 + android:layout_marginBottom="@dimen/rmrb_dp44"
  6 + android:layout_width="match_parent"
  7 + android:layout_height="match_parent"
  8 + android:gravity="center"
  9 + android:orientation="vertical">
  10 +
  11 + <com.wd.foundation.wdkit.widget.progress.PageLoadingView
  12 + android:id="@+id/channelSmallLoading"
  13 + android:layout_width="wrap_content"
  14 + android:layout_height="wrap_content"
  15 + android:layout_gravity="center" />
  16 +</LinearLayout>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<!-- 全局区域动画(全域动画)加载动画 refreshing_common_loading.pag -->
  3 +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4 + xmlns:app="http://schemas.android.com/apk/res-auto"
  5 + android:layout_width="match_parent"
  6 + android:layout_height="wrap_content"
  7 + android:gravity="center"
  8 + android:orientation="vertical">
  9 +
  10 +
  11 + <LinearLayout
  12 + android:layout_width="@dimen/rmrb_dp100"
  13 + android:layout_height="@dimen/rmrb_dp100"
  14 + android:layout_gravity="center"
  15 + android:gravity="center"
  16 + android:orientation="vertical">
  17 +
  18 + <com.airbnb.lottie.LottieAnimationView
  19 + android:id="@+id/animation_view"
  20 + android:layout_width="@dimen/rmrb_dp72"
  21 + android:layout_height="@dimen/rmrb_dp72"
  22 + app:lottie_autoPlay="false"
  23 + app:lottie_loop="true"
  24 + android:layout_gravity="center_horizontal"
  25 + />
  26 +
  27 + <TextView
  28 + android:id="@+id/text"
  29 + android:layout_width="wrap_content"
  30 + android:layout_height="wrap_content"
  31 + android:layout_gravity="center_horizontal"
  32 + android:layout_marginTop="@dimen/rmrb_dp10"
  33 + android:text="@string/loading_text"
  34 + android:textColor="#E6FFFFFF"
  35 + android:textSize="@dimen/rmrb_dp14"
  36 + android:visibility="gone" />
  37 + </LinearLayout>
  38 +</FrameLayout>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <dimen name="btmlogo_dimen">107dp</dimen>
  4 + <dimen name="btmjump_dimen">128dp</dimen>
  5 + <dimen name="btmjump_dimensmall">23dp</dimen>
  6 +</resources>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <dimen name="btmlogo_dimen">121dp</dimen>
  4 + <dimen name="btmjump_dimen">142dp</dimen>
  5 + <dimen name="btmjump_dimensmall">33dp</dimen>
  6 +</resources>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <dimen name="btmlogo_dimen">130dp</dimen>
  4 + <dimen name="btmjump_dimen">156dp</dimen>
  5 + <dimen name="btmjump_dimensmall">52dp</dimen>
  6 +</resources>