Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The solution to fix wrong progress when percentage is less than 50 #36

Open
hendiko opened this issue Jun 15, 2018 · 1 comment
Open

Comments

@hendiko
Copy link

hendiko commented Jun 15, 2018

Env:

Wrong Example on Android:
android

Normal Example on iOS:
ios

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:

  1. Fixed the issue when percentage is less than 50.
  2. Fixed textStyle prop which is applied in Text in View#innerCircle.
  3. 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
@luischavezpozo
Copy link

@hendiko thank you for the contribution. Please merge this fork

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants