mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-30 22:12:42 +08:00
Release React Native for Android
This is an early release and there are several things that are known not to work if you're porting your iOS app to Android. See the Known Issues guide on the website. We will work with the community to reach platform parity with iOS.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.views.switchviewview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.SwitchCompat;
|
||||
import android.widget.Switch;
|
||||
|
||||
/**
|
||||
* Switch that has its value controlled by JS. Whenever the value of the switch changes, we do not
|
||||
* allow any other changes to that switch until JS sets a value explicitly. This stops the Switch
|
||||
* from changing its value multiple times, when those changes have not been processed by JS first.
|
||||
*/
|
||||
/*package*/ class ReactSwitch extends SwitchCompat {
|
||||
|
||||
private boolean mAllowChange;
|
||||
|
||||
public ReactSwitch(Context context) {
|
||||
super(context);
|
||||
mAllowChange = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(boolean checked) {
|
||||
if (mAllowChange) {
|
||||
mAllowChange = false;
|
||||
super.setChecked(checked);
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void setOn(boolean on) {
|
||||
// If the switch has a different value than the value sent by JS, we must change it.
|
||||
if (isChecked() != on) {
|
||||
super.setChecked(on);
|
||||
}
|
||||
mAllowChange = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.views.switchviewview;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.events.Event;
|
||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||
|
||||
/**
|
||||
* Event emitted by a ReactSwitchManager once a switch is fully switched on/off
|
||||
*/
|
||||
/*package*/ class ReactSwitchEvent extends Event<ReactSwitchEvent> {
|
||||
|
||||
public static final String EVENT_NAME = "topChange";
|
||||
|
||||
private final boolean mIsChecked;
|
||||
|
||||
public ReactSwitchEvent(int viewId, long timestampMs, boolean isChecked) {
|
||||
super(viewId, timestampMs);
|
||||
mIsChecked = isChecked;
|
||||
}
|
||||
|
||||
public boolean getIsChecked() {
|
||||
return mIsChecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventName() {
|
||||
return EVENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getCoalescingKey() {
|
||||
// All switch events for a given view can be coalesced.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(RCTEventEmitter rctEventEmitter) {
|
||||
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
|
||||
}
|
||||
|
||||
private WritableMap serializeEventData() {
|
||||
WritableMap eventData = Arguments.createMap();
|
||||
eventData.putInt("target", getViewTag());
|
||||
eventData.putBoolean("value", getIsChecked());
|
||||
return eventData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
// switchview because switch is a keyword
|
||||
package com.facebook.react.views.switchviewview;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
|
||||
import com.facebook.csslayout.CSSNode;
|
||||
import com.facebook.csslayout.MeasureOutput;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.uimanager.CatalystStylesDiffMap;
|
||||
import com.facebook.react.uimanager.ReactShadowNode;
|
||||
import com.facebook.react.uimanager.SimpleViewManager;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.UIProp;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
|
||||
/**
|
||||
* View manager for {@link ReactSwitch} components.
|
||||
*/
|
||||
public class ReactSwitchManager extends SimpleViewManager<ReactSwitch> {
|
||||
|
||||
private static final String REACT_CLASS = "AndroidSwitch";
|
||||
@UIProp(UIProp.Type.BOOLEAN) public static final String PROP_ENABLED = ViewProps.ENABLED;
|
||||
@UIProp(UIProp.Type.BOOLEAN) public static final String PROP_ON = ViewProps.ON;
|
||||
|
||||
private static class ReactSwitchShadowNode extends ReactShadowNode implements
|
||||
CSSNode.MeasureFunction {
|
||||
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private boolean mMeasured;
|
||||
|
||||
private ReactSwitchShadowNode() {
|
||||
setMeasureFunction(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void measure(CSSNode node, float width, MeasureOutput measureOutput) {
|
||||
if (!mMeasured) {
|
||||
// Create a switch with the default config and measure it; since we don't (currently)
|
||||
// support setting custom switch text, this is fine, as all switches will measure the same
|
||||
// on a specific device/theme/locale combination.
|
||||
ReactSwitch reactSwitch = new ReactSwitch(getThemedContext());
|
||||
final int spec = View.MeasureSpec.makeMeasureSpec(
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
View.MeasureSpec.UNSPECIFIED);
|
||||
reactSwitch.measure(spec, spec);
|
||||
mWidth = reactSwitch.getMeasuredWidth();
|
||||
mHeight = reactSwitch.getMeasuredHeight();
|
||||
mMeasured = true;
|
||||
}
|
||||
measureOutput.width = mWidth;
|
||||
measureOutput.height = mHeight;
|
||||
}
|
||||
}
|
||||
|
||||
private static final CompoundButton.OnCheckedChangeListener ON_CHECKED_CHANGE_LISTENER =
|
||||
new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
ReactContext reactContext = (ReactContext) buttonView.getContext();
|
||||
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(
|
||||
new ReactSwitchEvent(
|
||||
buttonView.getId(),
|
||||
SystemClock.uptimeMillis(),
|
||||
isChecked));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return REACT_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReactShadowNode createCSSNodeInstance() {
|
||||
return new ReactSwitchShadowNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReactSwitch createViewInstance(ThemedReactContext context) {
|
||||
ReactSwitch view = new ReactSwitch(context);
|
||||
view.setShowText(false);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateView(ReactSwitch view, CatalystStylesDiffMap props) {
|
||||
super.updateView(view, props);
|
||||
if (props.hasKey(PROP_ENABLED)) {
|
||||
view.setEnabled(props.getBoolean(PROP_ENABLED, true));
|
||||
}
|
||||
if (props.hasKey(PROP_ON)) {
|
||||
// we set the checked change listener to null and then restore it so that we don't fire an
|
||||
// onChange event to JS when JS itself is updating the value of the switch
|
||||
view.setOnCheckedChangeListener(null);
|
||||
view.setOn(props.getBoolean(PROP_ON, false));
|
||||
view.setOnCheckedChangeListener(ON_CHECKED_CHANGE_LISTENER);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSwitch view) {
|
||||
view.setOnCheckedChangeListener(ON_CHECKED_CHANGE_LISTENER);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user