Search code examples
flutteruser-interfaceflutter-layoutflutter-animationflutter-design

Flutter custom radiobuttons


Can anyone guide me how to achieve this in flutter? Thanks

enter image description here


Solution

  • Here you go bro ..... Cheers !!!

    class _MyHomePageState extends State<MyHomePage> {
    
    
    
      double width;
      double height;
    
      int currentValue = 5;
    
      Map<int,int> minutesCostMap = {
        5: 20,
        10 : 25,
        15 : 30,
        20 : 35,
      },
    
    
      @override
      Widget build(BuildContext context) {
    
        height = MediaQuery.of(context).size.height;
        width = MediaQuery.of(context).size.width;
    
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                Padding(
                  padding: const EdgeInsets.symmetric(vertical: 15),
                  child: Text("Chris Watson",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 19),),
                ),
                Padding(
                  padding: const EdgeInsets.only(bottom: 25),
                  child: Text.rich(
                      TextSpan(children: [
                        TextSpan(text: "This "),
                        TextSpan(text: currentValue.toString() + " minutes ",style: TextStyle(fontWeight: FontWeight.bold)),
                        TextSpan(text: "session will cost you "),
                        TextSpan(text: minutesCostMap[currentValue].toString() + "\$",style: TextStyle(fontWeight: FontWeight.bold)),
                      ])
                  ),
                ),
                Stack(
                  alignment: Alignment.center,
                  children: [
                    Container(                                  /// GREY HORIZONTAL LINE
                      height: 10,width: width * 0.6,color: Colors.grey[350],
                    ),
                    Container(
                      width: width * 0.6 + 50,
                      height: 50,
                      child: Row(                            /// ROW OF 4 CIRCLE WIDGETS PLACED ABOVE THAT LNE
                        mainAxisSize: MainAxisSize.max,
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          checkpointButton(5,currentValue == 5),
                          checkpointButton(10,currentValue == 10),
                          checkpointButton(15,currentValue == 15),
                          checkpointButton(20,currentValue == 20),
                        ],
                      ),
                    ),
                    //Positioned(left: 0,chil),
                    //Positioned(left: ,child: Container(decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.blue),width: 40,height: 40,)),
                    //Positioned(left: ,child: Container(decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.blue),width: 40,height: 40,)),
                    //Positioned(left: ,child: Container(decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.blue),width: 40,height: 40,)),
                  ],
                ),
                Padding(
                  padding: EdgeInsets.only(top: 25),
                  child: Container(
                    width: width * 0.75,
                    height: 40,
                    child: Row(
                      mainAxisSize: MainAxisSize.max,
                      children: [
                        Expanded(
                          flex: 1,
                          child: Container(
                            decoration: BoxDecoration(border: Border.all(color: Colors.blue,width: 1.5)),
                            child: Center(child: Text("CANCEL",style: TextStyle(color: Colors.blue),),),
                          ),
                        ),
                        Container(width: 10,height: 5,),
                        Expanded(
                          flex: 2,
                          child: Container(color: Colors.blue,child: Center(child: Text("ACCEPT",style: TextStyle(color: Colors.white),),),),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ), // This trailing comma makes auto-formatting nicer for build methods.
        );
      }
    
      Widget checkpointButton(int value,bool isActive){
        return GestureDetector(               /// THIS WILL DETECT A TAP EVENT ON THIS CIRCLE WIDGET
            onTap: (){
              setState(() {
                currentValue = value;         /// IF THE CURRENT VALUE IS SAME AS THE VALUE OF THE CIRCLE, IT WILL CHANGE ITS APPEARANCE TO SHOW THAT ITS ACTIVE
              });
            },
            child: Container(            /// CIRCLE PRESENT BEHIND PROVIDING THE BLUE BORDER
                height: 50,width: 50,
                decoration: BoxDecoration(shape: BoxShape.circle,border: Border.all(color: isActive ? Colors.blue : Colors.transparent,width: 1.5)),
                child: Center(
                    child: Container(        /// INNER CIRCLE CONTAINING THE VALUE
                      decoration: BoxDecoration(shape: BoxShape.circle,color: isActive ? Colors.blue : Colors.grey[350]),
                      width: 40,height: 40,
                      child: Center(child: Text(value.toString(),style: TextStyle(fontWeight: FontWeight.bold,color: isActive ? Colors.white : Colors.black),)),
                      )
                )
            )
        );
      }
    
    }
    
    

    Result :

    enter image description here

    Edit :

    I have updated the code above to match your requirements. Basically what I did what I added a Map (minutesCostMap) which contains the list of the minutes and their corresponding cost. Then moving on the the place where we are displaying the cost, you can see that I used the value from the map itself. So the value we are printing will output the cost with corresponds to the provided minutes(i.e. present in the currentValue variable)