일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 보일러절약
- 괌 신혼여행
- 메이플스토리
- Android
- 방울토마토 씨부터 키우기
- 괌맛집
- 다이소 방울토마토키트
- 다이소 방울토마토
- 쿠폰나눔
- 방울토마토 유기농
- 에어팟충전기
- 신혼여행
- 맥세이프충전기
- 방울토마토키우기
- 스투키
- 괌
- 2in1무선충전기
- 어플만들기
- 집에서 방울토마토 키우기
- 메이플
- Ender 3 V3 KE
- 메이플스토리M
- 안방농사
- 집 방울토마토
- 휴대용무선충전기
- 핫엔드
- 방토 농사
- 겨울나기
- 다크나이트
- 안드로이드
Archives
- Today
- Total
괴도군의 블로그
[android]네이버 퀵메뉴만들기(바탕화면 플로팅버튼) 본문
반응형
안녕하세요 괴도입니다.
오늘은 네이버 퀵메뉴같은 어플종료와 상관없이 떠있는 버튼을 만들어보겠습니다.
프로젝트 구조는 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override protected void onResume() { super.onResume(); stopService(new Intent(this, FloatWindow.class)); } @Override protected void onPause() { super.onPause(); startService(new Intent(this, FloatWindow.class)); } } |
메인은 별거없습니다.. 화면도 기본화면이고..
앱 종료시나 가운데버튼으로 잠시 내릴때에 서비스 실행하는 코드입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | public class FloatWindow extends Service { private Context context; private boolean flagClick; private boolean flagView; private FloatView testView; private View inflateView; private WindowManager wm; private WindowManager.LayoutParams params; private WindowManager.LayoutParams floatWindowParams; private int start_x; private int start_y; private int prev_x; private int prev_y; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); context = this; testView = new FloatView(this); testView.setOnTouchListener(onTouchListener); params = new WindowManager.LayoutParams( 70, 70, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, //터치 인식 PixelFormat.TRANSLUCENT); //투명 params.gravity = Gravity.LEFT | Gravity.TOP; wm = (WindowManager) getSystemService(WINDOW_SERVICE); wm.addView(testView, params); inflateView = View.inflate(this, R.layout.floatwindow, null); floatWindowParams = new WindowManager.LayoutParams( WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, //터치 인식 PixelFormat.TRANSLUCENT); //투명 } private View.OnTouchListener onTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { flagClick = true; int x = (int) event.getRawX(); int y = (int) event.getRawY(); start_x = x; start_y = y; prev_x = params.x; prev_y = params.y; } break; case MotionEvent.ACTION_MOVE: { flagClick = false; int x = (int) (event.getRawX() - start_x); //이동한 거리 int y = (int) (event.getRawY() - start_y); //이동한 거리 params.x = prev_x + x; params.y = prev_y + y; wm.updateViewLayout(testView, params); } break; case MotionEvent.ACTION_UP: { if (flagClick) { floatWindowParams.x = params.x + 70; floatWindowParams.y = params.y - 50; Log.v("@@@@@@@@@", "@@@@@@ floatWindowParams.x: " + floatWindowParams.x + " floatWindowParams.y: " + floatWindowParams.y); inflateView = View.inflate(context, R.layout.floatwindow, null); inflateView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(inflateView); inflateView = null; } }); Button btn = (Button) inflateView.findViewById(R.id.btnend); btn.setX(floatWindowParams.x); btn.setY(floatWindowParams.y + 50); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onDestroy(); if (inflateView != null) //서비스 종료시 뷰 제거. *중요 : 뷰를 꼭 제거 해야함. { ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(inflateView); inflateView = null; } } }); Button bt = (Button) inflateView.findViewById(R.id.btn); bt.setX(floatWindowParams.x); bt.setY(floatWindowParams.y); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = context.getPackageManager().getLaunchIntentForPackage("com.nhn.android.search"); if (intent != null) { context.startActivity(intent); } if (inflateView != null) //서비스 종료시 뷰 제거. *중요 : 뷰를 꼭 제거 해야함. { ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(inflateView); inflateView = null; } } }); wm.addView(inflateView, floatWindowParams); flagView = true; } } } return false; } }; @Override public void onDestroy() { super.onDestroy(); if (testView != null) //서비스 종료시 뷰 제거. *중요 : 뷰를 꼭 제거 해야함. { ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(testView); testView = null; } if (inflateView != null) //서비스 종료시 뷰 제거. *중요 : 뷰를 꼭 제거 해야함. { if (flagView) { ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(inflateView); } inflateView = null; } stopSelf(); } |
서비스 클래스 입니다.
onCreate()시에 View를 생성하고 WindowManager에 addView하는 형식입니다.
터치리스너안에 코드가 더러워서.. 리팩토링이 필요하긴 합니다...
버튼을 누르고 움직일때는 클릭이 아니기때문에 업 이벤트시에 모든걸 처리합니다.
버튼을 눌렀을때 메뉴가 어떻게 나올지 고민을 하다가..
그냥 전체화면 dim처리하고.. 버튼위치로 메뉴위치정해서 옆에 나오게끔 해놨습니다.
그리고 서비스 종료시에는.. 메뉴화면이나 버튼뷰를 삭제시켜야 하기때문에..
onDestroy()에 코드를 넣어놨습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class FloatView extends View { public FloatView(Context context) { super(context); } public FloatView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setColor(Color.BLUE); canvas.drawOval(new RectF(0,0,70,70),paint); } } | cs |
버튼을 만들 뷰는.. 그냥 원하나 그립니다..ㅎㅎ
디자인을 수정하실분은 여기서 하시거나..
xml로 구성하셔서 view추가하시면 될듯합니다.
어디까지나 샘플.. 공부용이기 때문에.. 간단합니다
아참..
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
이 권한이 필요한데
target version을 23 (마쉬멜로우)으로 하시면
권한을 받아오는 코드를 해줘야하니..
22 이하로 하시기 바랍니다.
프로젝트도 첨부합니다.
안드로이드 스튜디오 버전입니다.
반응형
'#프로그래밍 > Android' 카테고리의 다른 글
[Android] 폰/태블릿 구분코드 (Phone/Tablet device code) (0) | 2016.04.08 |
---|---|
[Android] onConfigurationChanged() 호출이 안될때 / 화면회전시 onc (0) | 2016.04.08 |
[Android] 핸드폰에 저장된 wifi 비밀번호 알아내기(루팅x) (6) | 2016.03.14 |
[Android] GCM HTTP 테스트하기 / 구현하기 (2016 최신) (8) | 2016.01.29 |
[android] 리스트뷰 갱신하는 방법 (0) | 2016.01.29 |
Comments