Skip to content

Commit a797be6

Browse files
lexsfacebook-github-bot-0
authored andcommitted
Support 'color' attribute in ProgressBarAndroid
Differential Revision: D2625690 fb-gh-sync-id: 34ef656be7ce3304add3fae3e697c6b39b866af1
1 parent 6a656a1 commit a797be6

4 files changed

Lines changed: 99 additions & 28 deletions

File tree

Examples/UIExplorer/ProgressBarAndroidExample.android.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ var ProgressBarAndroidExample = React.createClass({
5454
<UIExplorerBlock title="Large Inverse ProgressBar">
5555
<ProgressBar styleAttr="LargeInverse" />
5656
</UIExplorerBlock>
57+
58+
<UIExplorerBlock title="Large Red ProgressBar">
59+
<ProgressBar styleAttr="Large" color="red" />
60+
</UIExplorerBlock>
5761
</UIExplorerPage>
5862
);
5963
},

Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var React = require('React');
1515
var ReactPropTypes = require('ReactPropTypes');
1616
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
1717

18-
var createReactNativeComponentClass = require('createReactNativeComponentClass');
18+
var requireNativeComponent = require('requireNativeComponent');
1919

2020
var STYLE_ATTRIBUTES = [
2121
'Horizontal',
@@ -62,6 +62,10 @@ var ProgressBarAndroid = React.createClass({
6262
* - LargeInverse
6363
*/
6464
styleAttr: ReactPropTypes.oneOf(STYLE_ATTRIBUTES),
65+
/**
66+
* Color of the progress bar.
67+
*/
68+
color: ReactPropTypes.string,
6569
/**
6670
* Used to locate this view in end-to-end tests.
6771
*/
@@ -81,12 +85,6 @@ var ProgressBarAndroid = React.createClass({
8185
},
8286
});
8387

84-
var AndroidProgressBar = createReactNativeComponentClass({
85-
validAttributes: {
86-
...ReactNativeViewAttributes.UIView,
87-
styleAttr: true,
88-
},
89-
uiViewClassName: 'AndroidProgressBar',
90-
});
88+
var AndroidProgressBar = requireNativeComponent('AndroidProgressBar', ProgressBarAndroid);
9189

9290
module.exports = ProgressBarAndroid;
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2004-present Facebook. All Rights Reserved.
2+
3+
package com.facebook.react.views.progressbar;
4+
5+
import javax.annotation.Nullable;
6+
7+
import android.content.Context;
8+
import android.graphics.PorterDuff;
9+
import android.graphics.drawable.Drawable;
10+
import android.view.ViewGroup;
11+
import android.widget.FrameLayout;
12+
import android.widget.ProgressBar;
13+
14+
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
15+
16+
/**
17+
* Controls an enclosing ProgressBar. Exists so that the ProgressBar can be recreated if
18+
* the style would change.
19+
*/
20+
class ProgressBarContainerView extends FrameLayout {
21+
private @Nullable Integer mColor;
22+
private @Nullable ProgressBar mProgressBar;
23+
24+
public ProgressBarContainerView(Context context) {
25+
super(context);
26+
}
27+
28+
public void setStyle(@Nullable String styleName) {
29+
int style = ReactProgressBarViewManager.getStyleFromString(styleName);
30+
mProgressBar = new ProgressBar(getContext(), null, style);
31+
removeAllViews();
32+
addView(
33+
mProgressBar,
34+
new ViewGroup.LayoutParams(
35+
ViewGroup.LayoutParams.WRAP_CONTENT,
36+
ViewGroup.LayoutParams.WRAP_CONTENT));
37+
}
38+
39+
public void setColor(@Nullable Integer color) {
40+
this.mColor = color;
41+
}
42+
43+
public void apply() {
44+
if (mProgressBar == null) {
45+
throw new JSApplicationIllegalArgumentException("setStyle() not called");
46+
}
47+
setColor(mProgressBar);
48+
}
49+
50+
private void setColor(ProgressBar progressBar) {
51+
Drawable drawable;
52+
if (progressBar.isIndeterminate()) {
53+
drawable = progressBar.getIndeterminateDrawable();
54+
} else {
55+
drawable = progressBar.getProgressDrawable();
56+
}
57+
58+
if (drawable == null) {
59+
return;
60+
}
61+
62+
if (mColor != null) {
63+
drawable.setColorFilter(mColor, PorterDuff.Mode.SRC_IN);
64+
} else {
65+
drawable.clearColorFilter();
66+
}
67+
}
68+
}

ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.java

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,20 @@
1111

1212
import javax.annotation.Nullable;
1313

14-
import android.view.ViewGroup;
15-
import android.widget.FrameLayout;
16-
import android.widget.ProgressBar;
17-
1814
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
1915
import com.facebook.react.uimanager.BaseViewManager;
2016
import com.facebook.react.uimanager.ReactProp;
2117
import com.facebook.react.uimanager.ThemedReactContext;
18+
import com.facebook.react.uimanager.ViewProps;
2219

2320
/**
24-
* Manages instances of ProgressBar. ProgressBar is wrapped in a FrameLayout because the style of
25-
* the ProgressBar can only be set in the constructor; whenever the style of a ProgressBar changes,
26-
* we have to drop the existing ProgressBar (if there is one) and create a new one with the style
27-
* given.
21+
* Manages instances of ProgressBar. ProgressBar is wrapped in a ProgressBarContainerView because
22+
* the style of the ProgressBar can only be set in the constructor; whenever the style of a
23+
* ProgressBar changes, we have to drop the existing ProgressBar (if there is one) and create a new
24+
* one with the style given.
2825
*/
2926
public class ReactProgressBarViewManager extends
30-
BaseViewManager<FrameLayout, ProgressBarShadowNode> {
27+
BaseViewManager<ProgressBarContainerView, ProgressBarShadowNode> {
3128

3229
/* package */ static final String PROP_STYLE = "styleAttr";
3330

@@ -40,19 +37,18 @@ public String getName() {
4037
}
4138

4239
@Override
43-
protected FrameLayout createViewInstance(ThemedReactContext context) {
44-
return new FrameLayout(context);
40+
protected ProgressBarContainerView createViewInstance(ThemedReactContext context) {
41+
return new ProgressBarContainerView(context);
4542
}
4643

4744
@ReactProp(name = PROP_STYLE)
48-
public void setStyle(FrameLayout view, @Nullable String styleName) {
49-
final int style = getStyleFromString(styleName);
50-
view.removeAllViews();
51-
view.addView(
52-
new ProgressBar(view.getContext(), null, style),
53-
new ViewGroup.LayoutParams(
54-
ViewGroup.LayoutParams.WRAP_CONTENT,
55-
ViewGroup.LayoutParams.WRAP_CONTENT));
45+
public void setStyle(ProgressBarContainerView view, @Nullable String styleName) {
46+
view.setStyle(styleName);
47+
}
48+
49+
@ReactProp(name = ViewProps.COLOR, customType = "Color")
50+
public void setColor(ProgressBarContainerView view, @Nullable Integer color) {
51+
view.setColor(color);
5652
}
5753

5854
@Override
@@ -66,10 +62,15 @@ public Class<ProgressBarShadowNode> getShadowNodeClass() {
6662
}
6763

6864
@Override
69-
public void updateExtraData(FrameLayout root, Object extraData) {
65+
public void updateExtraData(ProgressBarContainerView root, Object extraData) {
7066
// do nothing
7167
}
7268

69+
@Override
70+
protected void onAfterUpdateTransaction(ProgressBarContainerView view) {
71+
view.apply();
72+
}
73+
7374
/* package */ static int getStyleFromString(@Nullable String styleStr) {
7475
if (styleStr == null) {
7576
throw new JSApplicationIllegalArgumentException(

0 commit comments

Comments
 (0)