Support 'color' attribute in ProgressBarAndroid

Differential Revision: D2625690

fb-gh-sync-id: 34ef656be7ce3304add3fae3e697c6b39b866af1
This commit is contained in:
Alexander Blom 2015-11-06 02:33:32 -08:00 committed by facebook-github-bot-0
parent 6a656a1491
commit a797be6ffd
4 changed files with 99 additions and 28 deletions

View File

@ -54,6 +54,10 @@ var ProgressBarAndroidExample = React.createClass({
<UIExplorerBlock title="Large Inverse ProgressBar"> <UIExplorerBlock title="Large Inverse ProgressBar">
<ProgressBar styleAttr="LargeInverse" /> <ProgressBar styleAttr="LargeInverse" />
</UIExplorerBlock> </UIExplorerBlock>
<UIExplorerBlock title="Large Red ProgressBar">
<ProgressBar styleAttr="Large" color="red" />
</UIExplorerBlock>
</UIExplorerPage> </UIExplorerPage>
); );
}, },

View File

@ -15,7 +15,7 @@ var React = require('React');
var ReactPropTypes = require('ReactPropTypes'); var ReactPropTypes = require('ReactPropTypes');
var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
var createReactNativeComponentClass = require('createReactNativeComponentClass'); var requireNativeComponent = require('requireNativeComponent');
var STYLE_ATTRIBUTES = [ var STYLE_ATTRIBUTES = [
'Horizontal', 'Horizontal',
@ -62,6 +62,10 @@ var ProgressBarAndroid = React.createClass({
* - LargeInverse * - LargeInverse
*/ */
styleAttr: ReactPropTypes.oneOf(STYLE_ATTRIBUTES), styleAttr: ReactPropTypes.oneOf(STYLE_ATTRIBUTES),
/**
* Color of the progress bar.
*/
color: ReactPropTypes.string,
/** /**
* Used to locate this view in end-to-end tests. * Used to locate this view in end-to-end tests.
*/ */
@ -81,12 +85,6 @@ var ProgressBarAndroid = React.createClass({
}, },
}); });
var AndroidProgressBar = createReactNativeComponentClass({ var AndroidProgressBar = requireNativeComponent('AndroidProgressBar', ProgressBarAndroid);
validAttributes: {
...ReactNativeViewAttributes.UIView,
styleAttr: true,
},
uiViewClassName: 'AndroidProgressBar',
});
module.exports = ProgressBarAndroid; module.exports = ProgressBarAndroid;

View File

@ -0,0 +1,68 @@
// Copyright 2004-present Facebook. All Rights Reserved.
package com.facebook.react.views.progressbar;
import javax.annotation.Nullable;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
/**
* Controls an enclosing ProgressBar. Exists so that the ProgressBar can be recreated if
* the style would change.
*/
class ProgressBarContainerView extends FrameLayout {
private @Nullable Integer mColor;
private @Nullable ProgressBar mProgressBar;
public ProgressBarContainerView(Context context) {
super(context);
}
public void setStyle(@Nullable String styleName) {
int style = ReactProgressBarViewManager.getStyleFromString(styleName);
mProgressBar = new ProgressBar(getContext(), null, style);
removeAllViews();
addView(
mProgressBar,
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
}
public void setColor(@Nullable Integer color) {
this.mColor = color;
}
public void apply() {
if (mProgressBar == null) {
throw new JSApplicationIllegalArgumentException("setStyle() not called");
}
setColor(mProgressBar);
}
private void setColor(ProgressBar progressBar) {
Drawable drawable;
if (progressBar.isIndeterminate()) {
drawable = progressBar.getIndeterminateDrawable();
} else {
drawable = progressBar.getProgressDrawable();
}
if (drawable == null) {
return;
}
if (mColor != null) {
drawable.setColorFilter(mColor, PorterDuff.Mode.SRC_IN);
} else {
drawable.clearColorFilter();
}
}
}

View File

@ -11,23 +11,20 @@ package com.facebook.react.views.progressbar;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.uimanager.BaseViewManager; import com.facebook.react.uimanager.BaseViewManager;
import com.facebook.react.uimanager.ReactProp; import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewProps;
/** /**
* Manages instances of ProgressBar. ProgressBar is wrapped in a FrameLayout because the style of * Manages instances of ProgressBar. ProgressBar is wrapped in a ProgressBarContainerView because
* the ProgressBar can only be set in the constructor; whenever the style of a ProgressBar changes, * the style of the ProgressBar can only be set in the constructor; whenever the style of a
* we have to drop the existing ProgressBar (if there is one) and create a new one with the style * ProgressBar changes, we have to drop the existing ProgressBar (if there is one) and create a new
* given. * one with the style given.
*/ */
public class ReactProgressBarViewManager extends public class ReactProgressBarViewManager extends
BaseViewManager<FrameLayout, ProgressBarShadowNode> { BaseViewManager<ProgressBarContainerView, ProgressBarShadowNode> {
/* package */ static final String PROP_STYLE = "styleAttr"; /* package */ static final String PROP_STYLE = "styleAttr";
@ -40,19 +37,18 @@ public class ReactProgressBarViewManager extends
} }
@Override @Override
protected FrameLayout createViewInstance(ThemedReactContext context) { protected ProgressBarContainerView createViewInstance(ThemedReactContext context) {
return new FrameLayout(context); return new ProgressBarContainerView(context);
} }
@ReactProp(name = PROP_STYLE) @ReactProp(name = PROP_STYLE)
public void setStyle(FrameLayout view, @Nullable String styleName) { public void setStyle(ProgressBarContainerView view, @Nullable String styleName) {
final int style = getStyleFromString(styleName); view.setStyle(styleName);
view.removeAllViews(); }
view.addView(
new ProgressBar(view.getContext(), null, style), @ReactProp(name = ViewProps.COLOR, customType = "Color")
new ViewGroup.LayoutParams( public void setColor(ProgressBarContainerView view, @Nullable Integer color) {
ViewGroup.LayoutParams.WRAP_CONTENT, view.setColor(color);
ViewGroup.LayoutParams.WRAP_CONTENT));
} }
@Override @Override
@ -66,10 +62,15 @@ public class ReactProgressBarViewManager extends
} }
@Override @Override
public void updateExtraData(FrameLayout root, Object extraData) { public void updateExtraData(ProgressBarContainerView root, Object extraData) {
// do nothing // do nothing
} }
@Override
protected void onAfterUpdateTransaction(ProgressBarContainerView view) {
view.apply();
}
/* package */ static int getStyleFromString(@Nullable String styleStr) { /* package */ static int getStyleFromString(@Nullable String styleStr) {
if (styleStr == null) { if (styleStr == null) {
throw new JSApplicationIllegalArgumentException( throw new JSApplicationIllegalArgumentException(