졸업 프로젝트/React-Native

[React-Native] floating 버튼 구현

ansui 2025. 1. 22. 21:52

react-native-floating-bubble-plugin 

 

위 라이브러리를 이용하여 앱 버튼 클릭 시 floating 버튼이 생성되고 다시 클릭하면 앱이 실행되도록 구현하였다.

 

완성 화면


1️⃣라이브러리 설치

npm install react-native-floating-bubble-plugin --save

 

2️⃣ AndroidManifest.xml 파일에 아래 코드 추가

android > app > src > main > AndroidManifest.xml

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

 

3️⃣ floating 버튼 이미지 추가

아래 경로에 bubble_icon.png 이름으로 이미지를 추가한다.

android > app > src > main > res > drawble > bubble_icon.png

 

4️⃣ 코드 작성

  // 권한 얻기 & 버블 초기화
  useEffect(() => {
    requestPermission()
      .then(() => console.log('Permission Granted'))
      .catch(() => console.log('Permission is not granted'));
    initialize().then(() => console.log('Initialized the bubble'));
  }, []);
  
  // 대화 시작하기 버튼 눌렀을 때 버블 보이기
  const handleStart = async () => {
    await showFloatingBubble(800, 1500).then(() => console.log('Floating Bubble Added'));
  };
  
  // 플로팅 버튼 눌렀을 때 버블 삭제
  DeviceEventEmitter.addListener('floating-bubble-press', (e) => {
    hideFloatingBubble().then(() => console.log('Floating Bubble Removed'));
    console.log('Press Bubble');
  });

 

5️⃣ floating 버블 크기 조정

위치는 showFloatingBubble(x, y)로 조정할 수 있지만 크기를 조절하는 옵션이 없었다.

그래서 node_modules에서 관련 파일을 찾아 코드를 수정하였다.

 

node_modules > react-native-floating-bubble-plugin > android > src > res > layout > bubble_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<com.txusballesteros.bubbles.BubbleLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:contentDescription="NULL">

    <ImageView
        android:id="@+id/avatar"
        android:layout_width="70dp" // 이미지 너비 설정
        android:layout_height="70dp" // 이미지 높이 설정
        android:layout_gravity="center"
        android:src="@drawable/bubble_icon"
        android:scaleType="centerCrop"/>
</com.txusballesteros.bubbles.BubbleLayout>

 위 코드에서 원하는 너비와 높이로 수정을 해주었고 background 이미지도 있었는데 삭제했다.

 

이제 앱 밖에서 floating 버튼 클릭 시 다시 앱으로 실행하는 것을 구현할 것이다.

Deep Link를 사용하였다.

https://reactnavigation.org/docs/deep-linking/?config=static

 

6️⃣ AndroidManifest.xml 파일에 아래 코드 추가

마지막 줄인 scheme은 내가 원하는 앱의 이름을 적어주면 된다.

이 부분이 Linking에서 이동할 때 url의 prefix가 된다.

 

android > app > src > main > AndroidManifest.xml

<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="drivemate" />

 

7️⃣ Navigation으로 linking 했을 때 연결할 화면 설정

App.tsx

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 */

import React from 'react';
import { DefaultTheme, NavigationContainer } from '@react-navigation/native';
import Navigator from './src/navigation/Navigator';
import './src/input.css';

const BodyTheme = {
  ...DefaultTheme,
  colors: {
    ...DefaultTheme.colors,
    background: 'white',
  },
};

function App(): React.JSX.Element {
  return (
    <NavigationContainer
      theme={BodyTheme}
      linking={{
        prefixes: ['drivemate://'],
        config: {
          screens: {
            Main: '', //앱을 실행할 때 이동 지정안하면 navigator의 첫 화면(splash)
            EndChat: 'EndChat', // 딥링크 UL로 이동
          },
        },
      }}
    >
      <Navigator />
    </NavigationContainer>
  );
}

export default App;

 

8️⃣ floating 버튼 클릭 시 앱 실행 후 화면 연결하는 코드 추가

  // 플로팅 버튼 눌렀을 때
  DeviceEventEmitter.addListener('floating-bubble-press', (e) => {
    Linking.openURL('drivemate://EndChat');
    hideFloatingBubble().then(() => console.log('Floating Bubble Removed'));
  });

 


이런 기능은 한번도 구현해본 적이 없어서 어려웠다.

블로그 자료도 많이 없고 라이브러리도 오래된 것 뿐이어서 많이 찾고 ChatGpt도 사용하였다...

아직 floating 버튼 생성 시 앱을 background로 이동시키고 휴대폰 홈화면으로 이동하는 부분은 구현을 하지 않아서 앞으로 구현해야 한다. 아마도 react-native-background-actions 라이브러리를 사용할 것 같다.