pathfinders) {
181 | if (pathfinders == null || pathfinders.isEmpty()) {
182 | throw new IllegalArgumentException("Oh, No, It`s not have Pathfinder...");
183 | }
184 | Pathfinder pathfinder = pathfinders.get(0);
185 | boolean isConsistentPathfinder = pathfinder instanceof ConsistentPathfinder;
186 | if (!isConsistentPathfinder) {
187 | int size = pathfinders.size();
188 | for (int level = 0; level < size; level++) {
189 | pathfinder = pathfinders.get(level);
190 | if (level != pathfinder.depth) {
191 | throw new IllegalArgumentException("Oh, No, Pathfinders is incomplete...");
192 | }
193 | }
194 | }
195 | }
196 |
197 | private static class ConsistentPathfinder extends Pathfinder {
198 | public ConsistentPathfinder(int in_depth, int in_position) {
199 | super.depth = in_depth;
200 | super.position = in_position;
201 | }
202 | }
203 |
204 | public static class Pathfinder {
205 | public int depth;
206 | public int position;
207 |
208 | public Pathfinder() {
209 | }
210 |
211 | public Pathfinder(int in_depth, int in_position) {
212 | this.depth = in_depth;
213 | this.position = in_position;
214 | }
215 | }
216 |
217 | }
218 |
219 |
--------------------------------------------------------------------------------
/app/src/main/java/com/byl/mvvm/utils/LogUtil.kt:
--------------------------------------------------------------------------------
1 | package com.byl.mvvm.utils
2 |
3 | import android.util.Log
4 | import com.byl.mvvm.BuildConfig
5 |
6 | object LogUtil {
7 | private const val TAG = "mvvm_log"
8 | private const val TAG_NET = "mvvm_net"
9 |
10 | fun i(message: String?) {
11 | if (BuildConfig.DEBUG) Log.i(TAG, message)
12 | }
13 |
14 | fun e(message: String?) {
15 | if (BuildConfig.DEBUG) Log.e(TAG, message)
16 | }
17 |
18 | fun showHttpHeaderLog(message: String?) {
19 | if (BuildConfig.DEBUG) Log.d(TAG_NET, message)
20 | }
21 |
22 | fun showHttpApiLog(message: String?) {
23 | if (BuildConfig.DEBUG) Log.w(TAG_NET, message)
24 | }
25 |
26 | fun showHttpLog(message: String?) {
27 | if (BuildConfig.DEBUG) Log.i(TAG_NET, message)
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/byl/mvvm/utils/StatusBarUtil.java:
--------------------------------------------------------------------------------
1 | package com.byl.mvvm.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.graphics.Color;
7 | import android.os.Build;
8 | import android.util.DisplayMetrics;
9 | import android.util.Log;
10 | import android.view.Display;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.view.Window;
14 | import android.view.WindowManager;
15 | import android.widget.LinearLayout;
16 |
17 | import androidx.annotation.ColorInt;
18 | import androidx.annotation.FloatRange;
19 | import androidx.annotation.RequiresApi;
20 | import androidx.coordinatorlayout.widget.CoordinatorLayout;
21 | import androidx.drawerlayout.widget.DrawerLayout;
22 |
23 |
24 | import com.byl.mvvm.R;
25 |
26 | import java.lang.reflect.Field;
27 | import java.lang.reflect.Method;
28 | import java.util.regex.Pattern;
29 |
30 |
31 | /**
32 | * Created by Jaeger on 16/2/14.
33 | *
34 | * Email: chjie.jaeger@gmail.com
35 | * GitHub: https://github.com/laobie
36 | */
37 | public class StatusBarUtil {
38 |
39 | public static final int DEFAULT_STATUS_BAR_ALPHA = 0;
40 | private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.statusbarutil_fake_status_bar_view;
41 | private static final int FAKE_TRANSLUCENT_VIEW_ID = R.id.statusbarutil_translucent_view;
42 | private static final int TAG_KEY_HAVE_SET_OFFSET = -123;
43 |
44 | /**
45 | * 设置状态栏颜色
46 | *
47 | * @param activity 需要设置的 activity
48 | * @param color 状态栏颜色值
49 | */
50 | public static void setColor(Activity activity, @ColorInt int color) {
51 | if (activity == null) return;
52 | setColor(activity, color, DEFAULT_STATUS_BAR_ALPHA);
53 | }
54 |
55 | /**
56 | * 设置状态栏颜色
57 | *
58 | * @param activity 需要设置的activity
59 | * @param color 状态栏颜色值
60 | * @param statusBarAlpha 状态栏透明度
61 | */
62 |
63 | public static void setColor(Activity activity, @ColorInt int color, int statusBarAlpha) {
64 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
65 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
66 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
67 | activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));
68 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
69 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
70 | ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
71 | View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
72 | if (fakeStatusBarView != null) {
73 | if (fakeStatusBarView.getVisibility() == View.GONE) {
74 | fakeStatusBarView.setVisibility(View.VISIBLE);
75 | }
76 | fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
77 | } else {
78 | decorView.addView(createStatusBarView(activity, color, statusBarAlpha));
79 | }
80 | setRootView(activity);
81 | }
82 | }
83 |
84 | /**
85 | * 为滑动返回界面设置状态栏颜色
86 | *
87 | * @param activity 需要设置的activity
88 | * @param color 状态栏颜色值
89 | */
90 | public static void setColorForSwipeBack(Activity activity, int color) {
91 | setColorForSwipeBack(activity, color, DEFAULT_STATUS_BAR_ALPHA);
92 | }
93 |
94 | /**
95 | * 为滑动返回界面设置状态栏颜色
96 | *
97 | * @param activity 需要设置的activity
98 | * @param color 状态栏颜色值
99 | * @param statusBarAlpha 状态栏透明度
100 | */
101 | public static void setColorForSwipeBack(Activity activity, @ColorInt int color, int statusBarAlpha) {
102 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
103 |
104 | ViewGroup contentView = ((ViewGroup) activity.findViewById(android.R.id.content));
105 | View rootView = contentView.getChildAt(0);
106 | int statusBarHeight = getStatusBarHeight(activity);
107 | if (rootView != null && rootView instanceof CoordinatorLayout) {
108 | final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) rootView;
109 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
110 | coordinatorLayout.setFitsSystemWindows(false);
111 | contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
112 | boolean isNeedRequestLayout = contentView.getPaddingTop() < statusBarHeight;
113 | if (isNeedRequestLayout) {
114 | contentView.setPadding(0, statusBarHeight, 0, 0);
115 | coordinatorLayout.post(new Runnable() {
116 | @Override
117 | public void run() {
118 | coordinatorLayout.requestLayout();
119 | }
120 | });
121 | }
122 | } else {
123 | coordinatorLayout.setStatusBarBackgroundColor(calculateStatusColor(color, statusBarAlpha));
124 | }
125 | } else {
126 | contentView.setPadding(0, statusBarHeight, 0, 0);
127 | contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
128 | }
129 | setTransparentForWindow(activity);
130 | }
131 | }
132 |
133 | /**
134 | * 设置状态栏纯色 不加半透明效果
135 | *
136 | * @param activity 需要设置的 activity
137 | * @param color 状态栏颜色值
138 | */
139 | public static void setColorNoTranslucent(Activity activity, @ColorInt int color) {
140 | setColor(activity, color, 0);
141 | }
142 |
143 | /**
144 | * 设置状态栏颜色(5.0以下无半透明效果,不建议使用)
145 | *
146 | * @param activity 需要设置的 activity
147 | * @param color 状态栏颜色值
148 | */
149 | @Deprecated
150 | public static void setColorDiff(Activity activity, @ColorInt int color) {
151 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
152 | return;
153 | }
154 | transparentStatusBar(activity);
155 | ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
156 | // 移除半透明矩形,以免叠加
157 | View fakeStatusBarView = contentView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
158 | if (fakeStatusBarView != null) {
159 | if (fakeStatusBarView.getVisibility() == View.GONE) {
160 | fakeStatusBarView.setVisibility(View.VISIBLE);
161 | }
162 | fakeStatusBarView.setBackgroundColor(color);
163 | } else {
164 | contentView.addView(createStatusBarView(activity, color));
165 | }
166 | setRootView(activity);
167 | }
168 |
169 | /**
170 | * 使状态栏半透明
171 | *
172 | * 适用于图片作为背景的界面,此时需要图片填充到状态栏
173 | *
174 | * @param activity 需要设置的activity
175 | */
176 | public static void setTranslucent(Activity activity) {
177 | setTranslucent(activity, DEFAULT_STATUS_BAR_ALPHA);
178 | }
179 |
180 | /**
181 | * 使状态栏半透明
182 | *
183 | * 适用于图片作为背景的界面,此时需要图片填充到状态栏
184 | *
185 | * @param activity 需要设置的activity
186 | * @param statusBarAlpha 状态栏透明度
187 | */
188 | public static void setTranslucent(Activity activity, int statusBarAlpha) {
189 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
190 | return;
191 | }
192 | setTransparent(activity);
193 | addTranslucentView(activity, statusBarAlpha);
194 | }
195 |
196 | /**
197 | * 针对根布局是 CoordinatorLayout, 使状态栏半透明
198 | *
199 | * 适用于图片作为背景的界面,此时需要图片填充到状态栏
200 | *
201 | * @param activity 需要设置的activity
202 | * @param statusBarAlpha 状态栏透明度
203 | */
204 | public static void setTranslucentForCoordinatorLayout(Activity activity, int statusBarAlpha) {
205 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
206 | return;
207 | }
208 | transparentStatusBar(activity);
209 | addTranslucentView(activity, statusBarAlpha);
210 | }
211 |
212 | /**
213 | * 设置状态栏全透明
214 | *
215 | * @param activity 需要设置的activity
216 | */
217 | public static void setTransparent(Activity activity) {
218 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
219 | return;
220 | }
221 | transparentStatusBar(activity);
222 | setRootView(activity);
223 | }
224 |
225 | /**
226 | * 使状态栏透明(5.0以上半透明效果,不建议使用)
227 | *
228 | * 适用于图片作为背景的界面,此时需要图片填充到状态栏
229 | *
230 | * @param activity 需要设置的activity
231 | */
232 | @Deprecated
233 | public static void setTranslucentDiff(Activity activity) {
234 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
235 | // 设置状态栏透明
236 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
237 | setRootView(activity);
238 | }
239 | }
240 |
241 | /**
242 | * 为DrawerLayout 布局设置状态栏变色
243 | *
244 | * @param activity 需要设置的activity
245 | * @param drawerLayout DrawerLayout
246 | * @param color 状态栏颜色值
247 | */
248 | public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
249 | setColorForDrawerLayout(activity, drawerLayout, color, DEFAULT_STATUS_BAR_ALPHA);
250 | }
251 |
252 | /**
253 | * 为DrawerLayout 布局设置状态栏颜色,纯色
254 | *
255 | * @param activity 需要设置的activity
256 | * @param drawerLayout DrawerLayout
257 | * @param color 状态栏颜色值
258 | */
259 | public static void setColorNoTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
260 | setColorForDrawerLayout(activity, drawerLayout, color, 0);
261 | }
262 |
263 | /**
264 | * 为DrawerLayout 布局设置状态栏变色
265 | *
266 | * @param activity 需要设置的activity
267 | * @param drawerLayout DrawerLayout
268 | * @param color 状态栏颜色值
269 | * @param statusBarAlpha 状态栏透明度
270 | */
271 | public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color,
272 | int statusBarAlpha) {
273 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
274 | return;
275 | }
276 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
277 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
278 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
279 | activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
280 | } else {
281 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
282 | }
283 | // 生成一个状态栏大小的矩形
284 | // 添加 statusBarView 到布局中
285 | ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
286 | View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
287 | if (fakeStatusBarView != null) {
288 | if (fakeStatusBarView.getVisibility() == View.GONE) {
289 | fakeStatusBarView.setVisibility(View.VISIBLE);
290 | }
291 | fakeStatusBarView.setBackgroundColor(color);
292 | } else {
293 | contentLayout.addView(createStatusBarView(activity, color), 0);
294 | }
295 | // 内容布局不是 LinearLayout 时,设置padding top
296 | if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
297 | contentLayout.getChildAt(1)
298 | .setPadding(contentLayout.getPaddingLeft(), getStatusBarHeight(activity) + contentLayout.getPaddingTop(),
299 | contentLayout.getPaddingRight(), contentLayout.getPaddingBottom());
300 | }
301 | // 设置属性
302 | setDrawerLayoutProperty(drawerLayout, contentLayout);
303 | addTranslucentView(activity, statusBarAlpha);
304 | }
305 |
306 | /**
307 | * 设置 DrawerLayout 属性
308 | *
309 | * @param drawerLayout DrawerLayout
310 | * @param drawerLayoutContentLayout DrawerLayout 的内容布局
311 | */
312 | private static void setDrawerLayoutProperty(DrawerLayout drawerLayout, ViewGroup drawerLayoutContentLayout) {
313 | ViewGroup drawer = (ViewGroup) drawerLayout.getChildAt(1);
314 | drawerLayout.setFitsSystemWindows(false);
315 | drawerLayoutContentLayout.setFitsSystemWindows(false);
316 | drawerLayoutContentLayout.setClipToPadding(true);
317 | drawer.setFitsSystemWindows(false);
318 | }
319 |
320 | /**
321 | * 为DrawerLayout 布局设置状态栏变色(5.0以下无半透明效果,不建议使用)
322 | *
323 | * @param activity 需要设置的activity
324 | * @param drawerLayout DrawerLayout
325 | * @param color 状态栏颜色值
326 | */
327 | @Deprecated
328 | public static void setColorForDrawerLayoutDiff(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
329 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
330 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
331 | // 生成一个状态栏大小的矩形
332 | ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
333 | View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
334 | if (fakeStatusBarView != null) {
335 | if (fakeStatusBarView.getVisibility() == View.GONE) {
336 | fakeStatusBarView.setVisibility(View.VISIBLE);
337 | }
338 | fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, DEFAULT_STATUS_BAR_ALPHA));
339 | } else {
340 | // 添加 statusBarView 到布局中
341 | contentLayout.addView(createStatusBarView(activity, color), 0);
342 | }
343 | // 内容布局不是 LinearLayout 时,设置padding top
344 | if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
345 | contentLayout.getChildAt(1).setPadding(0, getStatusBarHeight(activity), 0, 0);
346 | }
347 | // 设置属性
348 | setDrawerLayoutProperty(drawerLayout, contentLayout);
349 | }
350 | }
351 |
352 | /**
353 | * 为 DrawerLayout 布局设置状态栏透明
354 | *
355 | * @param activity 需要设置的activity
356 | * @param drawerLayout DrawerLayout
357 | */
358 | public static void setTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout) {
359 | setTranslucentForDrawerLayout(activity, drawerLayout, DEFAULT_STATUS_BAR_ALPHA);
360 | }
361 |
362 | /**
363 | * 为 DrawerLayout 布局设置状态栏透明
364 | *
365 | * @param activity 需要设置的activity
366 | * @param drawerLayout DrawerLayout
367 | */
368 | public static void setTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout, int statusBarAlpha) {
369 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
370 | return;
371 | }
372 | setTransparentForDrawerLayout(activity, drawerLayout);
373 | addTranslucentView(activity, statusBarAlpha);
374 | }
375 |
376 | /**
377 | * 为 DrawerLayout 布局设置状态栏透明
378 | *
379 | * @param activity 需要设置的activity
380 | * @param drawerLayout DrawerLayout
381 | */
382 | public static void setTransparentForDrawerLayout(Activity activity, DrawerLayout drawerLayout) {
383 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
384 | return;
385 | }
386 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
387 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
388 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
389 | activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
390 | } else {
391 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
392 | }
393 |
394 | ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
395 | // 内容布局不是 LinearLayout 时,设置padding top
396 | if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
397 | contentLayout.getChildAt(1).setPadding(0, getStatusBarHeight(activity), 0, 0);
398 | }
399 |
400 | // 设置属性
401 | setDrawerLayoutProperty(drawerLayout, contentLayout);
402 | }
403 |
404 | /**
405 | * 为 DrawerLayout 布局设置状态栏透明(5.0以上半透明效果,不建议使用)
406 | *
407 | * @param activity 需要设置的activity
408 | * @param drawerLayout DrawerLayout
409 | */
410 | @Deprecated
411 | public static void setTranslucentForDrawerLayoutDiff(Activity activity, DrawerLayout drawerLayout) {
412 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
413 | // 设置状态栏透明
414 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
415 | // 设置内容布局属性
416 | ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
417 | contentLayout.setFitsSystemWindows(true);
418 | contentLayout.setClipToPadding(true);
419 | // 设置抽屉布局属性
420 | ViewGroup vg = (ViewGroup) drawerLayout.getChildAt(1);
421 | vg.setFitsSystemWindows(false);
422 | // 设置 DrawerLayout 属性
423 | drawerLayout.setFitsSystemWindows(false);
424 | }
425 | }
426 |
427 | /**
428 | * 为头部是 ImageView 的界面设置状态栏全透明
429 | *
430 | * @param activity 需要设置的activity
431 | * @param needOffsetView 需要向下偏移的 View
432 | */
433 | public static void setTransparentForImageView(Activity activity, View needOffsetView) {
434 | setTranslucentForImageView(activity, 0, needOffsetView);
435 | }
436 |
437 | /**
438 | * 为头部是 ImageView 的界面设置状态栏透明(使用默认透明度)
439 | *
440 | * @param activity 需要设置的activity
441 | * @param needOffsetView 需要向下偏移的 View
442 | */
443 | public static void setTranslucentForImageView(Activity activity, View needOffsetView) {
444 | setTranslucentForImageView(activity, DEFAULT_STATUS_BAR_ALPHA, needOffsetView);
445 | }
446 |
447 | /**
448 | * 为头部是 ImageView 的界面设置状态栏透明
449 | *
450 | * @param activity 需要设置的activity
451 | * @param statusBarAlpha 状态栏透明度
452 | * @param needOffsetView 需要向下偏移的 View
453 | */
454 | public static void setTranslucentForImageView(Activity activity, int statusBarAlpha, View needOffsetView) {
455 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
456 | return;
457 | }
458 | setTransparentForWindow(activity);
459 | addTranslucentView(activity, statusBarAlpha);
460 | if (needOffsetView != null) {
461 | Object haveSetOffset = needOffsetView.getTag(TAG_KEY_HAVE_SET_OFFSET);
462 | if (haveSetOffset != null && (Boolean) haveSetOffset) {
463 | return;
464 | }
465 | ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) needOffsetView.getLayoutParams();
466 | layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin + getStatusBarHeight(activity),
467 | layoutParams.rightMargin, layoutParams.bottomMargin);
468 | needOffsetView.setTag(TAG_KEY_HAVE_SET_OFFSET, true);
469 | }
470 | }
471 |
472 | /**
473 | * 为 fragment 头部是 ImageView 的设置状态栏透明
474 | *
475 | * @param activity fragment 对应的 activity
476 | * @param needOffsetView 需要向下偏移的 View
477 | */
478 | public static void setTranslucentForImageViewInFragment(Activity activity, View needOffsetView) {
479 | setTranslucentForImageViewInFragment(activity, DEFAULT_STATUS_BAR_ALPHA, needOffsetView);
480 | }
481 |
482 | /**
483 | * 为 fragment 头部是 ImageView 的设置状态栏透明
484 | *
485 | * @param activity fragment 对应的 activity
486 | * @param needOffsetView 需要向下偏移的 View
487 | */
488 | public static void setTransparentForImageViewInFragment(Activity activity, View needOffsetView) {
489 | setTranslucentForImageViewInFragment(activity, 0, needOffsetView);
490 | }
491 |
492 | /**
493 | * 为 fragment 头部是 ImageView 的设置状态栏透明
494 | *
495 | * @param activity fragment 对应的 activity
496 | * @param statusBarAlpha 状态栏透明度
497 | * @param needOffsetView 需要向下偏移的 View
498 | */
499 | public static void setTranslucentForImageViewInFragment(Activity activity, int statusBarAlpha, View needOffsetView) {
500 | setTranslucentForImageView(activity, statusBarAlpha, needOffsetView);
501 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
502 | clearPreviousSetting(activity);
503 | }
504 | }
505 |
506 | /**
507 | * 隐藏伪状态栏 View
508 | *
509 | * @param activity 调用的 Activity
510 | */
511 | public static void hideFakeStatusBarView(Activity activity) {
512 | ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
513 | View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
514 | if (fakeStatusBarView != null) {
515 | fakeStatusBarView.setVisibility(View.GONE);
516 | }
517 | View fakeTranslucentView = decorView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);
518 | if (fakeTranslucentView != null) {
519 | fakeTranslucentView.setVisibility(View.GONE);
520 | }
521 | }
522 |
523 | ///////////////////////////////////////////////////////////////////////////////////
524 |
525 | @TargetApi(Build.VERSION_CODES.KITKAT)
526 | private static void clearPreviousSetting(Activity activity) {
527 | ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
528 | View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
529 | if (fakeStatusBarView != null) {
530 | decorView.removeView(fakeStatusBarView);
531 | ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
532 | rootView.setPadding(0, 0, 0, 0);
533 | }
534 | }
535 |
536 | /**
537 | * 添加半透明矩形条
538 | *
539 | * @param activity 需要设置的 activity
540 | * @param statusBarAlpha 透明值
541 | */
542 | private static void addTranslucentView(Activity activity, int statusBarAlpha) {
543 | ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
544 | View fakeTranslucentView = contentView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);
545 | if (fakeTranslucentView != null) {
546 | if (fakeTranslucentView.getVisibility() == View.GONE) {
547 | fakeTranslucentView.setVisibility(View.VISIBLE);
548 | }
549 | fakeTranslucentView.setBackgroundColor(Color.argb(statusBarAlpha, 0, 0, 0));
550 | } else {
551 | contentView.addView(createTranslucentStatusBarView(activity, statusBarAlpha));
552 | }
553 | }
554 |
555 | /**
556 | * 生成一个和状态栏大小相同的彩色矩形条
557 | *
558 | * @param activity 需要设置的 activity
559 | * @param color 状态栏颜色值
560 | * @return 状态栏矩形条
561 | */
562 | private static View createStatusBarView(Activity activity, @ColorInt int color) {
563 | return createStatusBarView(activity, color, 0);
564 | }
565 |
566 | /**
567 | * 生成一个和状态栏大小相同的半透明矩形条
568 | *
569 | * @param activity 需要设置的activity
570 | * @param color 状态栏颜色值
571 | * @param alpha 透明值
572 | * @return 状态栏矩形条
573 | */
574 | private static View createStatusBarView(Activity activity, @ColorInt int color, int alpha) {
575 | // 绘制一个和状态栏一样高的矩形
576 | View statusBarView = new View(activity);
577 | LinearLayout.LayoutParams params =
578 | new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
579 | statusBarView.setLayoutParams(params);
580 | statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));
581 | statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
582 | return statusBarView;
583 | }
584 |
585 | /**
586 | * 设置根布局参数
587 | */
588 | private static void setRootView(Activity activity) {
589 | ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);
590 | for (int i = 0, count = parent.getChildCount(); i < count; i++) {
591 | View childView = parent.getChildAt(i);
592 | if (childView instanceof ViewGroup) {
593 | childView.setFitsSystemWindows(true);
594 | ((ViewGroup) childView).setClipToPadding(true);
595 | }
596 | }
597 | }
598 |
599 | /**
600 | * 设置透明
601 | */
602 | private static void setTransparentForWindow(Activity activity) {
603 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
604 | activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
605 | activity.getWindow()
606 | .getDecorView()
607 | .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
608 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
609 | activity.getWindow()
610 | .setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
611 | }
612 | }
613 |
614 | /**
615 | * 使状态栏透明
616 | */
617 | @TargetApi(Build.VERSION_CODES.KITKAT)
618 | private static void transparentStatusBar(Activity activity) {
619 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
620 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
621 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
622 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
623 | activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
624 | } else {
625 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
626 | }
627 | }
628 |
629 | /**
630 | * 创建半透明矩形 View
631 | *
632 | * @param alpha 透明值
633 | * @return 半透明 View
634 | */
635 | private static View createTranslucentStatusBarView(Activity activity, int alpha) {
636 | // 绘制一个和状态栏一样高的矩形
637 | View statusBarView = new View(activity);
638 | LinearLayout.LayoutParams params =
639 | new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
640 | statusBarView.setLayoutParams(params);
641 | statusBarView.setBackgroundColor(Color.argb(alpha, 0, 0, 0));
642 | statusBarView.setId(FAKE_TRANSLUCENT_VIEW_ID);
643 | return statusBarView;
644 | }
645 |
646 | /**
647 | * 获取状态栏高度
648 | *
649 | * @param context context
650 | * @return 状态栏高度
651 | */
652 | public static int getStatusBarHeight(Context context) {
653 | // 获得状态栏高度
654 | int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
655 | return context.getResources().getDimensionPixelSize(resourceId);
656 | }
657 |
658 | /**
659 | * 计算状态栏颜色
660 | *
661 | * @param color color值
662 | * @param alpha alpha值
663 | * @return 最终的状态栏颜色
664 | */
665 | private static int calculateStatusColor(@ColorInt int color, int alpha) {
666 | if (alpha == 0) {
667 | return color;
668 | }
669 | float a = 1 - alpha / 255f;
670 | int red = color >> 16 & 0xff;
671 | int green = color >> 8 & 0xff;
672 | int blue = color & 0xff;
673 | red = (int) (red * a + 0.5);
674 | green = (int) (green * a + 0.5);
675 | blue = (int) (blue * a + 0.5);
676 | return 0xff << 24 | red << 16 | green << 8 | blue;
677 | }
678 |
679 | public static boolean setMiuiStatusBarDarkMode(Activity activity, boolean darkmode) {
680 | Class extends Window> clazz = activity.getWindow().getClass();
681 | try {
682 | int darkModeFlag = 0;
683 | Class> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
684 | Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
685 | darkModeFlag = field.getInt(layoutParams);
686 | Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
687 | extraFlagField.invoke(activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag);
688 | return true;
689 | } catch (Exception e) {
690 | e.printStackTrace();
691 | }
692 | return false;
693 | }
694 |
695 | public static boolean setMeizuStatusBarDarkMode(Activity activity, boolean darkmode) {
696 | boolean result = false;
697 | if (activity != null) {
698 | try {
699 | WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
700 | Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
701 | Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
702 | darkFlag.setAccessible(true);
703 | meizuFlags.setAccessible(true);
704 | int bit = darkFlag.getInt(null);
705 | int value = meizuFlags.getInt(lp);
706 | if (darkmode) {
707 | value |= bit;
708 | } else {
709 | value &= ~bit;
710 | }
711 | meizuFlags.setInt(lp, value);
712 | activity.getWindow().setAttributes(lp);
713 | result = true;
714 | } catch (Exception e) {
715 | }
716 | }
717 | return result;
718 | }
719 |
720 |
721 | public static int DEFAULT_COLOR = 0;
722 | public static float DEFAULT_ALPHA = 0;//Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 0.2f : 0.3f;
723 | public static final int MIN_API = 19;
724 |
725 | //
726 | public static void immersive(Activity activity) {
727 | immersive(activity, DEFAULT_COLOR, DEFAULT_ALPHA);
728 | }
729 |
730 | public static void immersive(Activity activity, int color, @FloatRange(from = 0.0, to = 1.0) float alpha) {
731 | immersive(activity.getWindow(), color, alpha);
732 | }
733 |
734 | public static void immersive(Activity activity, int color) {
735 | immersive(activity.getWindow(), color, 1f);
736 | }
737 |
738 | public static void immersive(Window window) {
739 | immersive(window, DEFAULT_COLOR, DEFAULT_ALPHA);
740 | }
741 |
742 | public static void immersive(Window window, int color) {
743 | immersive(window, color, 1f);
744 | }
745 |
746 | public static void immersive(Window window, int color, @FloatRange(from = 0.0, to = 1.0) float alpha) {
747 | if (Build.VERSION.SDK_INT >= 21) {
748 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
749 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
750 | window.setStatusBarColor(mixtureColor(color, alpha));
751 |
752 | int systemUiVisibility = window.getDecorView().getSystemUiVisibility();
753 | systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
754 | systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
755 | window.getDecorView().setSystemUiVisibility(systemUiVisibility);
756 | } else if (Build.VERSION.SDK_INT >= 19) {
757 | window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
758 | setTranslucentView((ViewGroup) window.getDecorView(), color, alpha);
759 | } else if (Build.VERSION.SDK_INT >= MIN_API && Build.VERSION.SDK_INT > 16) {
760 | int systemUiVisibility = window.getDecorView().getSystemUiVisibility();
761 | systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
762 | systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
763 | window.getDecorView().setSystemUiVisibility(systemUiVisibility);
764 | }
765 | }
766 | //
767 |
768 | //
769 | public static void darkMode(Activity activity, boolean dark) {
770 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
771 | if (Build.MODEL.equals("MI 5") && isMIUI6Later())
772 | darkModeForMIUI6(activity.getWindow(), dark);
773 | else
774 | darkModeForM(activity.getWindow(), dark);
775 | } else if (isFlyme4Later()) {
776 | darkModeForFlyme4(activity.getWindow(), dark);
777 | } else if (isMIUI6Later()) {
778 | darkModeForMIUI6(activity.getWindow(), dark);
779 | }
780 | }
781 |
782 | /**
783 | * 设置状态栏darkMode,字体颜色及icon变黑(目前支持MIUI6以上,Flyme4以上,Android M以上)
784 | */
785 | public static void darkMode(Activity activity) {
786 | darkMode(activity.getWindow(), DEFAULT_COLOR, DEFAULT_ALPHA);
787 | }
788 |
789 | public static void darkMode(Activity activity, int color, @FloatRange(from = 0.0, to = 1.0) float alpha) {
790 | darkMode(activity.getWindow(), color, alpha);
791 | }
792 |
793 | /**
794 | * 设置状态栏darkMode,字体颜色及icon变黑(目前支持MIUI6以上,Flyme4以上,Android M以上)
795 | */
796 | public static void darkMode(Window window, int color, @FloatRange(from = 0.0, to = 1.0) float alpha) {
797 | if (isFlyme4Later()) {
798 | darkModeForFlyme4(window, true);
799 | immersive(window, color, alpha);
800 | } else if (isMIUI6Later()) {
801 | darkModeForMIUI6(window, true);
802 | immersive(window, color, alpha);
803 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
804 | darkModeForM(window, true);
805 | immersive(window, color, alpha);
806 | } else if (Build.VERSION.SDK_INT >= 19) {
807 | window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
808 | setTranslucentView((ViewGroup) window.getDecorView(), color, alpha);
809 | } else {
810 | immersive(window, color, alpha);
811 | }
812 | // if (Build.VERSION.SDK_INT >= 21) {
813 | // window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
814 | // window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
815 | // window.setStatusBarColor(Color.TRANSPARENT);
816 | // } else if (Build.VERSION.SDK_INT >= 19) {
817 | // window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
818 | // }
819 |
820 | // setTranslucentView((ViewGroup) window.getDecorView(), color, alpha);
821 | }
822 |
823 | //------------------------->
824 |
825 | /**
826 | * android 6.0设置字体颜色
827 | */
828 | @RequiresApi(Build.VERSION_CODES.M)
829 | private static void darkModeForM(Window window, boolean dark) {
830 | // window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
831 | // window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
832 | // window.setStatusBarColor(Color.TRANSPARENT);
833 |
834 | int systemUiVisibility = window.getDecorView().getSystemUiVisibility();
835 | if (dark) {
836 | systemUiVisibility |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
837 | } else {
838 | systemUiVisibility &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
839 | }
840 | window.getDecorView().setSystemUiVisibility(systemUiVisibility);
841 | }
842 |
843 | /**
844 | * 设置Flyme4+的darkMode,darkMode时候字体颜色及icon变黑
845 | * http://open-wiki.flyme.cn/index.php?title=Flyme%E7%B3%BB%E7%BB%9FAPI
846 | */
847 | public static boolean darkModeForFlyme4(Window window, boolean dark) {
848 | boolean result = false;
849 | if (window != null) {
850 | try {
851 | WindowManager.LayoutParams e = window.getAttributes();
852 | Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
853 | Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
854 | darkFlag.setAccessible(true);
855 | meizuFlags.setAccessible(true);
856 | int bit = darkFlag.getInt(null);
857 | int value = meizuFlags.getInt(e);
858 | if (dark) {
859 | value |= bit;
860 | } else {
861 | value &= ~bit;
862 | }
863 |
864 | meizuFlags.setInt(e, value);
865 | window.setAttributes(e);
866 | result = true;
867 | } catch (Exception var8) {
868 | Log.e("StatusBar", "darkIcon: failed");
869 | }
870 | }
871 |
872 | return result;
873 | }
874 |
875 | /**
876 | * 设置MIUI6+的状态栏是否为darkMode,darkMode时候字体颜色及icon变黑
877 | * http://dev.xiaomi.com/doc/p=4769/
878 | */
879 | public static boolean darkModeForMIUI6(Window window, boolean darkmode) {
880 | Class extends Window> clazz = window.getClass();
881 | try {
882 | int darkModeFlag = 0;
883 | Class> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
884 | Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
885 | darkModeFlag = field.getInt(layoutParams);
886 | Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
887 | extraFlagField.invoke(window, darkmode ? darkModeFlag : 0, darkModeFlag);
888 | return true;
889 | } catch (Exception e) {
890 | e.printStackTrace();
891 | return false;
892 | }
893 | }
894 |
895 | /**
896 | * 判断是否Flyme4以上
897 | */
898 | public static boolean isFlyme4Later() {
899 | return Build.FINGERPRINT.contains("Flyme_OS_4")
900 | || Build.VERSION.INCREMENTAL.contains("Flyme_OS_4")
901 | || Pattern.compile("Flyme OS [4|5]", Pattern.CASE_INSENSITIVE).matcher(Build.DISPLAY).find();
902 | }
903 |
904 | /**
905 | * 判断是否为MIUI6以上
906 | */
907 | public static boolean isMIUI6Later() {
908 | try {
909 | Class> clz = Class.forName("android.os.SystemProperties");
910 | Method mtd = clz.getMethod("get", String.class);
911 | String val = (String) mtd.invoke(null, "ro.miui.ui.version.name");
912 | val = val.replaceAll("[vV]", "");
913 | int version = Integer.parseInt(val);
914 | return version >= 6;
915 | } catch (Exception e) {
916 | return false;
917 | }
918 | }
919 | //
920 |
921 |
922 | /**
923 | * 增加View的paddingTop,增加的值为状态栏高度
924 | */
925 | public static void setPadding(Context context, View view) {
926 | if (Build.VERSION.SDK_INT >= MIN_API) {
927 | view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + getStatusBarHeight(context),
928 | view.getPaddingRight(), view.getPaddingBottom());
929 | }
930 | }
931 |
932 | public static void setPadding0(Context context, View view) {
933 | if (Build.VERSION.SDK_INT >= MIN_API) {
934 | view.setPadding(0, 0, 0, 0);
935 | }
936 | }
937 |
938 | public static void setPadding1(Context context, View view) {
939 | if (Build.VERSION.SDK_INT >= MIN_API) {
940 | view.setPadding(0, getStatusBarHeight(context), 0, 0);
941 | }
942 | }
943 |
944 | /**
945 | * 增加View的paddingTop,增加的值为状态栏高度 (智能判断,并设置高度)
946 | */
947 | public static void setPaddingSmart(Context context, View view) {
948 | if (Build.VERSION.SDK_INT >= MIN_API) {
949 | ViewGroup.LayoutParams lp = view.getLayoutParams();
950 | if (lp != null && lp.height > 0) {
951 | lp.height += getStatusBarHeight(context);//增高
952 | }
953 | view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + getStatusBarHeight(context),
954 | view.getPaddingRight(), view.getPaddingBottom());
955 | }
956 | }
957 |
958 | /**
959 | * 增加View的高度以及paddingTop,增加的值为状态栏高度.一般是在沉浸式全屏给ToolBar用的
960 | */
961 | public static void setHeightAndPadding(Context context, View view) {
962 | if (Build.VERSION.SDK_INT >= MIN_API) {
963 | ViewGroup.LayoutParams lp = view.getLayoutParams();
964 | lp.height += getStatusBarHeight(context);//增高
965 | view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + getStatusBarHeight(context),
966 | view.getPaddingRight(), view.getPaddingBottom());
967 | }
968 | }
969 |
970 | /**
971 | * 增加View上边距(MarginTop)一般是给高度为 WARP_CONTENT 的小控件用的
972 | */
973 | public static void setMargin(Context context, View view) {
974 | if (Build.VERSION.SDK_INT >= MIN_API) {
975 | ViewGroup.LayoutParams lp = view.getLayoutParams();
976 | if (lp instanceof ViewGroup.MarginLayoutParams) {
977 | ((ViewGroup.MarginLayoutParams) lp).topMargin += getStatusBarHeight(context);//增高
978 | }
979 | view.setLayoutParams(lp);
980 | }
981 | }
982 |
983 | /**
984 | * 创建假的透明栏
985 | */
986 | public static void setTranslucentView(ViewGroup container, int color, @FloatRange(from = 0.0, to = 1.0) float alpha) {
987 | if (Build.VERSION.SDK_INT >= 19) {
988 | int mixtureColor = mixtureColor(color, alpha);
989 | View translucentView = container.findViewById(android.R.id.custom);
990 | if (translucentView == null && mixtureColor != 0) {
991 | translucentView = new View(container.getContext());
992 | translucentView.setId(android.R.id.custom);
993 | ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
994 | ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(container.getContext()));
995 | container.addView(translucentView, lp);
996 | }
997 | if (translucentView != null) {
998 | translucentView.setBackgroundColor(mixtureColor);
999 | }
1000 | }
1001 | }
1002 |
1003 | public static int mixtureColor(int color, @FloatRange(from = 0.0, to = 1.0) float alpha) {
1004 | int a = (color & 0xff000000) == 0 ? 0xff : color >>> 24;
1005 | return (color & 0x00ffffff) | (((int) (a * alpha)) << 24);
1006 | }
1007 |
1008 | /**
1009 | * 判断底部navigator是否存在
1010 | *
1011 | * @return
1012 | * @paramwindowManager
1013 | */
1014 |
1015 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
1016 | public static boolean hasNavBar(WindowManager windowManager) {
1017 |
1018 | Display d = windowManager.getDefaultDisplay();
1019 |
1020 | DisplayMetrics realDisplayMetrics = new DisplayMetrics();
1021 |
1022 | d.getRealMetrics(realDisplayMetrics);
1023 |
1024 | int realHeight = realDisplayMetrics.heightPixels;
1025 |
1026 | int realWidth = realDisplayMetrics.widthPixels;
1027 |
1028 | DisplayMetrics displayMetrics = new DisplayMetrics();
1029 |
1030 | d.getMetrics(displayMetrics);
1031 |
1032 | int displayHeight = displayMetrics.heightPixels;
1033 |
1034 | int displayWidth = displayMetrics.widthPixels;
1035 |
1036 | return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
1037 |
1038 | }
1039 |
1040 |
1041 | /**
1042 | * 设置Android状态栏的字体颜色,状态栏为亮色的时候字体和图标是黑色,状态栏为暗色的时候字体和图标为白色
1043 | *
1044 | * @param dark 状态栏字体和图标是否为深色
1045 | */
1046 | protected static void setStatusBarFontDark(Activity mActivity, boolean dark) {
1047 | // 小米MIUI
1048 | try {
1049 | Window window = mActivity.getWindow();
1050 | Class clazz = mActivity.getWindow().getClass();
1051 | Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
1052 | Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
1053 | int darkModeFlag = field.getInt(layoutParams);
1054 | Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
1055 | if (dark) { //状态栏亮色且黑色字体
1056 | extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
1057 | } else { //清除黑色字体
1058 | extraFlagField.invoke(window, 0, darkModeFlag);
1059 | }
1060 | } catch (Exception e) {
1061 | e.printStackTrace();
1062 | }
1063 |
1064 | // 魅族FlymeUI
1065 | try {
1066 | Window window = mActivity.getWindow();
1067 | WindowManager.LayoutParams lp = window.getAttributes();
1068 | Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
1069 | Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
1070 | darkFlag.setAccessible(true);
1071 | meizuFlags.setAccessible(true);
1072 | int bit = darkFlag.getInt(null);
1073 | int value = meizuFlags.getInt(lp);
1074 | if (dark) {
1075 | value |= bit;
1076 | } else {
1077 | value &= ~bit;
1078 | }
1079 | meizuFlags.setInt(lp, value);
1080 | window.setAttributes(lp);
1081 | } catch (Exception e) {
1082 | e.printStackTrace();
1083 | }
1084 | // android6.0+系统
1085 | // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
1086 | // if (dark) {
1087 | // mActivity.getWindow().getDecorView().setSystemUiVisibility(
1088 | // View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
1089 | // | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
1090 | // }
1091 | // }
1092 | }
1093 |
1094 |
1095 | public static void initStatusBarFontDark(Activity mActivity, boolean dark) {
1096 | // 小米MIUI
1097 | try {
1098 | Window window = mActivity.getWindow();
1099 | Class clazz = mActivity.getWindow().getClass();
1100 | Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
1101 | Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
1102 | int darkModeFlag = field.getInt(layoutParams);
1103 | Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
1104 | if (dark) { //状态栏亮色且黑色字体
1105 | extraFlagField.invoke(window, darkModeFlag, darkModeFlag);
1106 | } else { //清除黑色字体
1107 | extraFlagField.invoke(window, 0, darkModeFlag);
1108 | }
1109 | } catch (Exception e) {
1110 | e.printStackTrace();
1111 | }
1112 |
1113 | // 魅族FlymeUI
1114 | try {
1115 | Window window = mActivity.getWindow();
1116 | WindowManager.LayoutParams lp = window.getAttributes();
1117 | Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
1118 | Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
1119 | darkFlag.setAccessible(true);
1120 | meizuFlags.setAccessible(true);
1121 | int bit = darkFlag.getInt(null);
1122 | int value = meizuFlags.getInt(lp);
1123 | if (dark) {
1124 | value |= bit;
1125 | } else {
1126 | value &= ~bit;
1127 | }
1128 | meizuFlags.setInt(lp, value);
1129 | window.setAttributes(lp);
1130 | } catch (Exception e) {
1131 | e.printStackTrace();
1132 | }
1133 | }
1134 |
1135 | /**
1136 | * 设置应用全屏
1137 | *
1138 | * @return void
1139 | * @author lanhm
1140 | * @date 2014年11月18日 下午5:48:30
1141 | * @MethodName: setFullScreen
1142 | */
1143 | public static void setFullScreen(Activity activity) {
1144 | activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
1145 | }
1146 |
1147 | /**
1148 | * 退出全屏
1149 | *
1150 | * @return void
1151 | * @author lanhm
1152 | * @date 2014年11月18日 下午5:48:52
1153 | * @MethodName: quitFullScreen
1154 | */
1155 | public static void quitFullScreen(Activity activity) {
1156 | final WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
1157 | attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
1158 | activity.getWindow().setAttributes(attrs);
1159 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
1160 | }
1161 |
1162 | //隐藏虚拟按键,并且全屏
1163 | public static void hideBottomUIMenu(Activity activity) {
1164 | if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
1165 | View v = activity.getWindow().getDecorView();
1166 | v.setSystemUiVisibility(View.GONE);
1167 | } else if (Build.VERSION.SDK_INT >= 19) {
1168 | //for new api versions.
1169 | View decorView = activity.getWindow().getDecorView();
1170 | int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
1171 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
1172 | decorView.setSystemUiVisibility(uiOptions);
1173 |
1174 | }
1175 | }
1176 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/byl/mvvm/utils/SysUtils.kt:
--------------------------------------------------------------------------------
1 | package com.byl.mvvm.utils
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.content.pm.ApplicationInfo
6 | import android.content.pm.PackageInfo
7 | import android.content.pm.PackageManager
8 | import android.os.Build
9 | import android.os.Environment
10 | import com.byl.mvvm.App
11 | import com.byl.mvvm.R
12 | import java.io.File
13 |
14 |
15 | object SysUtils {
16 |
17 | fun dp2Px(context: Context, dp: Float): Int {
18 | val scale: Float = context.resources.displayMetrics.density
19 | return (dp * scale + 0.5f).toInt()
20 | }
21 |
22 | fun px2Dp(context: Context, px: Float): Int {
23 | val scale: Float = context.resources.displayMetrics.density
24 | return (px / scale + 0.5f).toInt()
25 | }
26 |
27 |
28 | // 获取当前APP名称
29 | fun getAppName(context: Context): String? {
30 | val packageManager = context.packageManager
31 | val applicationInfo: ApplicationInfo
32 | applicationInfo = try {
33 | packageManager.getApplicationInfo(context.packageName, 0)
34 | } catch (e: java.lang.Exception) {
35 | return context.resources.getString(R.string.app_name)
36 | }
37 | return packageManager.getApplicationLabel(applicationInfo).toString()
38 | }
39 |
40 | fun getAppVersion(): String? {
41 | val context: Context = App.instance
42 | val manager: PackageManager = context.packageManager
43 | return try {
44 | val info: PackageInfo = manager.getPackageInfo(context.packageName, 0)
45 | info.versionName
46 | } catch (e: PackageManager.NameNotFoundException) {
47 | e.printStackTrace()
48 | "1.0.0"
49 | }
50 | }
51 |
52 | fun getAppVersionCode(): Int {
53 | val context: Context = App.instance
54 | val manager: PackageManager = context.packageManager
55 | return try {
56 | val info: PackageInfo = manager.getPackageInfo(context.packageName, 0)
57 | info.versionCode
58 | } catch (e: PackageManager.NameNotFoundException) {
59 | e.printStackTrace()
60 | 1
61 | }
62 | }
63 |
64 | /**
65 | * 获取手机型号
66 | *
67 | * @return 手机型号
68 | */
69 | fun getSystemModel(): String? {
70 | return try {
71 | Build.MODEL
72 | } catch (e: Exception) {
73 | ""
74 | }
75 | }
76 |
77 | /**
78 | * 获取手机厂商
79 | *
80 | * @return 手机厂商
81 | */
82 | fun getDeviceBrand(): String? {
83 | return try {
84 | Build.BRAND
85 | } catch (e: Exception) {
86 | ""
87 | }
88 | }
89 |
90 | fun initFiles() {
91 | var file = File(Environment.getExternalStorageDirectory(), "MVVM/data")
92 | if (!file.exists()) file.mkdirs()
93 | file = File(Environment.getExternalStorageDirectory(), "MVVM/images")
94 | if (!file.exists()) file.mkdirs()
95 | file = File(Environment.getExternalStorageDirectory(), "MVVM/download")
96 | if (!file.exists()) file.mkdirs()
97 | }
98 |
99 | fun getScreenWidth(activity: Activity): Int {
100 | var width = 0
101 | val windowManager = activity.windowManager
102 | val display = windowManager.defaultDisplay
103 | width = display.width
104 | return width
105 | }
106 |
107 | fun getScreenHeight(activity: Activity): Int {
108 | var height = 0
109 | val windowManager = activity.windowManager
110 | val display = windowManager.defaultDisplay
111 | height = display.height
112 | return height
113 | }
114 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/byl/mvvm/utils/ToastUtil.kt:
--------------------------------------------------------------------------------
1 | package com.byl.mvvm.utils
2 |
3 | import android.content.Context
4 | import android.text.TextUtils
5 | import android.widget.Toast
6 |
7 |
8 | object ToastUtil {
9 | fun showToast(context: Context?, message: String?) {
10 | if (!TextUtils.isEmpty(message)) Toast.makeText(context, message, Toast.LENGTH_SHORT)
11 | .show()
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/byl/mvvm/widget/ViewClickDelay.kt:
--------------------------------------------------------------------------------
1 | package com.byl.mvvm.widget
2 |
3 | import android.view.View
4 | import com.byl.mvvm.widget.ViewClickDelay.SPACE_TIME
5 | import com.byl.mvvm.widget.ViewClickDelay.hash
6 | import com.byl.mvvm.widget.ViewClickDelay.lastClickTime
7 |
8 | object ViewClickDelay {
9 | var hash: Int = 0
10 | var lastClickTime: Long = 0
11 | var SPACE_TIME: Long = 1000
12 | }
13 |
14 | infix fun View.clicks(clickAction: () -> Unit) {
15 | this.setOnClickListener {
16 | if (this.hashCode() != hash) {
17 | hash = this.hashCode()
18 | lastClickTime = System.currentTimeMillis()
19 | clickAction()
20 | } else {
21 | val currentTime = System.currentTimeMillis()
22 | if (currentTime - lastClickTime > SPACE_TIME) {
23 | lastClickTime = System.currentTimeMillis()
24 | clickAction()
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
20 |
24 |
25 |
36 |
37 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_test_event.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
20 |
24 |
25 |
28 |
29 |
33 |
34 |
39 |
40 |
41 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
22 |
23 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_article.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
19 |
20 |
31 |
32 |
45 |
46 |
47 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v23/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #2BD9B4
6 | #FFFFFF
7 |
8 | #111111
9 | #222222
10 | #333333
11 | #444444
12 | #555555
13 | #666666
14 | #777777
15 | #888888
16 | #999999
17 | #AAAAAA
18 | #BBBBBB
19 | #CCCCCC
20 | #DDDDDD
21 | #EEEEEE
22 | #FFFFFF
23 | #000000
24 |
25 | #F1F1F1
26 | #F2F2F2
27 | #F3F3F3
28 | #F4F4F4
29 | #F5F5F5
30 | #F6F6F6
31 | #F7F7F7
32 | #F8F8F8
33 | #F9F9F9
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MVVM
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/file_path.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
11 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | ext.kotlin_version = "1.5.21"
4 | repositories {
5 | maven { url 'https://jitpack.io' }
6 | maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
7 | maven { url 'https://maven.aliyun.com/repository/central' }
8 | maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
9 | google()
10 | mavenCentral()
11 | }
12 | dependencies {
13 | classpath "com.android.tools.build:gradle:4.0.0"
14 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | maven { url 'https://jitpack.io' }
21 | maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
22 | maven { url 'https://maven.aliyun.com/repository/central' }
23 | maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
24 | google()
25 | mavenCentral()
26 | }
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/baiyuliang/MVVM/d72a9fd2d47c61bbbd471d60aa1f6ea5c696d7e1/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jun 01 10:36:54 CST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | rootProject.name = "MVVM"
--------------------------------------------------------------------------------