QuadFlask / react-native-naver-map

🗺️naver map for react-native
MIT License
160 stars 143 forks source link

[Android] 커스텀 마커를 이용하여 지웠다가 다시 그렸을 경우에 뷰 깜빡임이 있습니다. #69

Open kimyoungjae96 opened 3 years ago

kimyoungjae96 commented 3 years ago

안녕하세요. 평소에 정말 잘 쓰고 있습니다. 항상 감사드립니다 ^^!

Version of react-native-naver-map libraries

0.0.59

Version of react-native

0.60.5

Platforms you faced the error (IOS or Android or both?)

android

Expected behavior

깜빡임 현상 제거

Actual behavior

마커를 그린 후에 지웠다가 다시 그리게 됐을때 마커 깜빡임 현상이 있습니다.

Tested environment (Emulator? Real Device?)

galaxy m20 실제 기기, 에뮬레이터 둘다 발생

Screen Shot

AnyConv com__1

open stack 버튼을 임시로 값을 바꾸는 버튼으로 바꿔서 마커를 임의로 안보이게 했다가 다시 보이게끔 했습니다.

import 'react-native-gesture-handler';
import React, {useEffect, useState} from 'react'
import NaverMapView, {Align, Circle, Marker, Path, Polygon, Polyline} from "./map";
import {Image, ImageBackground, PermissionsAndroid, Platform, ScrollView, Text, TouchableOpacity, View} from "react-native";
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from "@react-navigation/bottom-tabs";
import {createStackNavigator} from "@react-navigation/stack";

const P0 = {latitude: 37.564362, longitude: 126.977011};
const P1 = {latitude: 37.565051, longitude: 126.978567};
const P2 = {latitude: 37.565383, longitude: 126.976292};
const P4 = {latitude: 37.564834, longitude: 126.977218};
const P5 = {latitude: 37.562834, longitude: 126.976218};

const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();

const App = () => {
    return <NavigationContainer>
        <Stack.Navigator>
            <Stack.Screen name="home" component={HomeScreen}/>
            <Stack.Screen name="stack" component={MapViewScreen2}/>
        </Stack.Navigator>
    </NavigationContainer>
}

const HomeScreen = () =>
    <Tab.Navigator>
        <Tab.Screen name={"map"} component={MapViewScreen}/>
        <Tab.Screen name={"text"} component={TextScreen}/>
    </Tab.Navigator>

const TextScreen = () => {
    return <Text>text</Text>
}

const MapViewScreen = ({navigation}) => {
    const [number, setNumber] = useState(0)
    useEffect(() => {
        requestLocationPermission();
    }, []);

    return <>
        <NaverMapView style={{width: '100%', height: '100%'}}
                      showsMyLocationButton={true}
                      center={{...P0, zoom: 16}}
                      onTouch={e => console.warn('onTouch', JSON.stringify(e.nativeEvent))}
                      onCameraChange={e => console.warn('onCameraChange', JSON.stringify(e))}
                      onMapClick={e => console.warn('onMapClick', JSON.stringify(e))}
                      useTextureView>
            <Marker coordinate={P0} onClick={() => console.warn('onClick! p0')} caption={{text: "test caption", align: Align.Left}}/>
            <Marker coordinate={P1} pinColor="blue" onClick={() => console.warn('onClick! p1')}/>
            <Marker coordinate={P2} pinColor="red" alpha={0.5} onClick={() => console.warn('onClick! p2')}/>
            <Marker coordinate={P4} onClick={() => console.warn('onClick! p4')} image={require("./marker.png")} width={48} height={48}/>
            <Path coordinates={[P0, P1]} onClick={() => console.warn('onClick! path')} width={10}/>
            <Polyline coordinates={[P1, P2]} onClick={() => console.warn('onClick! polyline')}/>
            <Circle coordinate={P0} color={"rgba(255,0,0,0.3)"} radius={200} onClick={() => console.warn('onClick! circle')}/>
            <Polygon coordinates={[P0, P1, P2]} color={`rgba(0, 0, 0, 0.5)`} onClick={() => console.warn('onClick! polygon')}/>
            {number === 0 &&
            <Marker coordinate={P5} onClick={() => console.warn('onClick! p0')}
                    width={96} height={96}>
                <View style={{
                    backgroundColor: 'rgba(255,0,0,0.2)',
                    borderRadius: 80
                }}>
                    <View style={{
                        backgroundColor: 'rgba(0,0,255,0.3)',
                        borderWidth: 2,
                        borderColor: 'black',
                        flexDirection: 'row'
                    }}>
                        <Image source={require("./marker.png")} style={{
                            width: 32,
                            height: 32,
                            backgroundColor: 'rgba(0,0,0,0.2)',
                            resizeMode: 'stretch',
                            borderWidth: 2,
                            borderColor: 'black'
                        }} fadeDuration={0}/>
                        <Text>Image</Text>
                    </View>
                    <ImageBackground source={require("./marker.png")}
                                     style={{width: 64, height: 64}}>
                        <Text>image background</Text>
                    </ImageBackground>
                </View>
            </Marker>
            }
            {number === 1 && <Marker coordinate={P5} onClick={() => console.warn('onClick! p0')}
                                     width={96} height={96}>
                <View style={{
                    backgroundColor: 'rgba(255,0,0,0.2)',
                    borderRadius: 80
                }}>
                    <View style={{
                        backgroundColor: 'rgba(0,0,255,0.3)',
                        borderWidth: 2,
                        borderColor: 'black',
                        flexDirection: 'row'
                    }}>
                        <Image source={require("./marker.png")} style={{
                            width: 32,
                            height: 32,
                            backgroundColor: 'rgba(0,0,0,0.2)',
                            resizeMode: 'stretch',
                            borderWidth: 2,
                            borderColor: 'black'
                        }} fadeDuration={0}/>
                        <Text>Image</Text>
                    </View>
                    <ImageBackground source={require("./marker.png")}
                                     style={{width: 64, height: 64}}>
                        <Text>image background</Text>
                    </ImageBackground>
                </View>
            </Marker>}
        </NaverMapView>
        <TouchableOpacity style={{position: 'absolute', bottom: '10%', right: 8}} onPress={() => { setNumber((number+1)%2)} }>
            <View style={{backgroundColor: 'gray', padding: 4}}>
                <Text style={{color: 'white'}}>open stack</Text>
            </View>
        </TouchableOpacity>
        <Text style={{position: 'absolute', top: '95%', width: '100%', textAlign: 'center'}}>Icon made by Pixel perfect from www.flaticon.com</Text>
    </>
};

