BaseFloatDailog.java 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. /*
  2. * Copyright (c) 2016, Shanghai YUEWEN Information Technology Co., Ltd.
  3. * All rights reserved.
  4. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  5. *
  6. * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  7. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  8. * Neither the name of Shanghai YUEWEN Information Technology Co., Ltd. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  9. *
  10. * THIS SOFTWARE IS PROVIDED BY SHANGHAI YUEWEN INFORMATION TECHNOLOGY CO., LTD. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  11. *
  12. */
  13. package com.yyrh.ui.floatmenu.customfloat;
  14. import android.animation.Animator;
  15. import android.animation.ValueAnimator;
  16. import android.app.Activity;
  17. import android.content.Context;
  18. import android.content.SharedPreferences;
  19. import android.graphics.PixelFormat;
  20. import android.os.Build;
  21. import android.os.CountDownTimer;
  22. import android.os.Handler;
  23. import android.os.Looper;
  24. import android.util.TypedValue;
  25. import android.view.Gravity;
  26. import android.view.LayoutInflater;
  27. import android.view.MotionEvent;
  28. import android.view.View;
  29. import android.view.WindowManager;
  30. import android.view.animation.Interpolator;
  31. import android.view.animation.LinearInterpolator;
  32. /**
  33. * Created by wengyiming on 2017/8/25.
  34. */
  35. public abstract class BaseFloatDailog {
  36. /**
  37. * 悬浮球 坐落 左 右 标记
  38. */
  39. public static final int LEFT = 0;
  40. public static final int RIGHT = 1;
  41. /**
  42. * 记录 logo 停放的位置,以备下次恢复
  43. */
  44. private static final String LOCATION_X = "hintLocation";
  45. private static final String LOCATION_Y = "locationY";
  46. /**
  47. * 停靠默认位置
  48. */
  49. private int mDefaultLocation = RIGHT;
  50. /**
  51. * 悬浮窗 坐落 位置
  52. */
  53. private int mHintLocation = mDefaultLocation;
  54. /**
  55. * 记录当前手指位置在屏幕上的横坐标值
  56. */
  57. private float mXInScreen;
  58. /**
  59. * 记录当前手指位置在屏幕上的纵坐标值
  60. */
  61. private float mYInScreen;
  62. /**
  63. * 记录手指按下时在屏幕上的横坐标的值
  64. */
  65. private float mXDownInScreen;
  66. /**
  67. * 记录手指按下时在屏幕上的纵坐标的值
  68. */
  69. private float mYDownInScreen;
  70. /**
  71. * 记录手指按下时在小悬浮窗的View上的横坐标的值
  72. */
  73. private float mXInView;
  74. /**
  75. * 记录手指按下时在小悬浮窗的View上的纵坐标的值
  76. */
  77. private float mYinview;
  78. /**
  79. * 记录屏幕的宽度
  80. */
  81. private int mScreenWidth;
  82. /**
  83. * 来自 activity 的 wManager
  84. */
  85. private WindowManager wManager;
  86. /**
  87. * 为 wManager 设置 LayoutParams
  88. */
  89. private WindowManager.LayoutParams wmParams;
  90. /**
  91. * 用于显示在 mActivity 上的 mActivity
  92. */
  93. private Context mActivity;
  94. /**
  95. * 用于 定时 隐藏 logo的定时器
  96. */
  97. private CountDownTimer mHideTimer;
  98. /**
  99. * float menu的高度
  100. */
  101. private Handler mHandler = new Handler(Looper.getMainLooper());
  102. /**
  103. * 悬浮窗左右移动到默认位置 动画的 加速器
  104. */
  105. private Interpolator mLinearInterpolator = new LinearInterpolator();
  106. /**
  107. * 标记是否拖动中
  108. */
  109. private boolean isDraging = false;
  110. /**
  111. * 用于恢复悬浮球的location的属性动画值
  112. */
  113. private int mResetLocationValue;
  114. public boolean isApplictionDialog() {
  115. return isApplictionDialog;
  116. }
  117. private boolean isApplictionDialog = false;
  118. /**
  119. * 这个事件用于处理移动、自定义点击或者其它事情,return true可以保证onclick事件失效
  120. */
  121. private View.OnTouchListener touchListener = new View.OnTouchListener() {
  122. @Override
  123. public boolean onTouch(View v, MotionEvent event) {
  124. switch (event.getAction()) {
  125. case MotionEvent.ACTION_DOWN:
  126. floatEventDown(event);
  127. break;
  128. case MotionEvent.ACTION_MOVE:
  129. floatEventMove(event);
  130. break;
  131. case MotionEvent.ACTION_UP:
  132. case MotionEvent.ACTION_CANCEL:
  133. floatEventUp();
  134. break;
  135. }
  136. return true;
  137. }
  138. };
  139. ValueAnimator valueAnimator = null;
  140. private boolean isExpaned = false;
  141. private View logoView;
  142. private View rightView;
  143. private View leftView;
  144. private GetViewCallback mGetViewCallback;
  145. public Context getContext() {
  146. return mActivity;
  147. }
  148. public static class FloatDialogImp extends BaseFloatDailog {
  149. public FloatDialogImp(Context context, GetViewCallback getViewCallback) {
  150. super(context, getViewCallback);
  151. }
  152. public FloatDialogImp(Context context) {
  153. super(context);
  154. }
  155. @Override
  156. protected View getLeftView(LayoutInflater inflater, View.OnTouchListener touchListener) {
  157. return null;
  158. }
  159. @Override
  160. protected View getRightView(LayoutInflater inflater, View.OnTouchListener touchListener) {
  161. return null;
  162. }
  163. @Override
  164. protected View getLogoView(LayoutInflater inflater) {
  165. return null;
  166. }
  167. @Override
  168. protected void resetLogoViewSize(int hintLocation, View logoView) {
  169. }
  170. @Override
  171. protected void dragingLogoViewOffset(View logoView, boolean isDraging, boolean isResetPosition, float offset) {
  172. }
  173. @Override
  174. protected void shrinkLeftLogoView(View logoView) {
  175. }
  176. @Override
  177. protected void shrinkRightLogoView(View logoView) {
  178. }
  179. @Override
  180. protected void leftViewOpened(View leftView) {
  181. }
  182. @Override
  183. protected void rightViewOpened(View rightView) {
  184. }
  185. @Override
  186. protected void leftOrRightViewClosed(View logoView) {
  187. }
  188. @Override
  189. protected void onDestoryed() {
  190. }
  191. }
  192. protected BaseFloatDailog(Context context, GetViewCallback getViewCallback) {
  193. this(context);
  194. this.mGetViewCallback = getViewCallback;
  195. if (mGetViewCallback == null) {
  196. throw new IllegalArgumentException("GetViewCallback cound not be null!");
  197. }
  198. }
  199. protected BaseFloatDailog(Context context) {
  200. this.mActivity = context;
  201. initFloatWindow();
  202. initTimer();
  203. initFloatView();
  204. }
  205. private void initFloatView() {
  206. LayoutInflater inflater = LayoutInflater.from(mActivity);
  207. logoView = mGetViewCallback == null ? getLogoView(inflater) : mGetViewCallback.getLogoView(inflater);
  208. leftView = mGetViewCallback == null ? getLeftView(inflater, touchListener) : mGetViewCallback.getLeftView(inflater, touchListener);
  209. rightView = mGetViewCallback == null ? getRightView(inflater, touchListener) : mGetViewCallback.getRightView(inflater, touchListener);
  210. if (logoView == null) {
  211. throw new IllegalArgumentException("Must impl GetViewCallback or impl " + this.getClass().getSimpleName() + "and make getLogoView() not return null !");
  212. }
  213. logoView.setOnTouchListener(touchListener);//恢复touch事件
  214. }
  215. /**
  216. * 初始化 隐藏悬浮球的定时器
  217. */
  218. private void initTimer() {
  219. mHideTimer = new CountDownTimer(2000, 10) { //悬浮窗超过5秒没有操作的话会自动隐藏
  220. @Override
  221. public void onTick(long millisUntilFinished) {
  222. if (isExpaned) {
  223. mHideTimer.cancel();
  224. }
  225. }
  226. @Override
  227. public void onFinish() {
  228. if (isExpaned) {
  229. mHideTimer.cancel();
  230. return;
  231. }
  232. if (!isDraging) {
  233. if (mHintLocation == LEFT) {
  234. if (mGetViewCallback == null) {
  235. shrinkLeftLogoView(logoView);
  236. } else {
  237. mGetViewCallback.shrinkLeftLogoView(logoView);
  238. }
  239. } else {
  240. if (mGetViewCallback == null) {
  241. shrinkRightLogoView(logoView);
  242. } else {
  243. mGetViewCallback.shrinkRightLogoView(logoView);
  244. }
  245. }
  246. }
  247. }
  248. };
  249. }
  250. /**
  251. * 初始化悬浮球 window
  252. */
  253. private void initFloatWindow() {
  254. wmParams = new WindowManager.LayoutParams();
  255. if (mActivity instanceof Activity) {
  256. Activity activity = (Activity) mActivity;
  257. wManager = activity.getWindowManager();
  258. //类似dialog,寄托在activity的windows上,activity关闭时需要关闭当前float
  259. wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;
  260. isApplictionDialog = true;
  261. } else {
  262. wManager = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
  263. //判断状态栏是否显示 如果不显示则statusBarHeight为0
  264. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  265. if (Build.VERSION.SDK_INT > 23) {
  266. //在android7.1以上系统需要使用TYPE_PHONE类型 配合运行时权限
  267. wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
  268. } else {
  269. wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
  270. }
  271. } else {
  272. wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
  273. }
  274. isApplictionDialog = false;
  275. }
  276. mScreenWidth = wManager.getDefaultDisplay().getWidth();
  277. int screenHeigth = wManager.getDefaultDisplay().getHeight();
  278. wmParams.format = PixelFormat.RGBA_8888;
  279. wmParams.gravity = Gravity.LEFT | Gravity.TOP;
  280. wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
  281. mHintLocation = getSetting(LOCATION_X, mDefaultLocation);
  282. int defaultY = ((screenHeigth) / 2) / 3;
  283. int y = getSetting(LOCATION_Y, defaultY);
  284. if (mHintLocation == LEFT) {
  285. wmParams.x = 0;
  286. } else {
  287. wmParams.x = mScreenWidth;
  288. }
  289. if (y != 0 && y != defaultY) {
  290. wmParams.y = y;
  291. } else {
  292. wmParams.y = defaultY;
  293. }
  294. wmParams.alpha = 1;
  295. wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
  296. wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
  297. }
  298. /**
  299. * 悬浮窗touch事件的 down 事件
  300. */
  301. private void floatEventDown(MotionEvent event) {
  302. isDraging = false;
  303. mHideTimer.cancel();
  304. if (mGetViewCallback == null) {
  305. resetLogoViewSize(mHintLocation, logoView);
  306. } else {
  307. mGetViewCallback.resetLogoViewSize(mHintLocation, logoView);
  308. }
  309. mXInView = event.getX();
  310. mYinview = event.getY();
  311. mXDownInScreen = event.getRawX();
  312. mYDownInScreen = event.getRawY();
  313. mXInScreen = event.getRawX();
  314. mYInScreen = event.getRawY();
  315. }
  316. /**
  317. * 悬浮窗touch事件的 move 事件
  318. */
  319. private void floatEventMove(MotionEvent event) {
  320. mXInScreen = event.getRawX();
  321. mYInScreen = event.getRawY();
  322. //连续移动的距离超过3则更新一次视图位置
  323. if (Math.abs(mXInScreen - mXDownInScreen) > logoView.getWidth() / 4 || Math.abs(mYInScreen - mYDownInScreen) > logoView.getWidth() / 4) {
  324. wmParams.x = (int) (mXInScreen - mXInView);
  325. wmParams.y = (int) (mYInScreen - mYinview) - logoView.getHeight() / 2;
  326. updateViewPosition(); // 手指移动的时候更新小悬浮窗的位置
  327. double a = mScreenWidth / 2;
  328. float offset = (float) ((a - (Math.abs(wmParams.x - a))) / a);
  329. if (mGetViewCallback == null) {
  330. dragingLogoViewOffset(logoView, isDraging, false, offset);
  331. } else {
  332. mGetViewCallback.dragingLogoViewOffset(logoView, isDraging, false, offset);
  333. }
  334. } else {
  335. isDraging = false;
  336. // logoView.setDraging(false, 0, true);
  337. if (mGetViewCallback == null) {
  338. dragingLogoViewOffset(logoView, false, true, 0);
  339. } else {
  340. mGetViewCallback.dragingLogoViewOffset(logoView, false, true, 0);
  341. }
  342. }
  343. }
  344. /**
  345. * 悬浮窗touch事件的 up 事件
  346. */
  347. private void floatEventUp() {
  348. if (mXInScreen < mScreenWidth / 2) { //在左边
  349. mHintLocation = LEFT;
  350. } else { //在右边
  351. mHintLocation = RIGHT;
  352. }
  353. valueAnimator = ValueAnimator.ofInt(64);
  354. valueAnimator.setInterpolator(mLinearInterpolator);
  355. valueAnimator.setDuration(1000);
  356. valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  357. @Override
  358. public void onAnimationUpdate(ValueAnimator animation) {
  359. mResetLocationValue = (int) animation.getAnimatedValue();
  360. mHandler.post(updatePositionRunnable);
  361. }
  362. });
  363. valueAnimator.addListener(new Animator.AnimatorListener() {
  364. @Override
  365. public void onAnimationStart(Animator animation) {
  366. }
  367. @Override
  368. public void onAnimationEnd(Animator animation) {
  369. if (Math.abs(wmParams.x) < 0) {
  370. wmParams.x = 0;
  371. } else if (Math.abs(wmParams.x) > mScreenWidth) {
  372. wmParams.x = mScreenWidth;
  373. }
  374. updateViewPosition();
  375. isDraging = false;
  376. if (mGetViewCallback == null) {
  377. dragingLogoViewOffset(logoView, false, true, 0);
  378. } else {
  379. mGetViewCallback.dragingLogoViewOffset(logoView, false, true, 0);
  380. }
  381. mHideTimer.start();
  382. }
  383. @Override
  384. public void onAnimationCancel(Animator animation) {
  385. if (Math.abs(wmParams.x) < 0) {
  386. wmParams.x = 0;
  387. } else if (Math.abs(wmParams.x) > mScreenWidth) {
  388. wmParams.x = mScreenWidth;
  389. }
  390. updateViewPosition();
  391. isDraging = false;
  392. if (mGetViewCallback == null) {
  393. dragingLogoViewOffset(logoView, false, true, 0);
  394. } else {
  395. mGetViewCallback.dragingLogoViewOffset(logoView, false, true, 0);
  396. }
  397. mHideTimer.start();
  398. }
  399. @Override
  400. public void onAnimationRepeat(Animator animation) {
  401. }
  402. });
  403. if (!valueAnimator.isRunning()) {
  404. valueAnimator.start();
  405. }
  406. // //这里需要判断如果如果手指所在位置和logo所在位置在一个宽度内则不移动,
  407. if (Math.abs(mXInScreen - mXDownInScreen) > logoView.getWidth() / 5 || Math.abs(mYInScreen - mYDownInScreen) > logoView.getHeight() / 5) {
  408. isDraging = false;
  409. } else {
  410. openMenu();
  411. }
  412. }
  413. /**
  414. * 手指离开屏幕后 用于恢复 悬浮球的 logo 的左右位置
  415. */
  416. private Runnable updatePositionRunnable = new Runnable() {
  417. @Override
  418. public void run() {
  419. isDraging = true;
  420. checkPosition();
  421. }
  422. };
  423. /**
  424. * 用于检查并更新悬浮球的位置
  425. */
  426. private void checkPosition() {
  427. if (wmParams.x > 0 && wmParams.x < mScreenWidth) {
  428. if (mHintLocation == LEFT) {
  429. wmParams.x = wmParams.x - mResetLocationValue;
  430. } else {
  431. wmParams.x = wmParams.x + mResetLocationValue;
  432. }
  433. updateViewPosition();
  434. double a = mScreenWidth / 2;
  435. float offset = (float) ((a - (Math.abs(wmParams.x - a))) / a);
  436. // logoView.setDraging(isDraging, offset, true);
  437. if (mGetViewCallback == null) {
  438. dragingLogoViewOffset(logoView, false, true, 0);
  439. } else {
  440. mGetViewCallback.dragingLogoViewOffset(logoView, isDraging, true, offset);
  441. }
  442. return;
  443. }
  444. if (Math.abs(wmParams.x) < 0) {
  445. wmParams.x = 0;
  446. } else if (Math.abs(wmParams.x) > mScreenWidth) {
  447. wmParams.x = mScreenWidth;
  448. }
  449. if (valueAnimator.isRunning()) {
  450. valueAnimator.cancel();
  451. }
  452. updateViewPosition();
  453. isDraging = false;
  454. }
  455. public void show() {
  456. try {
  457. if (wManager != null && wmParams != null && logoView != null) {
  458. wManager.addView(logoView, wmParams);
  459. }
  460. if (mHideTimer != null) {
  461. mHideTimer.start();
  462. } else {
  463. initTimer();
  464. mHideTimer.start();
  465. }
  466. } catch (Exception e) {
  467. e.printStackTrace();
  468. }
  469. }
  470. /**
  471. * 打开菜单
  472. */
  473. private void openMenu() {
  474. if (isDraging) return;
  475. if (!isExpaned) {
  476. // logoView.setDrawDarkBg(false);
  477. try {
  478. wManager.removeViewImmediate(logoView);
  479. if (mHintLocation == RIGHT) {
  480. wManager.addView(rightView, wmParams);
  481. if (mGetViewCallback == null) {
  482. rightViewOpened(rightView);
  483. } else {
  484. mGetViewCallback.rightViewOpened(rightView);
  485. }
  486. } else {
  487. wManager.addView(leftView, wmParams);
  488. if (mGetViewCallback == null) {
  489. leftViewOpened(leftView);
  490. } else {
  491. mGetViewCallback.leftViewOpened(leftView);
  492. }
  493. }
  494. } catch (Exception e) {
  495. e.printStackTrace();
  496. }
  497. isExpaned = true;
  498. mHideTimer.cancel();
  499. } else {
  500. // logoView.setDrawDarkBg(true);
  501. try {
  502. wManager.removeViewImmediate(mHintLocation == LEFT ? leftView : rightView);
  503. wManager.addView(logoView, wmParams);
  504. if (mGetViewCallback == null) {
  505. leftOrRightViewClosed(logoView);
  506. } else {
  507. mGetViewCallback.leftOrRightViewClosed(logoView);
  508. }
  509. } catch (Exception e) {
  510. e.printStackTrace();
  511. }
  512. isExpaned = false;
  513. mHideTimer.start();
  514. }
  515. }
  516. /**
  517. * 更新悬浮窗在屏幕中的位置。
  518. */
  519. private void updateViewPosition() {
  520. isDraging = true;
  521. try {
  522. if (!isExpaned) {
  523. if (wmParams.y - logoView.getHeight() / 2 <= 0) {
  524. wmParams.y = 25;
  525. isDraging = true;
  526. }
  527. wManager.updateViewLayout(logoView, wmParams);
  528. }
  529. } catch (Exception e) {
  530. e.printStackTrace();
  531. }
  532. }
  533. /**
  534. * 移除所有悬浮窗 释放资源
  535. */
  536. public void dismiss() {
  537. //记录上次的位置logo的停放位置,以备下次恢复
  538. saveSetting(LOCATION_X, mHintLocation);
  539. saveSetting(LOCATION_Y, wmParams.y);
  540. logoView.clearAnimation();
  541. try {
  542. mHideTimer.cancel();
  543. if (isExpaned) {
  544. wManager.removeViewImmediate(mHintLocation == LEFT ? leftView : rightView);
  545. } else {
  546. wManager.removeViewImmediate(logoView);
  547. }
  548. isExpaned = false;
  549. isDraging = false;
  550. if (mGetViewCallback == null) {
  551. onDestoryed();
  552. } else {
  553. mGetViewCallback.onDestoryed();
  554. }
  555. } catch (Exception e) {
  556. e.printStackTrace();
  557. }
  558. }
  559. protected abstract View getLeftView(LayoutInflater inflater, View.OnTouchListener touchListener);
  560. protected abstract View getRightView(LayoutInflater inflater, View.OnTouchListener touchListener);
  561. protected abstract View getLogoView(LayoutInflater inflater);
  562. protected abstract void resetLogoViewSize(int hintLocation, View logoView);//logo恢复原始大小
  563. protected abstract void dragingLogoViewOffset(View logoView, boolean isDraging, boolean isResetPosition, float offset);
  564. protected abstract void shrinkLeftLogoView(View logoView);//logo左边收缩
  565. protected abstract void shrinkRightLogoView(View logoView);//logo右边收缩
  566. protected abstract void leftViewOpened(View leftView);//左菜单打开
  567. protected abstract void rightViewOpened(View rightView);//右菜单打开
  568. protected abstract void leftOrRightViewClosed(View logoView);
  569. protected abstract void onDestoryed();
  570. public interface GetViewCallback {
  571. View getLeftView(LayoutInflater inflater, View.OnTouchListener touchListener);
  572. View getRightView(LayoutInflater inflater, View.OnTouchListener touchListener);
  573. View getLogoView(LayoutInflater inflater);
  574. void resetLogoViewSize(int hintLocation, View logoView);//logo恢复原始大小
  575. void dragingLogoViewOffset(View logoView, boolean isDraging, boolean isResetPosition, float offset);//logo正被拖动,或真在恢复原位
  576. void shrinkLeftLogoView(View logoView);//logo左边收缩
  577. void shrinkRightLogoView(View logoView);//logo右边收缩
  578. void leftViewOpened(View leftView);//左菜单打开
  579. void rightViewOpened(View rightView);//右菜单打开
  580. void leftOrRightViewClosed(View logoView);
  581. void onDestoryed();
  582. }
  583. /**
  584. * 用于保存悬浮球的位置记录
  585. *
  586. * @param key String
  587. * @param defaultValue int
  588. * @return int
  589. */
  590. private int getSetting(String key, int defaultValue) {
  591. try {
  592. SharedPreferences sharedata = mActivity.getSharedPreferences("floatLogo", 0);
  593. return sharedata.getInt(key, defaultValue);
  594. } catch (Exception e) {
  595. e.printStackTrace();
  596. }
  597. return defaultValue;
  598. }
  599. /**
  600. * 用于保存悬浮球的位置记录
  601. *
  602. * @param key String
  603. * @param value int
  604. */
  605. public void saveSetting(String key, int value) {
  606. try {
  607. SharedPreferences.Editor sharedata = mActivity.getSharedPreferences("floatLogo", 0).edit();
  608. sharedata.putInt(key, value);
  609. sharedata.apply();
  610. } catch (Exception e) {
  611. e.printStackTrace();
  612. }
  613. }
  614. public static int dp2Px(float dp, Context mContext) {
  615. return (int) TypedValue.applyDimension(
  616. TypedValue.COMPLEX_UNIT_DIP,
  617. dp,
  618. mContext.getResources().getDisplayMetrics());
  619. }
  620. }