mTagData = new ArrayList<>();
26 | private static String mTagType[] = { "有电梯", "绿化率高", "小区环境好", "安静", "南北通透税费低" };
27 | private static String mTagColor[] = { "394043", "be5453", "00ae66", "b27f39", "ae005d" };
28 |
29 | @Override protected void onCreate(Bundle savedInstanceState) {
30 | super.onCreate(savedInstanceState);
31 | setContentView(R.layout.activity_flowtag_layout);
32 | ButterKnife.bind(this);
33 | initBar(mTitleBar);
34 | initData();
35 | initView();
36 | }
37 |
38 | private void initView() {
39 | mFlowLayout.removeAllViews();
40 | for (int i = 0; i < mTagData.size(); i++) {
41 | mFlowLayout.addView(new ColorTagView(this, mTagData.get(i)));
42 | }
43 | }
44 |
45 | private void initData() {
46 | Random random = new Random();
47 | for (int i = 0; i < 30; i++) {
48 | ColorTag colorTag = new ColorTag();
49 | colorTag.text = mTagType[random.nextInt(5)];
50 | colorTag.color = mTagColor[random.nextInt(5)];
51 | mTagData.add(colorTag);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/binioter/ui/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.binioter.ui;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import butterknife.ButterKnife;
6 | import butterknife.OnClick;
7 | import com.binioter.R;
8 | import com.binioter.base.BaseActivity;
9 | import com.binioter.widget.TopTitleBar;
10 |
11 | public class MainActivity extends BaseActivity {
12 |
13 | @Override protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_main);
16 | ButterKnife.bind(this);
17 | setSwipeBackEnabled(false);
18 | initTitleBar();
19 | }
20 |
21 | private void initTitleBar() {
22 | TopTitleBar topTitleBar = (TopTitleBar) findViewById(R.id.title_bar);
23 | topTitleBar.setTitle("首页");
24 | topTitleBar.setLeftVisible(false);
25 | initBar(topTitleBar);
26 | }
27 |
28 | @OnClick(R.id.btn_jump_dialog_aty) void onBtnJumpDialogAty() {
29 | startActivity(new Intent(MainActivity.this, CommonDialogActivity.class));
30 | }
31 |
32 | @OnClick(R.id.btn_jump_flow_aty) void onBtnJumpFlowAty() {
33 | startActivity(new Intent(MainActivity.this, FlowLayoutActivity.class));
34 | }
35 |
36 | @OnClick(R.id.btn_jump_tips_aty) void onBtnJumpTIpsAty() {
37 | startActivity(new Intent(MainActivity.this, TipTextViewActivity.class));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/binioter/ui/TipTextViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.binioter.ui;
2 |
3 | import android.os.Bundle;
4 | import android.widget.Button;
5 | import butterknife.Bind;
6 | import butterknife.ButterKnife;
7 | import butterknife.OnClick;
8 | import com.binioter.R;
9 | import com.binioter.base.BaseActivity;
10 | import com.binioter.tiptextview.TipTextView;
11 | import com.binioter.util.DensityUtil;
12 | import com.binioter.widget.TopTitleBar;
13 |
14 | /**
15 | * 创建时间: 2016/11/29 11:36
16 | * 作者: zhangbin
17 | * 描述: 弹出tips的Activity
18 | */
19 |
20 | public class TipTextViewActivity extends BaseActivity {
21 | @Bind(R.id.btn_show) Button mBtnShow;
22 | @Bind(R.id.btn_hide) Button mBtnHide;
23 | @Bind(R.id.tip_tv) TipTextView mTipTv;
24 | @Bind(R.id.title_bar) TopTitleBar mTitleBar;
25 |
26 | @Override protected void onCreate(Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | setContentView(R.layout.tip_textview_activity_layout);
29 | ButterKnife.bind(this);
30 | initBar(mTitleBar);
31 | //因为是带有沉浸式状态栏所以要加上状态栏的高度,没有沉浸式状态栏,这行代码可以去掉,默认为titlebar的高度
32 | mTipTv.setHeight(
33 | DensityUtil.px2dip(this, DensityUtil.getStatusBarHeight(this)) + mTitleBarHeight);
34 | }
35 |
36 | @OnClick(R.id.btn_show) void showTips() {
37 | mTipTv.showTips(getResources().getString(R.string.txt_tips));
38 | }
39 |
40 | @OnClick(R.id.btn_hide) void hideTips() {
41 | mTipTv.hideTips();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/binioter/utils/SystemBarTintManager.java:
--------------------------------------------------------------------------------
1 | package com.binioter.utils;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.annotation.TargetApi;
5 | import android.app.Activity;
6 | import android.content.Context;
7 | import android.content.res.Configuration;
8 | import android.content.res.Resources;
9 | import android.content.res.TypedArray;
10 | import android.graphics.drawable.Drawable;
11 | import android.os.Build;
12 | import android.util.DisplayMetrics;
13 | import android.util.TypedValue;
14 | import android.view.Gravity;
15 | import android.view.View;
16 | import android.view.ViewConfiguration;
17 | import android.view.ViewGroup;
18 | import android.view.Window;
19 | import android.view.WindowManager;
20 | import android.widget.FrameLayout.LayoutParams;
21 |
22 | import java.lang.reflect.Method;
23 |
24 | /**
25 | * Class to manage status and navigation bar tint effects when using KitKat
26 | * translucent system UI modes.
27 | */
28 | public class SystemBarTintManager {
29 |
30 | static {
31 | // Android allows a system property to override the presence of the navigation bar.
32 | // Used by the emulator.
33 | // See https://github.com/android/platform_frameworks_base/blob/master/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java#L1076
34 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
35 | try {
36 | Class c = Class.forName("android.os.SystemProperties");
37 | Method m = c.getDeclaredMethod("get", String.class);
38 | m.setAccessible(true);
39 | sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
40 | } catch (Throwable e) {
41 | sNavBarOverride = null;
42 | }
43 | }
44 | }
45 |
46 |
47 | /**
48 | * The default system bar tint color value.
49 | */
50 | public static final int DEFAULT_TINT_COLOR = 0x99000000;
51 |
52 | private static String sNavBarOverride;
53 |
54 | private final SystemBarConfig mConfig;
55 | private boolean mStatusBarAvailable;
56 | private boolean mNavBarAvailable;
57 | private boolean mStatusBarTintEnabled;
58 | private boolean mNavBarTintEnabled;
59 | private View mStatusBarTintView;
60 | private View mNavBarTintView;
61 |
62 | /**
63 | * Constructor. Call this in the host activity onCreate method after its
64 | * content view has been set. You should always create new instances when
65 | * the host activity is recreated.
66 | *
67 | * @param activity The host activity.
68 | */
69 | @TargetApi(19)
70 | public SystemBarTintManager(Activity activity) {
71 |
72 | Window win = activity.getWindow();
73 | ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();
74 |
75 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
76 | // check theme attrs
77 | int[] attrs = {android.R.attr.windowTranslucentStatus,
78 | android.R.attr.windowTranslucentNavigation};
79 | TypedArray a = activity.obtainStyledAttributes(attrs);
80 | try {
81 | mStatusBarAvailable = a.getBoolean(0, false);
82 | mNavBarAvailable = a.getBoolean(1, false);
83 | } finally {
84 | a.recycle();
85 | }
86 |
87 | // check window flags
88 | WindowManager.LayoutParams winParams = win.getAttributes();
89 | int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
90 | if ((winParams.flags & bits) != 0) {
91 | mStatusBarAvailable = true;
92 | }
93 | bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
94 | if ((winParams.flags & bits) != 0) {
95 | mNavBarAvailable = true;
96 | }
97 | }
98 |
99 | mConfig = new SystemBarConfig(activity, mStatusBarAvailable, mNavBarAvailable);
100 | // device might not have virtual navigation keys
101 | if (!mConfig.hasNavigtionBar()) {
102 | mNavBarAvailable = false;
103 | }
104 |
105 | if (mStatusBarAvailable) {
106 | setupStatusBarView(activity, decorViewGroup);
107 | }
108 | if (mNavBarAvailable) {
109 | setupNavBarView(activity, decorViewGroup);
110 | }
111 |
112 | }
113 |
114 | /**
115 | * Enable tinting of the system status bar.
116 | *
117 | * If the platform is running Jelly Bean or earlier, or translucent system
118 | * UI modes have not been enabled in either the theme or via window flags,
119 | * then this method does nothing.
120 | *
121 | * @param enabled True to enable tinting, false to disable it (default).
122 | */
123 | public void setStatusBarTintEnabled(boolean enabled) {
124 | mStatusBarTintEnabled = enabled;
125 | if (mStatusBarAvailable) {
126 | mStatusBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
127 | }
128 | }
129 |
130 | /**
131 | * Enable tinting of the system navigation bar.
132 | *
133 | * If the platform does not have soft navigation keys, is running Jelly Bean
134 | * or earlier, or translucent system UI modes have not been enabled in either
135 | * the theme or via window flags, then this method does nothing.
136 | *
137 | * @param enabled True to enable tinting, false to disable it (default).
138 | */
139 | public void setNavigationBarTintEnabled(boolean enabled) {
140 | mNavBarTintEnabled = enabled;
141 | if (mNavBarAvailable) {
142 | mNavBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
143 | }
144 | }
145 |
146 | /**
147 | * Apply the specified color tint to all system UI bars.
148 | *
149 | * @param color The color of the background tint.
150 | */
151 | public void setTintColor(int color) {
152 | setStatusBarTintColor(color);
153 | setNavigationBarTintColor(color);
154 | }
155 |
156 | /**
157 | * Apply the specified drawable or color resource to all system UI bars.
158 | *
159 | * @param res The identifier of the resource.
160 | */
161 | public void setTintResource(int res) {
162 | setStatusBarTintResource(res);
163 | setNavigationBarTintResource(res);
164 | }
165 |
166 | /**
167 | * Apply the specified drawable to all system UI bars.
168 | *
169 | * @param drawable The drawable to use as the background, or null to remove it.
170 | */
171 | public void setTintDrawable(Drawable drawable) {
172 | setStatusBarTintDrawable(drawable);
173 | setNavigationBarTintDrawable(drawable);
174 | }
175 |
176 | /**
177 | * Apply the specified alpha to all system UI bars.
178 | *
179 | * @param alpha The alpha to use
180 | */
181 | public void setTintAlpha(float alpha) {
182 | setStatusBarAlpha(alpha);
183 | setNavigationBarAlpha(alpha);
184 | }
185 |
186 | /**
187 | * Apply the specified color tint to the system status bar.
188 | *
189 | * @param color The color of the background tint.
190 | */
191 | public void setStatusBarTintColor(int color) {
192 | if (mStatusBarAvailable) {
193 | mStatusBarTintView.setBackgroundColor(color);
194 | }
195 | }
196 |
197 | /**
198 | * Apply the specified drawable or color resource to the system status bar.
199 | *
200 | * @param res The identifier of the resource.
201 | */
202 | public void setStatusBarTintResource(int res) {
203 | if (mStatusBarAvailable) {
204 | mStatusBarTintView.setBackgroundResource(res);
205 | }
206 | }
207 |
208 | /**
209 | * Apply the specified drawable to the system status bar.
210 | *
211 | * @param drawable The drawable to use as the background, or null to remove it.
212 | */
213 | @SuppressWarnings("deprecation")
214 | public void setStatusBarTintDrawable(Drawable drawable) {
215 | if (mStatusBarAvailable) {
216 | mStatusBarTintView.setBackgroundDrawable(drawable);
217 | }
218 | }
219 |
220 | /**
221 | * Apply the specified alpha to the system status bar.
222 | *
223 | * @param alpha The alpha to use
224 | */
225 | @TargetApi(11)
226 | public void setStatusBarAlpha(float alpha) {
227 | if (mStatusBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
228 | mStatusBarTintView.setAlpha(alpha);
229 | }
230 | }
231 |
232 | /**
233 | * Apply the specified color tint to the system navigation bar.
234 | *
235 | * @param color The color of the background tint.
236 | */
237 | public void setNavigationBarTintColor(int color) {
238 | if (mNavBarAvailable) {
239 | mNavBarTintView.setBackgroundColor(color);
240 | }
241 | }
242 |
243 | /**
244 | * Apply the specified drawable or color resource to the system navigation bar.
245 | *
246 | * @param res The identifier of the resource.
247 | */
248 | public void setNavigationBarTintResource(int res) {
249 | if (mNavBarAvailable) {
250 | mNavBarTintView.setBackgroundResource(res);
251 | }
252 | }
253 |
254 | /**
255 | * Apply the specified drawable to the system navigation bar.
256 | *
257 | * @param drawable The drawable to use as the background, or null to remove it.
258 | */
259 | @SuppressWarnings("deprecation")
260 | public void setNavigationBarTintDrawable(Drawable drawable) {
261 | if (mNavBarAvailable) {
262 | mNavBarTintView.setBackgroundDrawable(drawable);
263 | }
264 | }
265 |
266 | /**
267 | * Apply the specified alpha to the system navigation bar.
268 | *
269 | * @param alpha The alpha to use
270 | */
271 | @TargetApi(11)
272 | public void setNavigationBarAlpha(float alpha) {
273 | if (mNavBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
274 | mNavBarTintView.setAlpha(alpha);
275 | }
276 | }
277 |
278 | /**
279 | * Get the system bar configuration.
280 | *
281 | * @return The system bar configuration for the current device configuration.
282 | */
283 | public SystemBarConfig getConfig() {
284 | return mConfig;
285 | }
286 |
287 | /**
288 | * Is tinting enabled for the system status bar?
289 | *
290 | * @return True if enabled, False otherwise.
291 | */
292 | public boolean isStatusBarTintEnabled() {
293 | return mStatusBarTintEnabled;
294 | }
295 |
296 | /**
297 | * Is tinting enabled for the system navigation bar?
298 | *
299 | * @return True if enabled, False otherwise.
300 | */
301 | public boolean isNavBarTintEnabled() {
302 | return mNavBarTintEnabled;
303 | }
304 |
305 | private void setupStatusBarView(Context context, ViewGroup decorViewGroup) {
306 | mStatusBarTintView = new View(context);
307 | LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight());
308 | params.gravity = Gravity.TOP;
309 | if (mNavBarAvailable && !mConfig.isNavigationAtBottom()) {
310 | params.rightMargin = mConfig.getNavigationBarWidth();
311 | }
312 | mStatusBarTintView.setLayoutParams(params);
313 | mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);
314 | mStatusBarTintView.setVisibility(View.GONE);
315 | decorViewGroup.addView(mStatusBarTintView);
316 | }
317 |
318 | private void setupNavBarView(Context context, ViewGroup decorViewGroup) {
319 | mNavBarTintView = new View(context);
320 | LayoutParams params;
321 | if (mConfig.isNavigationAtBottom()) {
322 | params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getNavigationBarHeight());
323 | params.gravity = Gravity.BOTTOM;
324 | } else {
325 | params = new LayoutParams(mConfig.getNavigationBarWidth(), LayoutParams.MATCH_PARENT);
326 | params.gravity = Gravity.RIGHT;
327 | }
328 | mNavBarTintView.setLayoutParams(params);
329 | mNavBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);
330 | mNavBarTintView.setVisibility(View.GONE);
331 | decorViewGroup.addView(mNavBarTintView);
332 | }
333 |
334 | /**
335 | * Class which describes system bar sizing and other characteristics for the current
336 | * device configuration.
337 | */
338 | public static class SystemBarConfig {
339 |
340 | private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";
341 | private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height";
342 | private static final String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = "navigation_bar_height_landscape";
343 | private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width";
344 | private static final String SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar";
345 |
346 | private final boolean mTranslucentStatusBar;
347 | private final boolean mTranslucentNavBar;
348 | private final int mStatusBarHeight;
349 | private final int mActionBarHeight;
350 | private final boolean mHasNavigationBar;
351 | private final int mNavigationBarHeight;
352 | private final int mNavigationBarWidth;
353 | private final boolean mInPortrait;
354 | private final float mSmallestWidthDp;
355 |
356 | private SystemBarConfig(Activity activity, boolean translucentStatusBar, boolean traslucentNavBar) {
357 | Resources res = activity.getResources();
358 | mInPortrait = (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
359 | mSmallestWidthDp = getSmallestWidthDp(activity);
360 | mStatusBarHeight = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME);
361 | mActionBarHeight = getActionBarHeight(activity);
362 | mNavigationBarHeight = getNavigationBarHeight(activity);
363 | mNavigationBarWidth = getNavigationBarWidth(activity);
364 | mHasNavigationBar = (mNavigationBarHeight > 0);
365 | mTranslucentStatusBar = translucentStatusBar;
366 | mTranslucentNavBar = traslucentNavBar;
367 | }
368 |
369 | @TargetApi(14)
370 | private int getActionBarHeight(Context context) {
371 | int result = 0;
372 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
373 | TypedValue tv = new TypedValue();
374 | context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);
375 | result = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
376 | }
377 | return result;
378 | }
379 |
380 | @TargetApi(14)
381 | private int getNavigationBarHeight(Context context) {
382 | Resources res = context.getResources();
383 | int result = 0;
384 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
385 | if (hasNavBar(context)) {
386 | String key;
387 | if (mInPortrait) {
388 | key = NAV_BAR_HEIGHT_RES_NAME;
389 | } else {
390 | key = NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME;
391 | }
392 | return getInternalDimensionSize(res, key);
393 | }
394 | }
395 | return result;
396 | }
397 |
398 | @TargetApi(14)
399 | private int getNavigationBarWidth(Context context) {
400 | Resources res = context.getResources();
401 | int result = 0;
402 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
403 | if (hasNavBar(context)) {
404 | return getInternalDimensionSize(res, NAV_BAR_WIDTH_RES_NAME);
405 | }
406 | }
407 | return result;
408 | }
409 |
410 | @TargetApi(14)
411 | private boolean hasNavBar(Context context) {
412 | Resources res = context.getResources();
413 | int resourceId = res.getIdentifier(SHOW_NAV_BAR_RES_NAME, "bool", "android");
414 | if (resourceId != 0) {
415 | boolean hasNav = res.getBoolean(resourceId);
416 | // check override flag (see static block)
417 | if ("1".equals(sNavBarOverride)) {
418 | hasNav = false;
419 | } else if ("0".equals(sNavBarOverride)) {
420 | hasNav = true;
421 | }
422 | return hasNav;
423 | } else { // fallback
424 | return !ViewConfiguration.get(context).hasPermanentMenuKey();
425 | }
426 | }
427 |
428 | private int getInternalDimensionSize(Resources res, String key) {
429 | int result = 0;
430 | int resourceId = res.getIdentifier(key, "dimen", "android");
431 | if (resourceId > 0) {
432 | result = res.getDimensionPixelSize(resourceId);
433 | }
434 | return result;
435 | }
436 |
437 | @SuppressLint("NewApi")
438 | private float getSmallestWidthDp(Activity activity) {
439 | DisplayMetrics metrics = new DisplayMetrics();
440 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
441 | activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
442 | } else {
443 | // TODO this is not correct, but we don't really care pre-kitkat
444 | activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
445 | }
446 | float widthDp = metrics.widthPixels / metrics.density;
447 | float heightDp = metrics.heightPixels / metrics.density;
448 | return Math.min(widthDp, heightDp);
449 | }
450 |
451 | /**
452 | * Should a navigation bar appear at the bottom of the screen in the current
453 | * device configuration? A navigation bar may appear on the right side of
454 | * the screen in certain configurations.
455 | *
456 | * @return True if navigation should appear at the bottom of the screen, False otherwise.
457 | */
458 | public boolean isNavigationAtBottom() {
459 | return (mSmallestWidthDp >= 600 || mInPortrait);
460 | }
461 |
462 | /**
463 | * Get the height of the system status bar.
464 | *
465 | * @return The height of the status bar (in pixels).
466 | */
467 | public int getStatusBarHeight() {
468 | return mStatusBarHeight;
469 | }
470 |
471 | /**
472 | * Get the height of the action bar.
473 | *
474 | * @return The height of the action bar (in pixels).
475 | */
476 | public int getActionBarHeight() {
477 | return mActionBarHeight;
478 | }
479 |
480 | /**
481 | * Does this device have a system navigation bar?
482 | *
483 | * @return True if this device uses soft key navigation, False otherwise.
484 | */
485 | public boolean hasNavigtionBar() {
486 | return mHasNavigationBar;
487 | }
488 |
489 | /**
490 | * Get the height of the system navigation bar.
491 | *
492 | * @return The height of the navigation bar (in pixels). If the device does not have
493 | * soft navigation keys, this will always return 0.
494 | */
495 | public int getNavigationBarHeight() {
496 | return mNavigationBarHeight;
497 | }
498 |
499 | /**
500 | * Get the width of the system navigation bar when it is placed vertically on the screen.
501 | *
502 | * @return The width of the navigation bar (in pixels). If the device does not have
503 | * soft navigation keys, this will always return 0.
504 | */
505 | public int getNavigationBarWidth() {
506 | return mNavigationBarWidth;
507 | }
508 |
509 | /**
510 | * Get the layout inset for any system UI that appears at the top of the screen.
511 | *
512 | * @param withActionBar True to include the height of the action bar, False otherwise.
513 | * @return The layout inset (in pixels).
514 | */
515 | public int getPixelInsetTop(boolean withActionBar) {
516 | return (mTranslucentStatusBar ? mStatusBarHeight : 0) + (withActionBar ? mActionBarHeight : 0);
517 | }
518 |
519 | /**
520 | * Get the layout inset for any system UI that appears at the bottom of the screen.
521 | *
522 | * @return The layout inset (in pixels).
523 | */
524 | public int getPixelInsetBottom() {
525 | if (mTranslucentNavBar && isNavigationAtBottom()) {
526 | return mNavigationBarHeight;
527 | } else {
528 | return 0;
529 | }
530 | }
531 |
532 | /**
533 | * Get the layout inset for any system UI that appears at the right of the screen.
534 | *
535 | * @return The layout inset (in pixels).
536 | */
537 | public int getPixelInsetRight() {
538 | if (mTranslucentNavBar && !isNavigationAtBottom()) {
539 | return mNavigationBarWidth;
540 | } else {
541 | return 0;
542 | }
543 | }
544 |
545 | }
546 |
547 | }
548 |
549 |
--------------------------------------------------------------------------------
/app/src/main/java/com/binioter/utils/TitleBarHelper.java:
--------------------------------------------------------------------------------
1 | package com.binioter.utils;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.view.View;
6 | import com.binioter.R;
7 | import com.binioter.widget.TopTitleBar;
8 |
9 | public class TitleBarHelper {
10 |
11 | private Context mContext;
12 | private TopTitleBar mTopTitleBar;
13 |
14 | public TitleBarHelper(Context context, TopTitleBar titleBar) {
15 | this.mContext = context;
16 |
17 | this.mTopTitleBar = titleBar;
18 | }
19 |
20 | /**
21 | * decorate the titleBar,white
22 | * 初始化并开启沉浸模式
23 | */
24 |
25 | public void init() {
26 | if (mTopTitleBar != null) {
27 | mTopTitleBar.setBackgroundResource(R.color.title_bar_color);
28 | mTopTitleBar.setLeftClickListener(mDefaultListener);// set default
29 | // listener
30 | mTopTitleBar.setMainTitleColor(mContext.getResources().getColor(R.color.title_color));
31 | mTopTitleBar.setLeftImageResource(R.mipmap.btn_back_normal);
32 | mTopTitleBar.setDividerHeight(1);
33 | mTopTitleBar.setDividerColor(mContext.getResources().getColor(R.color.title_color));
34 | mTopTitleBar.setLeftTextColor(mContext.getResources().getColor(R.color.title_color));
35 | mTopTitleBar.setImmersive(true);
36 | }
37 | }
38 |
39 | private View.OnClickListener mDefaultListener = new View.OnClickListener() {
40 | @Override public void onClick(View v) {
41 | if (mContext != null) {
42 | Activity activity = (Activity) mContext;
43 | activity.finish();
44 | }
45 | }
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/binioter/widget/SwipeBackLayout.java:
--------------------------------------------------------------------------------
1 | package com.binioter.widget;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.graphics.Canvas;
6 | import android.graphics.Rect;
7 | import android.graphics.drawable.ColorDrawable;
8 | import android.support.v4.view.MotionEventCompat;
9 | import android.util.AttributeSet;
10 | import android.util.TypedValue;
11 | import android.view.MotionEvent;
12 | import android.view.VelocityTracker;
13 | import android.view.View;
14 | import android.view.ViewConfiguration;
15 | import android.view.ViewGroup;
16 | import android.view.Window;
17 | import android.view.animation.Interpolator;
18 | import android.widget.FrameLayout;
19 | import android.widget.Scroller;
20 | import com.binioter.R;
21 | import com.binioter.util.DensityUtil;
22 |
23 | /**
24 | *
滑动返回
25 | * 滑动返回:支持将Activity设置为向右滑返回; 原理 继承自FrameLayout
26 | * 将Activity中显示内容的View添加到到SwipeBackLayout的实例中,再将SwipeBackLayout的实例添加到Activity中.
27 | * 对SwipeBackLayout实例借助Scroller类调用ScrollTo方法来实现滑动显示内容的View.
28 | * Activity的背景会被设置为透明的,这样在显示内容的View滑动的过程中才可以显示出底层View. 另外还需要调用了
29 | * {@link #setBgTransparent()}将SwipeBackLayout的实例的背景设置为透明.
30 | */
31 | public class SwipeBackLayout extends FrameLayout {
32 |
33 | private Activity mActivity;
34 | private View mContentView;
35 | private ViewGroup mRealContentView;
36 | private Scroller mScroller;
37 | private int mViewWidth;
38 |
39 | private int mTouchSlop;
40 | private static final int MARGIN_THRESHOLD = 24; // dips
41 |
42 | private float mLastMotionX;
43 | private float mLastMotionY;
44 | private float mDownX;
45 | private int mCurMotionX;
46 |
47 | private int mActivePointerId = INVALID_POINTER;
48 | private static final int INVALID_POINTER = -1;
49 |
50 | private boolean mIsSilding = false;
51 | private boolean mIsFinish = false;
52 | private boolean mIsSwipeBackEnabled = true;
53 | private boolean mIsScrolling = false;
54 |
55 | private int mMarginThreshold;
56 |
57 | private int mAlphaBgColor = 0;
58 | private Rect mColorRect = new Rect();
59 |
60 | private VelocityTracker mVelocityTracker;
61 | private int mMinimumVelocity;
62 | private int mMaximumVelocity;
63 | private int mFlingDistance;
64 | private int mMoveDistance;
65 | private static final int MIN_DISTANCE_FOR_MOVE = 24; // dips
66 | private float mXVelocity;
67 |
68 | /**
69 | * SwipeLayout的构造函数
70 | *
71 | * @param context
72 | */
73 | public SwipeBackLayout(Context context) {
74 | super(context);
75 | init(context);
76 | }
77 |
78 | /**
79 | * SwipeLayout的构造函数
80 | *
81 | * @param context
82 | * @param attrs
83 | */
84 | public SwipeBackLayout(Context context, AttributeSet attrs) {
85 | super(context, attrs);
86 | init(context);
87 | }
88 |
89 | /**
90 | * SwipeLayout的构造函数
91 | *
92 | * @param context
93 | * @param attrs
94 | * @param defStyle
95 | */
96 | public SwipeBackLayout(Context context, AttributeSet attrs, int defStyle) {
97 | super(context, attrs, defStyle);
98 | init(context);
99 | }
100 |
101 | /**
102 | * 实例化一些需要的对象实例和参数
103 | *
104 | * @param context
105 | */
106 | private void init(Context context) {
107 | mMarginThreshold = (int) TypedValue.applyDimension(
108 | TypedValue.COMPLEX_UNIT_DIP, MARGIN_THRESHOLD, getResources()
109 | .getDisplayMetrics());
110 | mScroller = new Scroller(context, new MyAccelerateInterpolator(1.5f));
111 | mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 2;
112 | mMaximumVelocity = ViewConfiguration.getMaximumFlingVelocity();
113 | mMinimumVelocity = ViewConfiguration.getMinimumFlingVelocity();
114 | final float density = context.getResources().getDisplayMetrics().density;
115 | mMoveDistance = (int) (MIN_DISTANCE_FOR_MOVE * density);
116 | int deviceWidth = DensityUtil.getEquipmentWidth(context);
117 | mFlingDistance = deviceWidth / 4;
118 | }
119 |
120 | /**
121 | * @param activity
122 | */
123 | public void attachToActivity(Activity activity) {
124 | try {
125 | mActivity = activity;
126 |
127 | Window window = activity.getWindow();
128 | window.setBackgroundDrawable(new ColorDrawable(0));
129 |
130 | ViewGroup decor = (ViewGroup) window.getDecorView();
131 | mRealContentView = (ViewGroup) decor.getChildAt(0);
132 | decor.removeView(mRealContentView);
133 | mRealContentView.setClickable(true);
134 | addView(mRealContentView);
135 | mContentView = (View) mRealContentView.getParent();
136 | decor.addView(this);
137 | } catch (Exception e) {
138 | mIsSwipeBackEnabled = false;
139 | }
140 | }
141 |
142 | @Override
143 | protected void dispatchDraw(Canvas canvas) {
144 | super.dispatchDraw(canvas);
145 | if (mContentView != null) {
146 |
147 | int left = 0;
148 | int right = mCurMotionX;
149 | int top = 0;
150 | int bottom = mContentView.getBottom();
151 |
152 | mColorRect.top = top;
153 | mColorRect.bottom = bottom;
154 | mColorRect.left = left;
155 | mColorRect.right = right;
156 | canvas.clipRect(mColorRect);
157 |
158 | if (mViewWidth != 0) {
159 | mAlphaBgColor = 100 - (int) (((float) (-mCurMotionX) / (float) mViewWidth) * 120);
160 | }
161 |
162 | if (mAlphaBgColor > 100) {
163 | mAlphaBgColor = 100;
164 | }
165 |
166 | if (mIsFinish) {
167 | mAlphaBgColor = 0;
168 | }
169 |
170 | if (mAlphaBgColor < 0) {
171 | mAlphaBgColor = 0;
172 | }
173 |
174 | canvas.drawARGB(mAlphaBgColor, 0, 0, 0);
175 | }
176 | }
177 |
178 | /**
179 | * 事件拦截操作
180 | */
181 | @Override
182 | public boolean onInterceptTouchEvent(MotionEvent event) {
183 |
184 | if (!mIsSwipeBackEnabled) {
185 | return super.onInterceptTouchEvent(event);
186 | }
187 |
188 | if (mIsFinish || mIsScrolling) {
189 | return super.onInterceptTouchEvent(event);
190 | }
191 |
192 | final int action = event.getAction() & MotionEventCompat.ACTION_MASK;
193 |
194 | if (action == MotionEvent.ACTION_CANCEL
195 | || action == MotionEvent.ACTION_UP) {
196 | endDrag();
197 | return super.onInterceptTouchEvent(event);
198 | }
199 |
200 | switch (action) {
201 | case MotionEvent.ACTION_DOWN:
202 |
203 | int index = MotionEventCompat.getActionIndex(event);
204 | mActivePointerId = MotionEventCompat.getPointerId(event, index);
205 |
206 | if (isInvalidEvent(event, index, mActivePointerId)) {
207 | break;
208 | }
209 |
210 | mLastMotionX = MotionEventCompat.getX(event, index);
211 | mLastMotionY = MotionEventCompat.getY(event, index);
212 | mDownX = MotionEventCompat.getX(event, index);
213 |
214 | break;
215 | case MotionEvent.ACTION_MOVE:
216 |
217 | determineDrag(event);
218 |
219 | break;
220 | }
221 |
222 | return mIsSilding;
223 | }
224 |
225 | @Override
226 | public boolean onTouchEvent(MotionEvent event) {
227 |
228 | if (mIsFinish || mIsScrolling) {
229 | return super.onTouchEvent(event);
230 | }
231 |
232 | if (mVelocityTracker == null) {
233 | mVelocityTracker = VelocityTracker.obtain();
234 | }
235 | mVelocityTracker.addMovement(event);
236 |
237 | switch (event.getAction() & MotionEventCompat.ACTION_MASK) {
238 | case MotionEvent.ACTION_DOWN:
239 |
240 | completeScroll();
241 |
242 | int index = MotionEventCompat.getActionIndex(event);
243 | mActivePointerId = MotionEventCompat.getPointerId(event, index);
244 | mLastMotionX = event.getX();
245 | mDownX = MotionEventCompat.getX(event, index);
246 |
247 | break;
248 | case MotionEvent.ACTION_MOVE:
249 |
250 | if (!mIsSilding) {
251 | determineDrag(event);
252 | }
253 |
254 | if (mIsSilding) {
255 | final int activePointerIndex = getPointerIndex(event,
256 | mActivePointerId);
257 |
258 | if (isInvalidEvent(event, activePointerIndex, mActivePointerId)) {
259 | break;
260 | }
261 |
262 | final float x = MotionEventCompat.getX(event,
263 | activePointerIndex);
264 | final float deltaX = mLastMotionX - x;
265 | mLastMotionX = x;
266 | float oldScrollX = getScrollX();
267 | float scrollX = oldScrollX + deltaX;
268 | final float leftBound = -mViewWidth;
269 | final float rightBound = 0;
270 | if (scrollX < leftBound) {
271 | scrollX = leftBound;
272 | } else if (scrollX > rightBound) {
273 | scrollX = rightBound;
274 | }
275 | mLastMotionX += scrollX - (int) scrollX;
276 | mCurMotionX = (int) scrollX;
277 | mContentView.scrollTo((int) scrollX, getScrollY());
278 | }
279 |
280 | break;
281 | case MotionEvent.ACTION_UP:
282 |
283 | final VelocityTracker velocityTracker = mVelocityTracker;
284 | velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
285 | mXVelocity = velocityTracker.getXVelocity();
286 |
287 | int diffX = getDiffX(event);
288 |
289 | endDrag();
290 |
291 | if (Math.abs(mXVelocity) > mMinimumVelocity && diffX > mFlingDistance) {
292 | if (mXVelocity > 0) {
293 | mIsFinish = true;
294 | scrollRight();
295 | } else {
296 | scrollOrigin();
297 | mIsFinish = false;
298 | }
299 | return true;
300 | }
301 |
302 | if (mContentView.getScrollX() <= -mViewWidth / 2) {
303 | mIsFinish = true;
304 | scrollRight();
305 | } else {
306 | scrollOrigin();
307 | mIsFinish = false;
308 | }
309 | break;
310 |
311 | case MotionEvent.ACTION_CANCEL:
312 | releaseVelocityTracker();
313 | break;
314 | }
315 |
316 | return super.onTouchEvent(event);
317 | }
318 |
319 | private void determineDrag(MotionEvent ev) {
320 | final int activePointerId = mActivePointerId;
321 | final int pointerIndex = getPointerIndex(ev, activePointerId);
322 |
323 | if (isInvalidEvent(ev, pointerIndex, activePointerId)) {
324 | return;
325 | }
326 |
327 | final float x = MotionEventCompat.getX(ev, pointerIndex);
328 | final float dx = x - mLastMotionX;
329 | final float xDiff = Math.abs(dx);
330 | final float y = MotionEventCompat.getY(ev, pointerIndex);
331 | final float dy = y - mLastMotionY;
332 | final float yDiff = Math.abs(dy);
333 | if (dx > 0 && xDiff > mMoveDistance && xDiff > yDiff) {
334 | mIsSilding = true;
335 | mLastMotionX = x;
336 | mLastMotionY = y;
337 | }
338 | }
339 |
340 | private int getDiffX(MotionEvent ev) {
341 | final int activePointerId = mActivePointerId;
342 | final int pointerIndex = getPointerIndex(ev, activePointerId);
343 |
344 | if (isInvalidEvent(ev, pointerIndex, activePointerId)) {
345 | return 0;
346 | }
347 |
348 | final float x = MotionEventCompat.getX(ev, pointerIndex);
349 | final float dx = x - mDownX;
350 | final float xDiff = Math.abs(dx);
351 | return (int) xDiff;
352 | }
353 |
354 | private void endDrag() {
355 | mIsSilding = false;
356 | mActivePointerId = INVALID_POINTER;
357 | releaseVelocityTracker();
358 | }
359 |
360 | private boolean isInvalidEvent(MotionEvent event, int pointerIndex, int pointerId) {
361 |
362 | if (event == null) {
363 | return true;
364 | }
365 |
366 | if (pointerId == INVALID_POINTER || pointerIndex == INVALID_POINTER) {
367 | return true;
368 | }
369 |
370 | if (pointerIndex >= event.getPointerCount()) {
371 | return true;
372 | }
373 |
374 | return false;
375 | }
376 |
377 | @Override
378 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
379 | super.onLayout(changed, l, t, r, b);
380 | if (changed) {
381 | mViewWidth = this.getWidth();
382 | }
383 | }
384 |
385 | private int getPointerIndex(MotionEvent ev, int id) {
386 | int activePointerIndex = MotionEventCompat.findPointerIndex(ev, id);
387 | if (activePointerIndex == -1)
388 | mActivePointerId = INVALID_POINTER;
389 | return activePointerIndex;
390 | }
391 |
392 | /**
393 | * 滚动出界面
394 | */
395 | private void scrollRight() {
396 | mIsScrolling = true;
397 | final int delta = (mViewWidth + mContentView.getScrollX());
398 | mScroller.startScroll(mContentView.getScrollX(), 0, -delta + 1, 0);
399 | postInvalidate();
400 | }
401 |
402 | /**
403 | * 滚动到起始位置
404 | */
405 | private void scrollOrigin() {
406 | mIsScrolling = true;
407 | int delta = mContentView.getScrollX();
408 | mScroller.startScroll(mContentView.getScrollX(), 0, -delta, 0);
409 | postInvalidate();
410 | }
411 |
412 | private void completeScroll() {
413 | boolean needPopulate = mIsScrolling;
414 | if (needPopulate) {
415 | mScroller.abortAnimation();
416 | int oldX = getScrollX();
417 | int oldY = getScrollY();
418 | int x = mScroller.getCurrX();
419 | int y = mScroller.getCurrY();
420 | if (oldX != x || oldY != y) {
421 | mContentView.scrollTo(x, y);
422 | }
423 | }
424 | mIsScrolling = false;
425 | }
426 |
427 | @Override
428 | public void computeScroll() {
429 | if (!mScroller.isFinished() && mScroller.computeScrollOffset()) {
430 |
431 | int oldX = getScrollX();
432 | int oldY = getScrollY();
433 | int x = mScroller.getCurrX();
434 | int y = mScroller.getCurrY();
435 |
436 | if (oldX != x || oldY != y) {
437 | mContentView.scrollTo(x, y);
438 | }
439 |
440 | invalidate();
441 | }
442 |
443 | if (mScroller.isFinished() && mIsFinish) {
444 | mActivity.finish();
445 | mActivity.overridePendingTransition(0, 0);
446 | }
447 |
448 | if (mScroller.isFinished()) {
449 | completeScroll();
450 | }
451 | }
452 |
453 | private void releaseVelocityTracker() {
454 | if (mVelocityTracker != null) {
455 | mVelocityTracker.clear();
456 | mVelocityTracker.recycle();
457 | mVelocityTracker = null;
458 | }
459 | }
460 |
461 | /**
462 | * 是否滑动返回打开
463 | *
464 | * @return
465 | */
466 | public boolean isSwipeBackEnabled() {
467 | return mIsSwipeBackEnabled;
468 | }
469 |
470 | /**
471 | * 设置滑动返回的开关
472 | *
473 | * @param isSwipeBackEnabled
474 | */
475 | public void setSwipeBackEnabled(boolean isSwipeBackEnabled) {
476 | this.mIsSwipeBackEnabled = isSwipeBackEnabled;
477 | }
478 |
479 | /**
480 | * 设置背景为透明
481 | */
482 | public void setBgTransparent() {
483 | if (mRealContentView != null) {
484 | mRealContentView.setBackgroundResource(R.color.transparent);
485 | }
486 | }
487 |
488 | private static class MyAccelerateInterpolator implements Interpolator {
489 |
490 | private final float mFactor;
491 |
492 | public MyAccelerateInterpolator(float factor) {
493 | mFactor = factor;
494 | }
495 |
496 | public float getInterpolation(float input) {
497 | float result = input * (float) mFactor;
498 |
499 | if (result > 0.9) {
500 | result = 1.0f;
501 | }
502 |
503 | return result;
504 | }
505 | }
506 |
507 | /**
508 | * 滑动返回的接口
509 | */
510 | public interface SwipeControlInterface {
511 | /**
512 | * 打开滑动返回
513 | */
514 | public void enableSwipeBack();
515 |
516 | /**
517 | * 关闭滑动返回
518 | */
519 | public void disableSwipeBack();
520 | }
521 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/binioter/widget/TopTitleBar.java:
--------------------------------------------------------------------------------
1 | package com.binioter.widget;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.res.Resources;
6 | import android.content.res.TypedArray;
7 | import android.graphics.drawable.Drawable;
8 | import android.text.TextUtils;
9 | import android.util.AttributeSet;
10 | import android.view.Gravity;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.widget.ImageView;
14 | import android.widget.LinearLayout;
15 | import android.widget.TextView;
16 | import com.binioter.R;
17 | import java.util.ArrayList;
18 | import java.util.LinkedList;
19 | import java.util.List;
20 |
21 | /**
22 | * Created by zb on 2016/7/28.
23 | */
24 | public class TopTitleBar extends LinearLayout implements View.OnClickListener {
25 |
26 | private static final String TAG = TopTitleBar.class.getSimpleName();
27 | //private static final int DEFAULT_TITLE_BAR_HEIGHT = ;
28 | private static final int DEFAULT_LEFT_TEXT_SIZE = 16;
29 | private static final int DEFAULT_MAIN_TEXT_SIZE = 18;
30 | private static final int DEFAULT_SUB_TEXT_SIZE = 12;
31 | private static final int DEFAULT_ACTION_TEXT_SIZE = 16;
32 |
33 | private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";
34 |
35 | private Context mContext;
36 |
37 | private TextView mLeftText;
38 | private LinearLayout mRightLayout;
39 | private LinearLayout mCenterLayout;
40 | private TextView mCenterText;
41 | private TextView mSubTitleText;
42 | private View mDividerView;
43 |
44 | private boolean mImmersive;
45 |
46 | private int mScreenWidth;
47 | private int mStatusBarHeight;
48 | private int mActionPadding;
49 | private int mOutPadding;
50 | private int mMinSidePadding;
51 | private int mMainTextColor;
52 | private int mActionTextColor;
53 | private int mHeight;
54 |
55 | //中间布局是否一直居中,默认是
56 | private boolean isCenterAlways = true;
57 |
58 | /** titlebar中间的标题 */
59 | private String mTitle = "";
60 |
61 | /** titlebar背景色 */
62 | private int mBackground = 0xf9f9f9;
63 |
64 | /** titlebar返回按钮图片 */
65 | private int mBackIconRes = R.mipmap.btn_back_normal;
66 |
67 | /** titlebar返回按钮图片 */
68 | private boolean mDividerVisible = true;
69 |
70 | /** action缓存列表,这里不用弱引用是因为action可能在函数体内部加入,退出函数作用域action就释放了 */
71 | private final List mActionList = new ArrayList<>();
72 |
73 | public TopTitleBar(Context context) {
74 | this(context, null);
75 | }
76 |
77 | public TopTitleBar(Context context, AttributeSet attrs) {
78 | this(context, attrs, 0);
79 | }
80 |
81 | public TopTitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
82 | super(context, attrs, defStyleAttr);
83 | TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.TopTitleBar);
84 | mTitle = typedArray.getString(R.styleable.TopTitleBar_tb_title);
85 | mBackground = typedArray.getColor(R.styleable.TopTitleBar_tb_background,
86 | context.getResources().getColor(R.color.color_f9f9f9));
87 | mBackIconRes =
88 | typedArray.getResourceId(R.styleable.TopTitleBar_tb_back_icon, R.mipmap.btn_back_normal);
89 | mDividerVisible = typedArray.getBoolean(R.styleable.TopTitleBar_tb_divider_visible, true);
90 | typedArray.recycle();
91 | mContext = context;
92 | init(context);
93 | }
94 |
95 | private void init(Context context) {
96 | mScreenWidth = getResources().getDisplayMetrics().widthPixels;
97 | //若是浸没模式,则获取状态栏高度
98 | if (mImmersive) {
99 | mStatusBarHeight = getStatusBarHeight();
100 | } else {
101 | mStatusBarHeight = 0;
102 | }
103 | mOutPadding = dip2px(15); //layout间margin
104 | mActionPadding = dip2px(5); //layout中控件间的padding
105 | mMinSidePadding = dip2px(15); //非恒定居中模式时,左右两边的最小间距
106 | mHeight = context.getResources().getDimensionPixelSize(R.dimen.title_height);
107 | initView(context);
108 | }
109 |
110 | private void initView(Context context) {
111 | setOrientation(HORIZONTAL);
112 | mLeftText = new TextView(context);
113 | mCenterLayout = new LinearLayout(context);
114 | mRightLayout = new LinearLayout(context);
115 | mDividerView = new View(context);
116 |
117 | LayoutParams layoutParams =
118 | new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
119 |
120 | //左布局初始化默认值
121 | setDefaultTextStyle(mLeftText);
122 | mLeftText.setTextSize(DEFAULT_LEFT_TEXT_SIZE);
123 | mLeftText.setPadding(mOutPadding, 0, 0, 0);//有文字或图片加入再重设padding
124 | //mLeftText.setCompoundDrawablePadding(mActionPadding);// add draw padding
125 | //左布局默认实现
126 | mLeftText.setOnClickListener(new View.OnClickListener() {
127 | @Override public void onClick(View view) {
128 | if (null != mContext && mContext instanceof Activity) {
129 | ((Activity) mContext).finish();
130 | }
131 | }
132 | });
133 | //中央布局初始化默认值,默认是主标题+子标题形式
134 | mCenterText = new TextView(context);
135 | mSubTitleText = new TextView(context);
136 | mCenterLayout.addView(mCenterText);
137 | mCenterLayout.addView(mSubTitleText);
138 | mCenterLayout.setGravity(Gravity.CENTER);
139 | setDefaultTextStyle(mCenterText);
140 | setDefaultTextStyle(mSubTitleText);
141 | mCenterText.setTextSize(DEFAULT_MAIN_TEXT_SIZE);
142 | mCenterText.setTextColor(context.getResources().getColor(R.color.color_394043));
143 | mCenterText.setGravity(Gravity.CENTER);
144 | mSubTitleText.setTextSize(DEFAULT_SUB_TEXT_SIZE);
145 | mSubTitleText.setTextColor(context.getResources().getColor(R.color.color_394043));
146 | mSubTitleText.setGravity(Gravity.CENTER);
147 |
148 | //右布局通过addAction动态添加
149 | mRightLayout.setPadding(mOutPadding, 0, 0, 0);
150 |
151 | //底部分割线
152 | mDividerView.setBackgroundColor(context.getResources().getColor(R.color.color_cccccc));
153 |
154 | addView(mLeftText, layoutParams);
155 | addView(mCenterLayout);
156 | addView(mRightLayout, layoutParams);
157 | addView(mDividerView, new LayoutParams(LayoutParams.MATCH_PARENT, 1));
158 | setBackgroundColor(context.getResources().getColor(R.color.color_6b7072));
159 | setTitle(mTitle);
160 | setBackgroundColor(mBackground);
161 | setLeftImageResource(mBackIconRes);
162 | setDividerVisible(mDividerVisible);
163 | }
164 |
165 | /**
166 | * 开启沉浸式,状态栏的高度会增加到title bar的高度中
167 | * java代码中也需要进行设置
168 | */
169 | public void setImmersive(boolean immersive) {
170 | mImmersive = immersive;
171 | if (mImmersive) {
172 | mStatusBarHeight = getStatusBarHeight();
173 | } else {
174 | mStatusBarHeight = 0;
175 | }
176 | }
177 |
178 | public void setHeight(int height) {
179 | mHeight = height;
180 | setMeasuredDimension(getMeasuredWidth(), mHeight);
181 | }
182 |
183 | /**
184 | * 默认文字样式设置
185 | */
186 | private void setDefaultTextStyle(TextView mTextView) {
187 | if (null != mContext) {
188 | mTextView.setTextColor(mContext.getResources().getColor(R.color.color_6b7072));
189 | mTextView.setSingleLine();
190 | mTextView.setGravity(Gravity.CENTER_VERTICAL);
191 | mTextView.setEllipsize(TextUtils.TruncateAt.END);
192 | }
193 | }
194 |
195 | /**
196 | * 左布局设置方法
197 | */
198 | public void setLeftText(CharSequence title) {
199 | if (null == title) {
200 | return;
201 | }
202 | //设置文字和返回按钮间距
203 | mLeftText.setCompoundDrawablePadding(mActionPadding);
204 | mLeftText.setText(title);
205 | adjustLeftTextPadding();
206 | }
207 |
208 | public void setLeftText(int resid) {
209 | //设置文字和返回按钮间距
210 | mLeftText.setCompoundDrawablePadding(mActionPadding);
211 | mLeftText.setText(resid);
212 | }
213 |
214 | public void setLeftImageResource(int resId) {
215 | mLeftText.setCompoundDrawablesWithIntrinsicBounds(resId, 0, 0, 0);
216 | adjustLeftTextPadding();
217 | }
218 |
219 | private void adjustLeftTextPadding() {
220 | mLeftText.setPadding(mOutPadding, 0, mOutPadding, 0);
221 | }
222 |
223 | public void setLeftClickListener(OnClickListener l) {
224 | mLeftText.setOnClickListener(l);
225 | }
226 |
227 | /**
228 | * @param left 单位dp
229 | * @param top 单位dp
230 | * @param right 单位dp
231 | * @param bottom 单位dp
232 | */
233 | public void setLeftTextPadding(int left, int top, int right, int bottom) {
234 | mLeftText.setPadding(dip2px(left), dip2px(top), dip2px(right), dip2px(bottom));
235 | }
236 |
237 | public void setLeftTextBackground(int resId) {
238 | mLeftText.setBackgroundResource(resId);
239 | }
240 |
241 | public void setLeftTextSize(float size) {
242 | mLeftText.setTextSize(size);
243 | }
244 |
245 | public void setLeftTextColor(int color) {
246 | mLeftText.setTextColor(color);
247 | }
248 |
249 | public void setLeftVisible(boolean visible) {
250 | mLeftText.setVisibility(visible ? View.VISIBLE : View.GONE);
251 | }
252 |
253 | /**
254 | * 设置文字标题,是否需要从新添加title,一般来说不需要,除非之前添加过centerview
255 | *
256 | * @param title 标题
257 | */
258 | public void setTitle(CharSequence title) {
259 | setTitle(title, false);
260 | }
261 |
262 | /**
263 | * 中央布局设置方法
264 | *
265 | * @param title 标题
266 | * @param needReAdd 是否需要从新添加,一般来说不需要,除非之前添加过centerview
267 | */
268 | public void setTitle(CharSequence title, boolean needReAdd) {
269 | if (null == title) {
270 | return;
271 | }
272 | if (needReAdd) {
273 | mCenterLayout.removeAllViews();
274 | mCenterLayout.addView(mCenterText);
275 | mCenterLayout.addView(mSubTitleText);
276 | }
277 | //若用换行符分隔文字,则主标题和子标题竖直排列
278 | int index = title.toString().indexOf("\n");
279 | if (index > 0) {
280 | setTitle(title.subSequence(0, index), title.subSequence(index + 1, title.length()),
281 | LinearLayout.VERTICAL);
282 | } else {
283 | //若用制表符分隔文字,则主标题和子标题水平排列
284 | index = title.toString().indexOf("\t");
285 | if (index > 0) {
286 | setTitle(title.subSequence(0, index), " " + title.subSequence(index + 1, title.length()),
287 | LinearLayout.HORIZONTAL);
288 | } else {
289 | mCenterText.setText(title);
290 | mSubTitleText.setVisibility(View.GONE);
291 | }
292 | }
293 | }
294 |
295 | private void setTitle(CharSequence title, CharSequence subTitle, int orientation) {
296 | mCenterLayout.setOrientation(orientation);
297 | mCenterText.setText(title);
298 | mSubTitleText.setText(subTitle);
299 | mSubTitleText.setVisibility(View.VISIBLE);
300 | }
301 |
302 | public void setTitle(int resid) {
303 | setTitle(getResources().getString(resid));
304 | }
305 |
306 | public void setCenterClickListener(OnClickListener l) {
307 | mCenterLayout.setOnClickListener(l);
308 | }
309 |
310 | public void setMainTitleSize(float size) {
311 | mCenterText.setTextSize(size);
312 | }
313 |
314 | public void setMainTitleColor(int color) {
315 | mCenterText.setTextColor(color);
316 | }
317 |
318 | public void setMainTitleBackground(int resid) {
319 | mCenterText.setBackgroundResource(resid);
320 | }
321 |
322 | public void setMainTitleVisible(boolean visible) {
323 | mCenterText.setVisibility(visible ? View.VISIBLE : View.GONE);
324 | }
325 |
326 | public void setSubTitleSize(float size) {
327 | mSubTitleText.setTextSize(size);
328 | }
329 |
330 | public void setSubTitleColor(int color) {
331 | mSubTitleText.setTextColor(color);
332 | }
333 |
334 | public void setSubTitleBackground(int resid) {
335 | mSubTitleText.setBackgroundResource(resid);
336 | }
337 |
338 | public void setSubTitleVisible(boolean visible) {
339 | mSubTitleText.setVisibility(visible ? View.VISIBLE : View.GONE);
340 | }
341 |
342 | /**
343 | * 中央布局设置自定义view,如搜索框等
344 | */
345 | public void setCustomTitleView(View titleView) {
346 | LinearLayout.LayoutParams lp =
347 | new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
348 | ViewGroup.LayoutParams.WRAP_CONTENT);
349 | titleView.setLayoutParams(lp);
350 | mCenterLayout.removeAllViews();
351 | mCenterLayout.addView(titleView);
352 | }
353 |
354 | /**
355 | * 设置中央布局控件可见性
356 | */
357 | public void setCenterViewVisible(int visible) {
358 | mCenterLayout.setVisibility(visible);
359 | }
360 |
361 | /**
362 | * 设置中央布局不居中,紧凑排布
363 | */
364 | public void setIsCenterAlways(boolean isCenterAlways) {
365 | this.isCenterAlways = isCenterAlways;
366 | invalidate();
367 | }
368 |
369 | /**
370 | * 获得布局的真实宽度
371 | */
372 | private int getRealWidth(View view) {
373 | int result = mMinSidePadding;
374 | if (null != view) {
375 | result = (view.getVisibility() == View.GONE) ? mMinSidePadding : view.getMeasuredWidth();
376 | }
377 | return result;
378 | }
379 |
380 | /**
381 | * 底部分割线设置方法
382 | */
383 |
384 | public void setDivider(int resId) {
385 | mDividerView.setBackgroundResource(resId);
386 | }
387 |
388 | public void setDividerColor(int color) {
389 | mDividerView.setBackgroundColor(color);
390 | }
391 |
392 | public void setDividerHeight(int dividerHeight) {
393 | mDividerView.getLayoutParams().height = dividerHeight;
394 | }
395 |
396 | public void setDividerVisible(boolean visible) {
397 | mDividerView.setVisibility(visible ? View.VISIBLE : View.GONE);
398 | }
399 |
400 | /**
401 | *
402 | */
403 | /*public void setActionTextColor(int colorResId) {
404 | mActionTextColor = colorResId;
405 | }*/
406 | @Override public void onClick(View view) {
407 | final Object tag = view.getTag();
408 | if (tag instanceof Action) {
409 | final Action action = (Action) tag;
410 | action.performAction(view);
411 | }
412 | }
413 |
414 | /**
415 | * Adds a list of {@link Action}s.
416 | *
417 | * @param actionList the actions to add
418 | */
419 | public void addActions(ActionList actionList) {
420 | int actions = actionList.size();
421 | for (int i = 0; i < actions; i++) {
422 | addAction(actionList.get(i));
423 | }
424 | }
425 |
426 | /**
427 | * Adds a new {@link Action}.
428 | *
429 | * @param action the action to add
430 | */
431 | public View addAction(Action action) {
432 | final int index = mRightLayout.getChildCount();
433 | return addAction(action, index);
434 | }
435 |
436 | /**
437 | * Adds a new {@link Action} at the specified index.
438 | *
439 | * @param action the action to add
440 | * @param index the position at which to add the action
441 | */
442 | public View addAction(Action action, int index) {
443 | if (null == action) {
444 | return null;
445 | }
446 | mActionList.add(action);
447 | LinearLayout.LayoutParams params =
448 | new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
449 | View view = inflateAction(action);
450 | mRightLayout.addView(view, index, params);
451 | return view;
452 | }
453 |
454 | /**
455 | * Removes all action views from this action bar
456 | */
457 | public void removeAllActions() {
458 | mRightLayout.removeAllViews();
459 | }
460 |
461 | /**
462 | * Remove a action from the action bar.
463 | *
464 | * @param index position of action to remove
465 | */
466 | public void removeActionAt(int index) {
467 | mRightLayout.removeViewAt(index);
468 | }
469 |
470 | /**
471 | * Remove a action from the action bar.
472 | *
473 | * @param action The action to remove
474 | */
475 | public void removeAction(Action action) {
476 | int childCount = mRightLayout.getChildCount();
477 | for (int i = 0; i < childCount; i++) {
478 | View view = mRightLayout.getChildAt(i);
479 | if (view != null) {
480 | final Object tag = view.getTag();
481 | if (tag instanceof Action && tag.equals(action)) {
482 | mRightLayout.removeView(view);
483 | }
484 | }
485 | }
486 | }
487 |
488 | /**
489 | * Returns the number of actions currently registered with the action bar.
490 | *
491 | * @return action count
492 | */
493 | public int getActionCount() {
494 | return mRightLayout.getChildCount();
495 | }
496 |
497 | private View inflateAction(Action action) {
498 | View view = null;
499 | if (action instanceof ImageAction) {
500 | ImageView img = new ImageView(getContext());
501 | img.setImageResource(action.getDrawable());
502 | view = img;
503 | } else if (action instanceof TextAction) {
504 | TextView text = new TextView(getContext());
505 | setDefaultTextStyle(text);
506 | text.setText(action.getText());
507 | text.setTextSize(DEFAULT_ACTION_TEXT_SIZE);
508 | if (((TextAction) action).getColor() != -1) {
509 | text.setTextColor(((TextAction) action).getColor());
510 | }
511 | view = text;
512 | } else if (action instanceof ViewAction) {
513 | view = ((ViewAction) action).getView();
514 | }
515 | if (action.getBackground() != 0) {
516 | view.setBackgroundResource(action.getBackground());
517 | }
518 | view.setPadding(0, 0, mOutPadding, 0);
519 | view.setTag(action);
520 | view.setOnClickListener(this);
521 | return view;
522 | }
523 |
524 | public View getViewByAction(Action action) {
525 | View view = findViewWithTag(action);
526 | return view;
527 | }
528 |
529 | /**
530 | * 设置右边第一个按钮图标
531 | *
532 | * @param drawable 图片资源
533 | */
534 | public void setRightImage(Drawable drawable) {
535 | setRightImage(0, drawable);
536 | }
537 |
538 | /**
539 | * 设置右边按钮图标
540 | *
541 | * @param index 图标位置
542 | * @param drawable 图片资源
543 | */
544 | public void setRightImage(int index, Drawable drawable) {
545 | Action action = mActionList.get(index);
546 | if (null != action) {
547 | View view = getViewByAction(action);
548 | if (null != view && view instanceof ImageView) {
549 | ImageView imageView = (ImageView) view;
550 | imageView.setImageDrawable(drawable);
551 | }
552 | }
553 | }
554 |
555 | @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
556 | int heightMode = MeasureSpec.getMode(heightMeasureSpec);
557 | int height;
558 | if (heightMode != MeasureSpec.EXACTLY) {// 没有指定高度
559 | height = mHeight + mStatusBarHeight;
560 | heightMeasureSpec = MeasureSpec.makeMeasureSpec(mHeight, MeasureSpec.EXACTLY);
561 | } else {// 指定后高度
562 | height = MeasureSpec.getSize(heightMeasureSpec) + mStatusBarHeight;
563 | }
564 |
565 | measureChild(mLeftText, widthMeasureSpec, heightMeasureSpec);
566 | measureChild(mRightLayout, widthMeasureSpec, heightMeasureSpec);
567 |
568 | if (isCenterAlways) {
569 | if (mLeftText.getMeasuredWidth() > mRightLayout.getMeasuredWidth()) {
570 | mCenterLayout.measure(
571 | MeasureSpec.makeMeasureSpec(mScreenWidth - 2 * mLeftText.getMeasuredWidth(),
572 | MeasureSpec.EXACTLY), heightMeasureSpec);
573 | } else {
574 | mCenterLayout.measure(
575 | MeasureSpec.makeMeasureSpec(mScreenWidth - 2 * mRightLayout.getMeasuredWidth(),
576 | MeasureSpec.EXACTLY), heightMeasureSpec);
577 | }
578 | } else {
579 | mCenterLayout.measure(MeasureSpec.makeMeasureSpec(mScreenWidth -
580 | getRealWidth(mLeftText) -
581 | getRealWidth(mRightLayout), MeasureSpec.EXACTLY), heightMeasureSpec);
582 | }
583 |
584 | measureChild(mDividerView, widthMeasureSpec, heightMeasureSpec);
585 | setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height);
586 | }
587 |
588 | @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {
589 | mLeftText.layout(0, mStatusBarHeight, mLeftText.getMeasuredWidth(),
590 | mLeftText.getMeasuredHeight() + mStatusBarHeight);
591 | mRightLayout.layout(mScreenWidth - mRightLayout.getMeasuredWidth(), mStatusBarHeight,
592 | mScreenWidth, mRightLayout.getMeasuredHeight() + mStatusBarHeight);
593 |
594 | if (isCenterAlways) {
595 | if (mLeftText.getMeasuredWidth() > mRightLayout.getMeasuredWidth()) {
596 | mCenterLayout.layout(mLeftText.getMeasuredWidth(), mStatusBarHeight,
597 | mScreenWidth - mLeftText.getMeasuredWidth(), getMeasuredHeight());
598 | } else {
599 | mCenterLayout.layout(mRightLayout.getMeasuredWidth(), mStatusBarHeight,
600 | mScreenWidth - mRightLayout.getMeasuredWidth(), getMeasuredHeight());
601 | }
602 | } else {
603 | mCenterLayout.layout(getRealWidth(mLeftText), mStatusBarHeight,
604 | mScreenWidth - getRealWidth(mRightLayout), getMeasuredHeight());
605 | }
606 |
607 | mDividerView.layout(0, getMeasuredHeight() - mDividerView.getMeasuredHeight(),
608 | getMeasuredWidth(), getMeasuredHeight());
609 | }
610 |
611 | private int dip2px(int dpValue) {
612 | final float scale = Resources.getSystem().getDisplayMetrics().density;
613 | return (int) (dpValue * scale + 0.5f);
614 | }
615 |
616 | /**
617 | * 计算状态栏高度高度 getStatusBarHeight
618 | */
619 | public static int getStatusBarHeight() {
620 | return getInternalDimensionSize(Resources.getSystem(), STATUS_BAR_HEIGHT_RES_NAME);
621 | }
622 |
623 | private static int getInternalDimensionSize(Resources res, String key) {
624 | int result = 0;
625 | int resourceId = res.getIdentifier(key, "dimen", "android");
626 | if (resourceId > 0) {
627 | result = res.getDimensionPixelSize(resourceId);
628 | }
629 | return result;
630 | }
631 |
632 | /**
633 | * A {@link LinkedList} that holds a list of {@link Action}s.
634 | */
635 | @SuppressWarnings("serial") public static class ActionList extends LinkedList {
636 | }
637 |
638 | /**
639 | * Definition of an action that could be performed, along with a icon to
640 | * show.
641 | */
642 | public interface Action {
643 |
644 | String getText();
645 |
646 | int getDrawable();
647 |
648 | void performAction(View view);
649 |
650 | int getBackground();
651 | }
652 |
653 | public static class BaseAction implements Action {
654 | @Override public int getDrawable() {
655 | return 0;
656 | }
657 |
658 | @Override public void performAction(View view) {
659 |
660 | }
661 |
662 | @Override public String getText() {
663 | return null;
664 | }
665 |
666 | @Override public int getBackground() {
667 | return 0;
668 | }
669 | }
670 |
671 | public static class ImageAction extends BaseAction {
672 |
673 | private int mDrawable;
674 |
675 | public ImageAction(int drawable) {
676 | mDrawable = drawable;
677 | }
678 |
679 | @Override public int getDrawable() {
680 | return mDrawable;
681 | }
682 | }
683 |
684 | public static class TextAction extends BaseAction {
685 |
686 | final private String mText;
687 | private int mColor = -1;
688 |
689 | public TextAction(String text) {
690 | mText = text;
691 | }
692 |
693 | public TextAction(String text, int color) {
694 | mText = text;
695 | mColor = color;
696 | }
697 |
698 | @Override public String getText() {
699 | return mText;
700 | }
701 |
702 | public int getColor() {
703 | return mColor;
704 | }
705 | }
706 |
707 | /**
708 | * 低级接口,直接返回view
709 | */
710 | public static class ViewAction extends BaseAction {
711 |
712 | private View mView;
713 |
714 | public ViewAction(View view) {
715 | mView = view;
716 | }
717 |
718 | public View getView() {
719 | return mView;
720 | }
721 | }
722 | }
723 |
724 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_common_dialog_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
20 |
21 |
22 |
27 |
28 |
33 |
34 |
39 |
40 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_flowtag_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
12 |
13 |
19 |
20 |
26 |
27 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tip_textview_activity_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
20 |
21 |
27 |
28 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_base.xml:
--------------------------------------------------------------------------------
1 |
4 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_second.xml:
--------------------------------------------------------------------------------
1 |
4 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/btn_back_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/app/src/main/res/mipmap-xxhdpi/btn_back_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #FFFFFF
5 | #262f3d
6 | #00000000
7 | #be5453
8 | #000000
9 | #222222
10 | #6b7072
11 | #cccccc
12 | #394043
13 | #f9f9f9
14 | #f2f3f5
15 | #00ae66
16 | #3F51B5
17 | #FFFFFF
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 47dp
6 | 20dp
7 | 24dp
8 | 16dp
9 | 14dp
10 | 36dp
11 | 12dp
12 | 10dp
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | CommonApp
3 |
4 | Hello world!
5 | Settings
6 | BaseActivity
7 | CommonDialogActivity
8 | FlowLayoutActivity
9 | TipTextViewActivity
10 | 返回
11 | 弹出tips
12 | 隐藏tips
13 | 我是带动画弹出的tips
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/commonutil/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/commonutil/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | minSdkVersion 11
9 | targetSdkVersion 21
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile fileTree(dir: 'libs', include: ['*.jar'])
23 | compile 'com.android.support:appcompat-v7:25.0.0'
24 | }
25 |
--------------------------------------------------------------------------------
/commonutil/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/zhangbin/Documents/AndroidDevTools/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/commonutil/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/commonutil/src/main/java/com/binioter/util/DensityUtil.java:
--------------------------------------------------------------------------------
1 | package com.binioter.util;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 | import android.view.Surface;
6 | import android.view.WindowManager;
7 | import java.lang.reflect.Field;
8 |
9 | /**
10 | * 创建时间: 2016/11/25 11:22
11 | * 作者: zhangbin
12 | * 描述: 单位转换工具类
13 | */
14 |
15 | public class DensityUtil {
16 | static int displayMetricsWidthPixels;
17 |
18 | /**
19 | * dip转换px
20 | *
21 | * @param context 上下文
22 | * @param dpValue dip值
23 | * @return px值
24 | */
25 |
26 | public static int dip2px(Context context, float dpValue) {
27 | final float scale = UIUtils.getDisplayMetrics(context).density;
28 | return (int) (dpValue * scale + 0.5f);
29 | }
30 |
31 | /**
32 | * px转换dip
33 | *
34 | * @param context 上下文
35 | * @param pxValue px值
36 | * @return dip值
37 | */
38 | public static int px2dip(Context context, float pxValue) {
39 | final float scale = UIUtils.getDisplayMetrics(context).density;
40 | return (int) (pxValue / scale + 0.5f);
41 | }
42 |
43 | public static int getEquipmentWidth(Context context) {
44 | DisplayMetrics metric = new DisplayMetrics();
45 | WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
46 | manager.getDefaultDisplay().getMetrics(metric);
47 | int orientation = manager.getDefaultDisplay().getOrientation();
48 | if (orientation == Surface.ROTATION_90 || orientation == Surface.ROTATION_270) {
49 | displayMetricsWidthPixels = metric.heightPixels; // 屏幕宽度(像素)
50 | } else {
51 | displayMetricsWidthPixels = metric.widthPixels; // 屏幕宽度(像素)
52 | }
53 | return displayMetricsWidthPixels;
54 | }
55 |
56 | /**
57 | * 获取状态栏/通知栏的高度
58 | */
59 | public static int getStatusBarHeight(Context context) {
60 | Class> c = null;
61 | Object obj = null;
62 | Field field = null;
63 | int x = 0, sbar = 0;
64 | try {
65 | c = Class.forName("com.android.internal.R$dimen");
66 | obj = c.newInstance();
67 | field = c.getField("status_bar_height");
68 | x = Integer.parseInt(field.get(obj).toString());
69 | sbar = context.getResources().getDimensionPixelSize(x);
70 | } catch (Exception e1) {
71 | e1.printStackTrace();
72 | }
73 | return sbar;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/commonutil/src/main/java/com/binioter/util/UIUtils.java:
--------------------------------------------------------------------------------
1 | package com.binioter.util;
2 |
3 | import android.content.Context;
4 | import android.content.res.AssetFileDescriptor;
5 | import android.content.res.AssetManager;
6 | import android.content.res.ColorStateList;
7 | import android.content.res.Resources;
8 | import android.graphics.Bitmap;
9 | import android.graphics.Bitmap.Config;
10 | import android.graphics.Canvas;
11 | import android.graphics.Paint;
12 | import android.graphics.PorterDuff.Mode;
13 | import android.graphics.PorterDuffXfermode;
14 | import android.graphics.Rect;
15 | import android.graphics.RectF;
16 | import android.graphics.drawable.Drawable;
17 | import android.util.DisplayMetrics;
18 | import android.view.LayoutInflater;
19 | import android.view.View;
20 | import android.view.ViewGroup;
21 | import java.io.File;
22 | import java.io.FileNotFoundException;
23 | import java.io.FileOutputStream;
24 | import java.io.IOException;
25 |
26 | /**
27 | * 创建时间: 2016/11/18 13:43
28 | * 作者: zhangbin
29 | * 描述: UI工具类
30 | */
31 | public class UIUtils {
32 |
33 | public static View inflate(Context context, int resId) {
34 | return LayoutInflater.from(context).inflate(resId, null);
35 | }
36 |
37 | public static Resources getResources(Context context) {
38 | return context.getResources();
39 | }
40 |
41 | public static String getString(Context context, int resId) {
42 | return getResources(context).getString(resId);
43 | }
44 |
45 | public static String getString(Context context, int id, Object... formatArgs)
46 | throws Resources.NotFoundException {
47 | return getResources(context).getString(id, formatArgs);
48 | }
49 |
50 | /** 获取文字数组 */
51 | public static String[] getStringArray(Context context, int resId) {
52 | return getResources(context).getStringArray(resId);
53 | }
54 |
55 | /** 获取dimen */
56 | public static int getDimens(Context context, int resId) {
57 | return getResources(context).getDimensionPixelSize(resId);
58 | }
59 |
60 | /** 获取drawable */
61 | public static Drawable getDrawable(Context context, int resId) {
62 | return getResources(context).getDrawable(resId);
63 | }
64 |
65 | /** 获取颜色 */
66 | public static int getColor(Context context, int resId) {
67 | return getResources(context).getColor(resId);
68 | }
69 |
70 | /** 获取颜色选择器 */
71 | public static ColorStateList getColorStateList(Context context, int resId) {
72 | return getResources(context).getColorStateList(resId);
73 | }
74 |
75 | public static AssetFileDescriptor openRawResourceFd(Context context, int beep) {
76 | return getResources(context).openRawResourceFd(beep);
77 | }
78 |
79 | public static AssetManager getAssets(Context context) {
80 | return getResources(context).getAssets();
81 | }
82 |
83 | public static DisplayMetrics getDisplayMetrics(Context context) {
84 | return getResources(context).getDisplayMetrics();
85 | }
86 |
87 | public static Bitmap toRoundCorner(Bitmap bitmap, float pixels) {
88 | Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
89 | Canvas canvas = new Canvas(output);
90 |
91 | final int color = 0xff424242;
92 | final Paint paint = new Paint();
93 | final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
94 | final RectF rectF = new RectF(rect);
95 | final float roundPx = pixels;
96 |
97 | paint.setAntiAlias(true);
98 | canvas.drawARGB(0, 0, 0, 0);
99 |
100 | paint.setColor(color);
101 | canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
102 | paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
103 | canvas.drawBitmap(bitmap, rect, rect, paint);
104 |
105 | return output;
106 | }
107 |
108 | public static void saveBitmap2File(Bitmap bm, String fileDir) {
109 | File round_file = new File(fileDir);
110 | if (round_file.exists()) {
111 | round_file.delete();
112 | }
113 |
114 | try {
115 | FileOutputStream out = new FileOutputStream(round_file);
116 | bm.compress(Bitmap.CompressFormat.PNG, 90, out);
117 | out.flush();
118 | out.close();
119 | } catch (FileNotFoundException e) {
120 | // TODO Auto-generated catch block
121 | e.printStackTrace();
122 | } catch (IOException e) {
123 | // TODO Auto-generated catch block
124 | e.printStackTrace();
125 | }
126 | }
127 |
128 | /**
129 | * 直接使用,不用转换View
130 | */
131 | @SuppressWarnings("unchecked") public static T findViewById(View view, int id) {
132 | return (T) view.findViewById(id);
133 | }
134 |
135 | /** 动态设置view的margin */
136 | public static void setMargins(View v, int l, int t, int r, int b) {
137 | if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
138 | ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
139 | p.setMargins(l, t, r, b);
140 | v.requestLayout();
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/commonutil/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/commonutil/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/commonutil/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/commonutil/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/commonutil/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/commonutil/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/commonutil/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/commonutil/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/commonutil/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/commonutil/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/commonutil/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/commonutil/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | CommonUtil
3 |
4 |
--------------------------------------------------------------------------------
/commonutil/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/dialog/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/dialog/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | minSdkVersion 11
9 | targetSdkVersion 21
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile fileTree(dir: 'libs', include: ['*.jar'])
23 | compile 'com.android.support:appcompat-v7:25.0.0'
24 | }
25 |
--------------------------------------------------------------------------------
/dialog/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/zhangbin/Documents/AndroidDevTools/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/dialog/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/dialog/src/main/java/com/binioter/dialog/CustomDialog.java:
--------------------------------------------------------------------------------
1 | package com.binioter.dialog;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.content.DialogInterface;
6 | import android.os.Build;
7 | import android.support.annotation.AnimatorRes;
8 | import android.text.TextUtils;
9 | import android.view.Display;
10 | import android.view.Gravity;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.view.ViewGroup.LayoutParams;
14 | import android.view.Window;
15 | import android.view.WindowManager;
16 | import android.widget.LinearLayout;
17 | import android.widget.TextView;
18 |
19 | /**
20 | * 创建时间: 2016/11/18 13:43
21 | * 作者: zhangbin
22 | * 描述: 自定义dialog
23 | */
24 |
25 | public class CustomDialog extends Dialog {
26 |
27 | public CustomDialog(Context context) {
28 | super(context);
29 | }
30 |
31 | public CustomDialog(Context context, int themeResId) {
32 | super(context, themeResId);
33 | }
34 |
35 | protected CustomDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
36 | super(context, cancelable, cancelListener);
37 | }
38 |
39 | public static class Builder {
40 | private Context mContext;
41 | private String mTitle;
42 | private String mMessage;
43 | private String mLeftBtnText;
44 | private String mRightBtnText;
45 | private View mContentView;
46 | private int mGravity;
47 | private int mAnimation;
48 | private boolean isCancelable;
49 | private OnClickListener mLeftBtnClickListener;
50 | private OnClickListener mRightBtnClickListener;
51 |
52 | public Builder(Context context) {
53 | this.mContext = context;
54 | }
55 |
56 | /**
57 | * 设置提示信息
58 | *
59 | * @param message 提示内容
60 | */
61 | public Builder setMessage(String message) {
62 | this.mMessage = message;
63 | return this;
64 | }
65 |
66 | /**
67 | * 根据资源id设置提示信息
68 | */
69 | public Builder setMessage(int resId) {
70 | this.mMessage = (String) mContext.getText(resId);
71 | return this;
72 | }
73 |
74 | /**
75 | * 根据资源id设置标题
76 | */
77 | public Builder setTitle(int resId) {
78 | this.mTitle = (String) mContext.getText(resId);
79 | return this;
80 | }
81 |
82 | /**
83 | * 设置标题
84 | */
85 |
86 | public Builder setTitle(String title) {
87 | this.mTitle = title;
88 | return this;
89 | }
90 |
91 | /**
92 | * 设置自定义布局
93 | *
94 | * @param v 布局view
95 | */
96 | public Builder setContentView(View v) {
97 | this.mContentView = v;
98 | return this;
99 | }
100 |
101 | /**
102 | * 根据资源id设置自定义布局
103 | *
104 | * @param layoutId 布局id
105 | */
106 | public Builder setContentView(int layoutId) {
107 | this.mContentView = LayoutInflater.from(mContext).inflate(layoutId, null);
108 | return this;
109 | }
110 |
111 | /**
112 | * 点击屏幕dialog是否消失
113 | */
114 | public Builder setCancelable(boolean cancelable) {
115 | this.isCancelable = cancelable;
116 | return this;
117 | }
118 |
119 | /**
120 | * 根据资源id设置左边按钮
121 | *
122 | * @param resId 资源id
123 | * @param listener 点击事件监听
124 | */
125 | public Builder setLeftBtnText(int resId, OnClickListener listener) {
126 | this.mLeftBtnText = (String) mContext.getText(resId);
127 | this.mLeftBtnClickListener = listener;
128 | return this;
129 | }
130 |
131 | /**
132 | * 设置左边按钮
133 | *
134 | * @param leftBtnText 按钮名称
135 | * @param listener 点击事件监听
136 | */
137 | public Builder setLeftBtnText(String leftBtnText, OnClickListener listener) {
138 | this.mLeftBtnText = leftBtnText;
139 | this.mLeftBtnClickListener = listener;
140 | return this;
141 | }
142 |
143 | /**
144 | * 根据资源id设置右边按钮
145 | *
146 | * @param resId 资源id
147 | * @param listener 点击事件监听
148 | */
149 | public Builder setRightBtnText(int resId, OnClickListener listener) {
150 | this.mRightBtnText = (String) mContext.getText(resId);
151 | this.mRightBtnClickListener = listener;
152 | return this;
153 | }
154 |
155 | /**
156 | * 设置右边按钮
157 | *
158 | * @param rightBtnText 按钮名称
159 | * @param listener 点击事件监听
160 | */
161 | public Builder setRightBtnText(String rightBtnText, OnClickListener listener) {
162 | this.mRightBtnText = rightBtnText;
163 | this.mRightBtnClickListener = listener;
164 | return this;
165 | }
166 |
167 | /**
168 | * dialog的位置
169 | *
170 | * @param gravity {@link Gravity }
171 | */
172 | public Builder setGravity(int gravity) {
173 | this.mGravity = gravity;
174 | return this;
175 | }
176 |
177 | /**
178 | * 设置dialog动画
179 | *
180 | * @param animation 动画资源id
181 | */
182 | public Builder setAnimation(@AnimatorRes int animation) {
183 | this.mAnimation = animation;
184 | return this;
185 | }
186 |
187 | /**
188 | * 创建dialog
189 | */
190 | public CustomDialog create() {
191 | LayoutInflater inflater =
192 | (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
193 | //初始化dialog
194 | final CustomDialog dialog = new CustomDialog(mContext, R.style.Dialog);
195 | View layout = inflater.inflate(R.layout.custom_dialog_layout, null);
196 | dialog.addContentView(layout,
197 | new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
198 | // 设置title
199 | if (!TextUtils.isEmpty(mTitle)) {
200 | ((TextView) layout.findViewById(R.id.tv_title)).setText(mTitle);
201 | } else {
202 | layout.findViewById(R.id.tv_title).setVisibility(View.GONE);
203 | }
204 |
205 | // 设置左边按钮
206 | if (TextUtils.isEmpty(mLeftBtnText) || TextUtils.isEmpty(mRightBtnText)) {
207 | //没有左侧按钮
208 | layout.findViewById(R.id.tv_left_btn).setVisibility(View.GONE);
209 | } else {
210 | ((TextView) layout.findViewById(R.id.tv_left_btn)).setText(mLeftBtnText);
211 | if (mLeftBtnClickListener != null) {
212 | (layout.findViewById(R.id.tv_left_btn)).setOnClickListener(new View.OnClickListener() {
213 | public void onClick(View v) {
214 | mLeftBtnClickListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE);
215 | }
216 | });
217 | }
218 | }
219 | //设置右侧按钮一直存在
220 | ((TextView) layout.findViewById(R.id.tv_right_btn)).setText(mRightBtnText);
221 | if (mRightBtnClickListener != null) {
222 | (layout.findViewById(R.id.tv_right_btn)).setOnClickListener(new View.OnClickListener() {
223 | public void onClick(View v) {
224 | mRightBtnClickListener.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
225 | }
226 | });
227 | }
228 |
229 | //设置提示内容
230 | if (mMessage != null) {
231 | ((TextView) layout.findViewById(R.id.tv_message)).setText(mMessage);
232 | } else if (mContentView != null) {
233 | //没有提示内容,设置自定义布局
234 | ((LinearLayout) layout.findViewById(R.id.ll_content)).removeAllViews();
235 | ((LinearLayout) layout.findViewById(R.id.ll_content)).addView(mContentView,
236 | new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
237 | }
238 | Window window = dialog.getWindow();
239 | WindowManager windowManager = window.getWindowManager();
240 | Display display = windowManager.getDefaultDisplay();
241 | WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
242 | lp.width = (int) (display.getWidth() * 0.9); //设置宽度
243 | dialog.getWindow().setAttributes(lp);
244 | window.setGravity(mGravity);
245 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
246 | window.setWindowAnimations(mAnimation);
247 | }
248 | dialog.setCancelable(isCancelable);
249 | dialog.setContentView(layout);
250 | return dialog;
251 | }
252 | }
253 | }
254 |
--------------------------------------------------------------------------------
/dialog/src/main/java/com/binioter/dialog/DialogUtil.java:
--------------------------------------------------------------------------------
1 | package com.binioter.dialog;
2 |
3 | import android.content.Context;
4 | import android.content.DialogInterface;
5 | import android.text.TextUtils;
6 | import android.widget.LinearLayout;
7 |
8 | /**
9 | * 创建时间: 2016/11/18 14:15
10 | * 作者: zhangbin
11 | * 描述: dialog工具类
12 | */
13 |
14 | public class DialogUtil {
15 | /**
16 | * 只有msg和一个按钮
17 | *
18 | * @param context 上下文
19 | * @param msg 提示信息
20 | * @param btn1title 左边按钮名称
21 | * @param mlistener1 左边按钮事件
22 | */
23 | public static CustomDialog createDialogButton(Context context, String msg, String btn1title,
24 | DialogInterface.OnClickListener mlistener1) {
25 | return createDialog(context, null, msg, btn1title, mlistener1, null, null, null);
26 | }
27 |
28 | /**
29 | * 只有msg和两个按钮
30 | *
31 | * @param msg 提示信息
32 | * @param btn1title 左边按钮名称
33 | * @param mlistener1 左边按钮事件
34 | * @param btn2title 右边按钮名称
35 | * @param mlistener2 右边按钮事件
36 | */
37 | public static CustomDialog createDialog2Button(Context context, String msg, String btn1title,
38 | DialogInterface.OnClickListener mlistener1, String btn2title,
39 | DialogInterface.OnClickListener mlistener2) {
40 | return createDialog(context, null, msg, btn1title, mlistener1, btn2title, mlistener2, null);
41 | }
42 |
43 | /**
44 | * 只有title和一个按钮和提示信息
45 | *
46 | * @param title 对话框标题
47 | * @param msg 提示信息
48 | * @param btn1title 左边按钮名称
49 | * @param mlistener1 左边按钮事件
50 | */
51 | public static CustomDialog createDialogMsg(Context context, String title, String msg,
52 | String btn1title, DialogInterface.OnClickListener mlistener1) {
53 | return createDialog(context, title, msg, btn1title, mlistener1, null, null, null);
54 | }
55 |
56 | /**
57 | * 自定义提示信息部分dialog
58 | *
59 | * @param contentView 自定义view
60 | * @param title 对话框标题
61 | * @param btn1title 左边按钮名称
62 | * @param mlistener1 左边按钮事件
63 | * @param btn2title 右边按钮名称
64 | * @param mlistener2 右边按钮事件
65 | */
66 | public static CustomDialog createCustomDialog(Context context, String title,
67 | LinearLayout contentView, String btn1title, DialogInterface.OnClickListener mlistener1,
68 | String btn2title, DialogInterface.OnClickListener mlistener2) {
69 | return createDialog(context, title, null, btn1title, mlistener1, btn2title, mlistener2,
70 | contentView);
71 | }
72 |
73 | /**
74 | * 有title和两个按钮和提示信息
75 | *
76 | * @param title 对话框标题
77 | * @param msg 提示信息
78 | * @param btn1title 左边按钮名称
79 | * @param mlistener1 左边按钮事件
80 | * @param btn2title 右边按钮名称
81 | * @param mlistener2 右边按钮事件
82 | */
83 | public static CustomDialog createDialog2ButtonMsg(Context context, String title, String msg,
84 | String btn1title, DialogInterface.OnClickListener mlistener1, String btn2title,
85 | DialogInterface.OnClickListener mlistener2) {
86 | return createDialog(context, title, msg, btn1title, mlistener1, btn2title, mlistener2, null);
87 | }
88 |
89 | /**
90 | * 有title和两个按钮和自定义view
91 | *
92 | * @param title 对话框标题
93 | * @param msg 提示信息
94 | * @param btn1title 左边按钮名称
95 | * @param mlistener1 左边按钮事件
96 | * @param btn2title 右边按钮名称
97 | * @param mlistener2 右边按钮事件
98 | * @param contentView 自定义view
99 | */
100 | private static CustomDialog createDialog(Context context, String title, String msg,
101 | String btn1title, DialogInterface.OnClickListener mlistener1, String btn2title,
102 | DialogInterface.OnClickListener mlistener2, LinearLayout contentView) {
103 | CustomDialog.Builder builder = new CustomDialog.Builder(context).setTitle(title);
104 | if (!TextUtils.isEmpty(msg)) {
105 | builder.setMessage(msg);
106 | }
107 | if (!TextUtils.isEmpty(btn1title) && !TextUtils.isEmpty(btn2title)) {
108 | builder.setRightBtnText(btn2title, mlistener2);
109 | builder.setLeftBtnText(btn1title, mlistener1);
110 | } else {
111 | builder.setRightBtnText(btn1title, mlistener1);
112 | }
113 | if (null != contentView) {
114 | builder.setContentView(contentView);
115 | }
116 | return builder.create();
117 | }
118 | }
119 |
120 |
--------------------------------------------------------------------------------
/dialog/src/main/res/layout/custom_dialog_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
27 |
28 |
34 |
35 |
36 |
44 |
45 |
46 |
52 |
53 |
61 |
62 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/dialog/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/dialog/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/dialog/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/dialog/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/dialog/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/dialog/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/dialog/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/dialog/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/dialog/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/dialog/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/dialog/src/main/res/values-v5/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
--------------------------------------------------------------------------------
/dialog/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #FFFFFF
7 | #262f3d
8 | #00000000
9 | #be5453
10 | #000000
11 | #222222
12 | #6b7072
13 | #cccccc
14 | #394043
15 | #f9f9f9
16 | #f2f3f5
17 | #00ae66
18 |
19 |
--------------------------------------------------------------------------------
/dialog/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 20dp
4 | 24dp
5 | 16dp
6 | 14dp
7 | 36dp
8 | 12dp
9 | 10dp
10 |
11 |
--------------------------------------------------------------------------------
/dialog/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Dialog
3 | 确定
4 | 取消
5 | 提示 ¬
6 |
7 |
--------------------------------------------------------------------------------
/dialog/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/flowtag/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/flowtag/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "23.0.2"
6 |
7 | defaultConfig {
8 | minSdkVersion 11
9 | targetSdkVersion 21
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile fileTree(include: ['*.jar'], dir: 'libs')
23 | compile 'com.android.support:appcompat-v7:25.0.0'
24 | compile project(':commonutil')
25 | }
26 |
--------------------------------------------------------------------------------
/flowtag/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/zhangbin/Documents/AndroidDevTools/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/flowtag/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/flowtag/src/main/java/com/binioter/flowtag/ColorTag.java:
--------------------------------------------------------------------------------
1 | package com.binioter.flowtag;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 创建时间:2016/09/07 21:25
7 | * 作者:zhangbin
8 | * 描述:彩色标签实体类
9 | */
10 | public class ColorTag implements Serializable {
11 | private static final long serialVersionUID = 8415706975169999471L;
12 | public String text;
13 | public String color;
14 | }
--------------------------------------------------------------------------------
/flowtag/src/main/java/com/binioter/flowtag/ColorTagView.java:
--------------------------------------------------------------------------------
1 | package com.binioter.flowtag;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.drawable.GradientDrawable;
7 | import android.widget.LinearLayout;
8 | import android.widget.TextView;
9 | import com.binioter.util.DensityUtil;
10 |
11 | /**
12 | * 创建时间:2016/09/07 18:43
13 | * 作者:zhangbin
14 | * 描述:彩色标签view
15 | */
16 | public class ColorTagView extends TextView {
17 | private static final String DEFAULT_BACKGROUND_TRANSPARENCY = "26";
18 | private static final String DEFAULT_TEXT_COLOR = "849AAE";
19 | private static final String DEFAULT_BACKGROUND_COLOR = "f0f3f5";
20 |
21 | private float mTextCenterX; //文本中轴线X坐标
22 | private float mTextBaselineY; //文本baseline线Y坐标
23 | private Paint mPaint; //控件画笔
24 | private Paint.FontMetrics mFontMetrics;
25 |
26 | public ColorTagView(Context context, ColorTag colorTag) {
27 | super(context);
28 | //setTypeface(MyApplication.getInstance().typeface);
29 | int textColor = TagUtil.parseColor(colorTag.color, DEFAULT_TEXT_COLOR);//文字颜色
30 | int fillColor = TagUtil.parseColor(DEFAULT_BACKGROUND_TRANSPARENCY + colorTag.color,
31 | DEFAULT_BACKGROUND_COLOR);//背景颜色
32 | GradientDrawable gd = new GradientDrawable();//创建drawable
33 | gd.setColor(fillColor);
34 | gd.setCornerRadius(DensityUtil.dip2px(context, 2));
35 | setTextColor(textColor);
36 | setBackgroundDrawable(gd);
37 | setTextSize(13);
38 | setText(colorTag.text);
39 | setPadding(DensityUtil.dip2px(context, 4), DensityUtil.dip2px(context, 1),
40 | DensityUtil.dip2px(context, 4), DensityUtil.dip2px(context, 1));
41 | LinearLayout.LayoutParams params =
42 | new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
43 | LinearLayout.LayoutParams.WRAP_CONTENT);
44 | setLayoutParams(params);
45 | }
46 |
47 | @Override protected void onDraw(Canvas canvas) {
48 | mPaint = getPaint();
49 | mPaint.setColor(getCurrentTextColor());
50 | mPaint.setTextAlign(Paint.Align.CENTER);
51 | setTextLocation();
52 | canvas.drawText(getText().toString(), mTextCenterX, mTextBaselineY, mPaint);
53 | }
54 |
55 | /**
56 | * 定位文本绘制的位置
57 | */
58 | private void setTextLocation() {
59 | int viewWidth = getWidth();
60 | int viewHeight = getHeight();
61 | mFontMetrics = mPaint.getFontMetrics();
62 | float textCenterVerticalBaselineY =
63 | viewHeight / 2 - mFontMetrics.descent + (mFontMetrics.descent - mFontMetrics.ascent) / 2;
64 | mTextCenterX = (float) viewWidth / 2;
65 | mTextBaselineY = textCenterVerticalBaselineY;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/flowtag/src/main/java/com/binioter/flowtag/FlowLayout.java:
--------------------------------------------------------------------------------
1 | package com.binioter.flowtag;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.util.AttributeSet;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import binitoer.com.flowtag.R;
9 |
10 | /**
11 | * 创建时间: 2016/11/02
12 | * 作者: zhangbin
13 | * 描述: 标签流式布局,支持设置最大行数
14 | */
15 | public class FlowLayout extends ViewGroup {
16 |
17 | private static final int DEFAULT_HORIZONTAL_SPACING = 5;
18 | private static final int DEFAULT_VERTICAL_SPACING = 5;
19 |
20 | private int mVerticalSpacing;
21 | private int mHorizontalSpacing;
22 | private int mLineNum;
23 |
24 | public FlowLayout(Context context) {
25 | super(context);
26 | }
27 |
28 | public FlowLayout(Context context, AttributeSet attrs) {
29 | super(context, attrs);
30 |
31 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FlowLayout);
32 | try {
33 | mHorizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_horizontal_spacing,
34 | DEFAULT_HORIZONTAL_SPACING);
35 | mVerticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_vertical_spacing,
36 | DEFAULT_VERTICAL_SPACING);
37 | mLineNum = a.getInteger(R.styleable.FlowLayout_max_line_count, Integer.MAX_VALUE);
38 | } finally {
39 | a.recycle();
40 | }
41 | }
42 |
43 | /**
44 | * 设置最大行数
45 | */
46 | public void setLineNum(int lineNum) {
47 | mLineNum = lineNum;
48 | }
49 |
50 | /**
51 | * 设置水平间距
52 | */
53 | public void setHorizontalSpacing(int pixelSize) {
54 | mHorizontalSpacing = pixelSize;
55 | }
56 |
57 | /**
58 | * 设置垂直间距
59 | */
60 | public void setVerticalSpacing(int pixelSize) {
61 | mVerticalSpacing = pixelSize;
62 | }
63 |
64 | @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
65 | int myWidth = resolveSize(0, widthMeasureSpec);
66 |
67 | int paddingLeft = getPaddingLeft();
68 | int paddingTop = getPaddingTop();
69 | int paddingRight = getPaddingRight();
70 | int paddingBottom = getPaddingBottom();
71 |
72 | int childLeft = paddingLeft;
73 | int childTop = paddingTop;
74 | int lineNum = 0;
75 |
76 | int lineHeight = 0;
77 |
78 | // Measure each child and put the child to the right of previous child
79 | // if there's enough room for it, otherwise, wrap the line and put the child to next line.
80 | for (int i = 0, childCount = getChildCount(); i < childCount; ++i) {
81 | View child = getChildAt(i);
82 | if (child.getVisibility() != View.GONE) {
83 | measureChild(child, widthMeasureSpec, heightMeasureSpec);
84 | } else {
85 | continue;
86 | }
87 |
88 | int childWidth = child.getMeasuredWidth();
89 | int childHeight = child.getMeasuredHeight();
90 |
91 | lineHeight = Math.max(childHeight, lineHeight);
92 |
93 | if (childLeft + childWidth + paddingRight > myWidth) {
94 | lineNum++;
95 | if (mLineNum > lineNum) {
96 | childLeft = paddingLeft;
97 | childTop += mVerticalSpacing + lineHeight;
98 | lineHeight = childHeight;
99 | }
100 | }
101 | childLeft += childWidth + mHorizontalSpacing;
102 | }
103 |
104 | int wantedHeight = childTop + lineHeight + paddingBottom;
105 |
106 | setMeasuredDimension(myWidth, resolveSize(wantedHeight, heightMeasureSpec));
107 | }
108 |
109 | @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {
110 | int myWidth = r - l;
111 |
112 | int paddingLeft = getPaddingLeft();
113 | int paddingTop = getPaddingTop();
114 | int paddingRight = getPaddingRight();
115 |
116 | int childLeft = paddingLeft;
117 | int childTop = paddingTop;
118 | int lineNum = 0;
119 | int lineHeight = 0;
120 | for (int i = 0, childCount = getChildCount(); i < childCount; ++i) {
121 | View childView = getChildAt(i);
122 |
123 | if (childView.getVisibility() == View.GONE) {
124 | continue;
125 | }
126 |
127 | int childWidth = childView.getMeasuredWidth();
128 | int childHeight = childView.getMeasuredHeight();
129 |
130 | lineHeight = Math.max(childHeight, lineHeight);
131 |
132 | if (childLeft + childWidth + paddingRight > myWidth) {
133 | lineNum++;
134 | if (mLineNum <= lineNum) {
135 | return;
136 | }
137 | childLeft = paddingLeft;
138 | childTop += mVerticalSpacing + lineHeight;
139 | lineHeight = childHeight;
140 | }
141 | childView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
142 | childLeft += childWidth + mHorizontalSpacing;
143 | }
144 | }
145 | }
--------------------------------------------------------------------------------
/flowtag/src/main/java/com/binioter/flowtag/TagUtil.java:
--------------------------------------------------------------------------------
1 | package com.binioter.flowtag;
2 |
3 | import android.graphics.Color;
4 | import android.support.annotation.NonNull;
5 | import android.text.TextUtils;
6 |
7 | /**
8 | * 创建时间: 2016/11/25 11:20
9 | * 作者: zhangbin
10 | * 描述: 标签工具类
11 | */
12 |
13 | public class TagUtil {
14 | /**
15 | * 解析颜色,可以以#开头,也可以不用
16 | *
17 | * @param colorStr 39ac6a
18 | * @param defaultColor 39ac6a
19 | * @return Color.parseColor("39ac6a")
20 | */
21 | public static int parseColor(String colorStr, @NonNull String defaultColor) {
22 | int color;
23 | if (TextUtils.isEmpty(colorStr)) {
24 | colorStr = defaultColor;
25 | }
26 | String prefix = colorStr.startsWith("#") ? "" : "#";
27 | String prefixDef = defaultColor.startsWith("#") ? "" : "#";
28 | try {
29 | color = Color.parseColor(prefix + colorStr);
30 | } catch (Exception ex) {
31 | // 务必正确书写 defaultColor
32 | color = Color.parseColor(prefixDef + defaultColor);
33 | ex.printStackTrace();
34 | }
35 | return color;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/flowtag/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/flowtag/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flowtag/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/flowtag/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flowtag/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/flowtag/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flowtag/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/flowtag/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flowtag/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/flowtag/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flowtag/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/flowtag/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Flowtag
3 |
4 |
--------------------------------------------------------------------------------
/flowtag/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/binIoter/CommonApp/b4e150994e294bad985d2f5a8ec3521fd75a72d1/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue May 31 14:40:08 CST 2016
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-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
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 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':flowtag', ':commonutil', ':dialog', ':tiptextview'
2 |
--------------------------------------------------------------------------------
/tiptextview/src/main/java/com/binioter/tiptextview/TipTextView.java:
--------------------------------------------------------------------------------
1 | package com.binioter.tiptextview;
2 |
3 | import android.animation.AnimatorSet;
4 | import android.animation.ObjectAnimator;
5 | import android.content.Context;
6 | import android.os.Handler;
7 | import android.util.AttributeSet;
8 | import android.widget.TextView;
9 | import com.binioter.util.DensityUtil;
10 |
11 | /**
12 | * 创建时间: 2016/11/28 13:35
13 | * 作者: zhangbin
14 | * 描述: 提示TextView
15 | */
16 | public class TipTextView extends TextView {
17 | /**
18 | * 动画执行时间/毫秒
19 | */
20 | private static final int DURATION_TIME = 400;
21 | /**
22 | * autoTips显示时间/毫秒
23 | */
24 | private static final int SHOW_TIME = 5000;
25 | private static final String TRANSLATIONY = "translationY";
26 | private static final String ALPHA = "alpha";
27 | /**
28 | * 高度
29 | */
30 | private int mHeight = 47;
31 | /**
32 | * tips是否正在显示
33 | */
34 | private boolean mIsShowing;
35 | private Context mContext;
36 |
37 | public TipTextView(Context context) {
38 | super(context);
39 | this.mContext = context;
40 | }
41 |
42 | public TipTextView(Context context, AttributeSet paramAttributeSet) {
43 | super(context, paramAttributeSet);
44 | this.mContext = context;
45 | }
46 |
47 | public TipTextView(Context context, AttributeSet paramAttributeSet, int paramInt) {
48 | super(context, paramAttributeSet, paramInt);
49 | this.mContext = context;
50 | }
51 |
52 | /**
53 | * 显示tips
54 | *
55 | * @param tips 显示文本
56 | */
57 | public void showTips(String tips) {
58 | if (mIsShowing) {
59 | return;
60 | }
61 | setText(tips);
62 | //向下移动动画
63 | ObjectAnimator animTransIn =
64 | ObjectAnimator.ofFloat(this, TRANSLATIONY, 0f, DensityUtil.dip2px(mContext, mHeight));
65 | ObjectAnimator animFadeIn = ObjectAnimator.ofFloat(this, ALPHA, 0f, 1f);
66 | AnimatorSet animSet = new AnimatorSet();
67 | animSet.play(animTransIn).with(animFadeIn);
68 | animSet.setDuration(DURATION_TIME);
69 | animSet.start();
70 | mIsShowing = true;
71 | }
72 |
73 | /**
74 | * 隐藏tips
75 | */
76 | public void hideTips() {
77 | if (!mIsShowing) {
78 | return;
79 | }
80 | //向上移动动画
81 | ObjectAnimator animTransOut =
82 | ObjectAnimator.ofFloat(this, TRANSLATIONY, DensityUtil.dip2px(mContext, mHeight), 0f);
83 | ObjectAnimator animFadeOut = ObjectAnimator.ofFloat(this, ALPHA, 1f, 0f);
84 | AnimatorSet animSet = new AnimatorSet();
85 | animSet.play(animTransOut).with(animFadeOut);
86 | animSet.setDuration(DURATION_TIME);
87 | animSet.start();
88 | mIsShowing = false;
89 | }
90 |
91 | /**
92 | * 显示tips并自动消失
93 | *
94 | * @param tips 显示文本
95 | */
96 | public void showAutoHideTips(String tips) {
97 | showTips(tips);
98 | new Handler().postDelayed(new Runnable() {
99 | @Override public void run() {
100 | hideTips();
101 | }
102 | }, SHOW_TIME);
103 | }
104 |
105 | /**
106 | * 设置标题栏高度
107 | */
108 | public void setHeight(int height) {
109 | this.mHeight = height;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------