const MapViewScreen2 = ({navigation}) => {
    return <View>
        <TouchableOpacity onPress={navigation.goBack}>
            <View style={{backgroundColor: 'gray', padding: 4}}>
                <Text style={{color: 'white'}}>goBack</Text>
            </View>
        </TouchableOpacity>
        <ScrollView style={{width: '100%', height: '100%'}}>
            <Text>scrollGesturesEnabled: default</Text>
            <NaverMapView style={{width: '100%', height: 200}}
                          center={{...P0, zoom: 15}}
                          useTextureView>
                <Marker coordinate={P0}/>
            </NaverMapView>
            {Array.from({length: 20}, (_, i) => i).map(i => <Text key={i}></Text>)}
            <Text>scrollGesturesEnabled</Text>
            <NaverMapView style={{width: '100%', height: 200}}
                          center={{...P0, zoom: 15}}
                          scrollGesturesEnabled
                          useTextureView>
                <Marker coordinate={P0}/>
            </NaverMapView>
            {Array.from({length: 20}, (_, i) => i).map(i => <Text key={i}></Text>)}
            <Text>scrollGesturesEnabled: false</Text>
            <NaverMapView style={{width: '100%', height: 200}}
                          center={{...P0, zoom: 15}}
                          scrollGesturesEnabled={false}
                          useTextureView>
                <Marker coordinate={P0}/>
            </NaverMapView>
            {Array.from({length: 20}, (_, i) => i).map(i => <Text key={i}></Text>)}
        </ScrollView>
    </View>
}

async function requestLocationPermission() {
    if (Platform.OS !== 'android') return;
    try {
        const granted = await PermissionsAndroid.request(
            PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
            {
                title: 'Location Permission',
                message: 'show my location need Location permission',
                buttonNeutral: 'Ask Me Later',
                buttonNegative: 'Cancel',
                buttonPositive: 'OK',
            },
        );
        if (granted === PermissionsAndroid.RESULTS.GRANTED) {
            console.log('You can use the location');
        } else {
            console.log('Location permission denied');
        }
    } catch (err) {
        console.warn(err);
    }
}

export default App;
QuadFlask commented 3 years ago

커스텀 마커를 주기적으로 렌더링을 하고 있는데 더블버퍼링을 쓰던가 해야겠네요;;

dkahdwk commented 2 years ago

@QuadFlask 안드로이드에서 커스텀마커 깜빡거리는 현상 아직도 존재하는데 해결책 찾으셨나요...?

carpediem0804 commented 2 years ago

혹시 해결책 있나요 .....

dkahdwk commented 2 years ago

@carpediem0804 현재는 아래처럼 쓰시면 해결됩니다.

  <NaverMapView
    ...
    useTextureView // (android)깜빡이는 현상해결
  />

위 방법은 react-navigation을 같이쓸때 생기는 이슈방지이지만 이상하게 적용하면 깜빡임이 제어가 되더라구요. (98%정도?)

다만 네이버맵을 쓰는 화면에서 animation 이벤트가 발생하는 부분을 따로 사용하다면, 여전히 깜빡일거에요. 만드신 개발자분이 더 개발을 안하신지 꽤 되고 연락도 안되서 다른 문제점들이 발생할수도있는데 현재 RN naver map 라이브러리는 여기가 유일해서 선택지는 없습니다.

mym0404 commented 3 months ago

안녕하세요, Fabric에서 지원되는 새로운 라이브러리를 개발중에 있으며 아직 초기 단계지만 빠르게 개발할 예정이니 참고해주시면 감사드리겠습니다.