Env:
Wrong Example on Android:
![android](https://user-images.githubusercontent.com/3890570/41461557-a445dfd2-70c2-11e8-8ec4-9c4d57c25a69.png)
Normal Example on iOS:
![ios](https://user-images.githubusercontent.com/3890570/41461588-b5aad00c-70c2-11e8-954f-578179c57ba0.png)
When percentage is less than 50, the circle is wrong.
I thought it might be caused by overflow
on Android, and I found an known issue in [email protected] described as below:
overflow样式在Android默认为hidden而且无法更改
这是Android本身的渲染机制所致。我们没有实现这一特性,因为这是个大工程,而且我们还有很多其他重要的任务。
Android的overflow:hidden还有另外一个问题:如果父容器有borderRadius圆角边框样式,那么即便开启了overflow:hidden也仍然无法把子视图超出圆角边框的部分裁切掉。这个问题只存在于Android上,iOS并没有这个问题(子视图的内容不会超出父容器的圆角边框)。你可以在这里看到问题的演示,以及在这里查看这个问题的报告以及后续进展。
So the implementation of overflow
differs in Android and iOS, that's why the issue only occurs on Android in my project.
I have tried the solutions which I can found here, unfortunately none of them works.
So I have to dig into it and this is my solution:
Solution
Step 1
line 74 in method constructor
:
if (percent >= 50) {
rightTransformerDegree = '180deg';
leftTransformerDegree = (percent - 50) * 3.6 + 'deg';
} else {
rightTransformerDegree = percent * 3.6 + 'deg';
leftTransformerDegree = '0deg';
}
changed into
if (percent >= 50) {
rightTransformerDegree = '180deg';
leftTransformerDegree = (percent - 50) * 3.6 + 'deg';
} else {
rightTransformerDegree = percent * 3.6 + 'deg';
leftTransformerDegree = '180deg'; // line 74: changed here
}
Step2
line 94 in method componentWillReceiveProps
if (percent >= 50) {
rightTransformerDegree = '180deg';
leftTransformerDegree = (percent - 50) * 3.6 + 'deg';
} else {
rightTransformerDegree = percent * 3.6 + 'deg';
}
insert a line:
if (percent >= 50) {
rightTransformerDegree = '180deg';
leftTransformerDegree = (percent - 50) * 3.6 + 'deg';
} else {
rightTransformerDegree = percent * 3.6 + 'deg';
leftTransformerDegree = "180deg"; // insert a line here
}
Step 3
Adjust content between line 123 and 152:
<View style={[styles.leftWrap,{
width: this.props.radius,
height: this.props.radius * 2,
left:0,
}]}>
<View style={[styles.loader,{
left: this.props.radius,
width:this.props.radius,
height: this.props.radius*2,
borderTopLeftRadius:0,
borderBottomLeftRadius:0,
backgroundColor:this.props.color,
transform:[{translateX:-this.props.radius/2},{rotate:this.state.leftTransformerDegree},{translateX:this.props.radius/2}],
}]}></View>
</View>
<View style={[styles.leftWrap,{
left:this.props.radius,
width: this.props.radius,
height: this.props.radius * 2,
}]}>
<View style={[styles.loader,{
left:-this.props.radius,
width:this.props.radius,
height: this.props.radius*2,
borderTopRightRadius:0,
borderBottomRightRadius:0,
backgroundColor: this.props.color,
transform:[{translateX:this.props.radius/2},{rotate:this.state.rightTransformerDegree},{translateX:-this.props.radius/2}],
}]}></View>
</View>
Put View#rightTransformerDegree
before View#leftTransformerDegree
, and change backgroundColor
of View#leftTransformerDegree
<View style={[styles.leftWrap,{
left:this.props.radius,
width: this.props.radius,
height: this.props.radius * 2,
}]}>
<View style={[styles.loader,{
left:-this.props.radius,
width:this.props.radius,
height: this.props.radius*2,
borderTopRightRadius:0,
borderBottomRightRadius:0,
backgroundColor: this.props.color,
transform:[{translateX:this.props.radius/2},{rotate:this.state.rightTransformerDegree},{translateX:-this.props.radius/2}],
}]}></View>
</View>
<View style={[styles.leftWrap,{
width: this.props.radius,
height: this.props.radius * 2,
left:0,
}]}>
<View style={[styles.loader,{
left: this.props.radius,
width:this.props.radius,
height: this.props.radius*2,
borderTopLeftRadius:0,
borderBottomLeftRadius:0,
backgroundColor:percent >= 50 ? this.props.color : this.props.bgcolor, // changed this line
transform:[{translateX:-this.props.radius/2},{rotate:this.state.leftTransformerDegree},{translateX:this.props.radius/2}],
}]}></View>
</View>
Conclusion
I have forked this project and rewritten the code, I hope it could be merged into this project, or you can visit at My forked repo
Some changes in forked repo:
- Fixed the issue when percentage is less than 50.
- Fixed
textStyle
prop which is applied in Text
in View#innerCircle
.
- Added new prop
rotate
to support customizing the start position of progress circle.
Warning
I have tested my solution only in environments below:
-
Android:
- Device: XiaoMi 5
- OS: Android 6.0.1 MXB48T
- react: 15.4.1
- react-native: 0.39.2
-
iOS:
- Device: iPhone 6s
- OS: iOS 11.4
- react: 15.3.1
- react-native: 0.33.1