2017-06-21 2 views
1

私のReact Nativeアプリ(RN 0.42)にbottom: 0というボタンを描きます。これは、iOSとほとんどのAndroid搭載端末でうまく機能します。しかし、物理的なハードウェアボタンのないAndroidデバイスでは、ボタンバーは自分のボタンのすぐ上の画面に描画されます。React Nativeでハードウェアボタンが描画されているかどうかを確認します

ので:ハードウェアボタンが物理的またはソフトウェアが、この場合、私のレイアウトを調整するために駆動されているかどうかを検出する方法はありますか?それとも、これはReact Nativeのバグですか?これはモーダルダイアログでしか起こらないからですか? enter image description here

ギャラクシーS5:(このデバイスは、実際のハードウェアボタンを持っているので、bottom: 45が多すぎる)

ネクサス(:bottom: 45とハードウェアボタンが画面に描画されている緑色のボタンは、スタイルを持っています):その中にアクセスするので、Androidデバイスは、物理的なボタンを持っているかどうかを判断するためにJavaを使用して enter image description here

答えて

2

それはappears to be easyは私がViewConfiguration.get(context).hasPermanentMenuKey()の結果を返すためにNative Moduleラッパーになるだろうネイティブ反応します。

あなたはdetecthardwareと呼ばれる新しいAndroidのリソースディレクトリ(または適切な他を作成し、あなたのあなたがMainActivityMainApplicationファイルを参照してください同じレベルで、その後、/app/src/main/java/<com.companyname.appname>/フォルダ内の、アンドロイドStudioでネイティブプロジェクトに反応する/androidディレクトリを開くことができます名)。

package com.companyname.appname.detecthardware; 

import com.facebook.react.bridge.ReactApplicationContext; 
import com.facebook.react.bridge.ReactContextBaseJavaModule; 
import com.facebook.react.bridge.Callback; 
import com.facebook.react.bridge.ReactMethod; 

import java.util.List; 

public class DetectHardwareModule extends ReactContextBaseJavaModule { 

    public DetectHardwareModule(ReactApplicationContext reactContext) { 
     super(reactContext); 
    } 

    @Override 
    public String getName() { 
     return "DetectHardware"; 
    } 

    @ReactMethod 
    public void hasHardwareButtons(final Callback callback) { 
     callback.invoke(ViewConfiguration.get(getReactApplicationContext()).hasPermanentMenuKey()); 
    } 
} 

その後DetectHardwarePackage.javaを作成し、これを含める:そのDetectHardwareModule.javaを作成し、これを含める内

package com.companyname.appname.detecthardware; 

import com.facebook.react.ReactPackage; 
import com.facebook.react.bridge.JavaScriptModule; 
import com.facebook.react.bridge.NativeModule; 
import com.facebook.react.bridge.ReactApplicationContext; 
import com.facebook.react.uimanager.ViewManager; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

public class DetectHardwarePackage implements ReactPackage { 
    @Override 
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { 
     List<NativeModule> modules = new ArrayList<>(); 
     modules.add(new DetectHardwareModule(reactContext)); 
     return modules; 
    } 

    @Override 
    public List<Class<? extends JavaScriptModule>> createJSModules() { 
     return Collections.emptyList(); 
    } 

    @Override 
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { 
     return Collections.emptyList(); 
    } 
} 

ごMainApplication.java内には、ようgetPackages 方法を含める必要がありますJavaScriptコードからアクセスできます:

@Override 
protected List<ReactPackage> getPackages() { 
    return Arrays.<ReactPackage>asList(
     new MainReactPackage(), 
     new DetectHardwarePackage() 
    ); 
} 

ここで、React Nativeコンポーネント内で、01をインポートしてくださいはreact-nativeからPlatformに変更されているため、Android上でのみ機能が実行されます。 componentDidMountで:

componentDidMount() { 
    if (Platform.OS === 'android') { 
     NativeModules.DetectHardware.hasHardwareButtons(function(result) { 
      this.setState({hasHardwareButtons: result}) 
     }.bind(this)); 
    } 
} 

そして最後に、あなたのrender関数内で、プラットフォームはAndroidとhasHardwareButtonsであれば0にbottom量を計算することは事実である、そうでない場合は45:

var bottom = (Platform.OS === 'android' && this.state.hasHardwareButtons) ? 0 : 45 
+0

おかげで、これはかなりいいです! –

関連する問題