Ankush Rishi
Ankush Rishi

Reputation: 3160

Display value of slider with respect to slider thumb

I want to move the label with respect to slider thumb just like this one: enter image description here

Right now my slider is like this:

enter image description here

I want to display the label shown as 30 km with respect to the slider thumb such that as the slider moves, the label should move accordingly.

I am using Native React Slider component.

this is my code:

<Slider 
     style={styles.slider} 
     thumbTintColor='rgb(252, 228, 149)' 
     step={1} 
     maximumValue={5} 
     thumbTintColor='rgb(252, 228, 149)' 
     maximumTrackTintColor='#494A48' 
     minimumTrackTintColor='rgb(252, 228, 149)' />

Upvotes: 10

Views: 27021

Answers (7)

Sahil Kashyap
Sahil Kashyap

Reputation: 359

Building on the ahsan code, i added Animated value, and wrapped the value in Animated.View so it can animate properly

import React, { useState } from 'react';
import { Text, View, StyleSheet, Slider,Animated } from 'react-native';

const SliderComponent = () => {
  const minDistance = 10;
  const maxDistance = 100;

  const tooltipPosition = new Animated.Value(0);

  const updateTooltipPosition = (value) => {
    setDistance(value);
    tooltipPosition.setValue(value);
  };
  const [distance, setDistance] = useState(30);

  return (
    <View style={styles.container}>
      <Slider
        style={{ width: 300 }}
        step={1}
        minimumValue={minDistance}
        maximumValue={maxDistance}
        value={distance}
        onValueChange={(val) => updateTooltipPosition(val)}
        thumbTintColor='rgb(252, 228, 149)'
        maximumTrackTintColor='#d3d3d3'
        minimumTrackTintColor='rgb(252, 228, 149)'
      />
      <View style={styles.textCon}>
        <Text style={styles.colorGrey}>{minDistance} km</Text>
        <Animated.View
        style={[
          styles.bubble,
          { left: `${(distance / 100) * 90}%`, transform: [{ translateY: -10 }] },
        ]}
      >
        <Text style={[styles.colorYellow]}>{distance} km</Text>
      </Animated.View>
        <Text style={styles.colorGrey}>{maxDistance} km</Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#000',
  },
  textCon: {
    width: 320,
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  colorGrey: {
    color: '#d3d3d3',
  },
  colorYellow: {
    color: 'rgb(252, 228, 149)',
  },
  bubble: {
    position: 'absolute',
    alignItems: 'center',
    justifyContent: 'center',
  },
  bubbleText: {
    color: '#000000',
    fontWeight: 'bold',
    fontSize: 16,
    backgroundColor: '#FFFFFF',
    borderRadius: 5,
    paddingVertical: 5,
    paddingHorizontal: 10,
  },
});

export default SliderComponent;

https://snack.expo.dev/@sahilkash/slider?platform=android

Upvotes: 0

Doddanna D
Doddanna D

Reputation: 41

import {Slider} from 'react-native-elements';    
<Slider
      thumbStyle={{height: 15, width: 15, backgroundColor: 'orange'}}
      maximumTrackTintColor="grey"
      minimumTrackTintColor="orange"
      thumbProps={{
        children: (
          <View
            style={{
              color: 'green',
              marginTop: -22,
              width: 100,
            }}>
            <Text>Text</Text>
          </View>
        ),
      }}
    />

enter image description here

enter image description here

enter image description here

Upvotes: 0

Mbs Yaswanth
Mbs Yaswanth

Reputation: 150

I think react-native-multi-slider will solve your problem . You can change the slider thumb by sending your custom designed component to the customMarker prop that is available. Then you can wrap the Multislider in another component, maintain the state(for slider position value) there and send value as prop to your custom designed marker everytime the thumb position changes which can be detected using onValuesChange prop.

This link might also help you.

Upvotes: 0

Developer
Developer

Reputation: 432

You can adjust left of the text to the value of the slider.

const left = this.state.value * (screenWidth-60)/100 - 15;

<Text style={ { width: 50, textAlign: 'center', left: left } }>
  {Math.floor( this.state.value )}
</Text>

<Slider maximumValue={100} 
        value={this.state.value}
        onValueChange={value => this.setState({ value })} />

enter image description here

enter image description here

enter image description here

Upvotes: 18

thegoodguy
thegoodguy

Reputation: 172

  1. measure the size and position of the slider View

    <Slider
        maximumValue={10}
        onLayout={(event)=>{this.slider_bound(event)}}/>
    
    
    //majore size of Slider.
    slider_bound=(event)=>{
    var {x, y, width, height} = event.nativeEvent.layout;
    this.state.slider_Width=width;
    this.state.slider_Height=height;
    this.state.slider_x = x;
    this.state.slider_y = y;
    this.state.slider_x_step_size = width/10; //Devide the width by slider maximum value
    
    this.setState({triger:''});
    console.log(TAG+"Slider Dimen:"+width,height+'pos:',x,y);
    
    }
    

2.Now in "onValueChange" callback of slider.

   //compute position to show slider value txt
   this.state.value_x = (value * this.state.slider_x_step_size) + this.state.slider_x;
   this.state.value_y = this.state.slider_Height + this.state.slider_y; 
  1. Show the slider Value txt on Calculated positions.

    <Text style={{position:'absolute',top:this.state.value_y,left:this.state.value_x,color:colors.blackc}}>{this.state.data.slider_value}</Text>
    

.............. that will do the job, but You might have to tweak it little bit.

Upvotes: 0

Ahsan Ali
Ahsan Ali

Reputation: 5135

Solution to your problem:

    constructor(props){
        super(props)
        this.state = {
            distance: 30,
            minDistance: 10,
            maxDistance: 100
        }
    }


    render() {
        return (
            <View style={styles.container}>
                <Slider
                    style={{ width: 300}}
                    step={1}
                    minimumValue={this.state.minDistance}
                    maximumValue={this.state.maxDistance}
                    value={this.state.distance}
                    onValueChange={val => this.setState({ distance: val })}
                    thumbTintColor='rgb(252, 228, 149)'
                    maximumTrackTintColor='#d3d3d3' 
                    minimumTrackTintColor='rgb(252, 228, 149)'
                />
                <View style={styles.textCon}>
                    <Text style={styles.colorGrey}>{this.state.minDistance} km</Text>
                    <Text style={styles.colorYellow}>
                        {this.state.distance + 'km'}
                    </Text>
                    <Text style={styles.colorGrey}>{this.state.maxDistance} km</Text>
                </View>
            </View>
        );
    }
}

Styles:

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#000',
    },
    textCon: {
        width: 320,
        flexDirection: 'row',
        justifyContent: 'space-between'
    },
    colorGrey: {
        color: '#d3d3d3'
    },
    colorYellow: {
        color: 'rgb(252, 228, 149)'
    }
});

Output:

https://i.sstatic.net/telTT.jpg

Working Snippet: https://snack.expo.io/Syrt3Bs7z

Upvotes: 6

Val
Val

Reputation: 22797

Built in <Slider /> doesn't provide those flexibility to customize what you want.

This should works, react-native-slider, which is a drop-in replacement of official <Slider />.

What you need is very similar to it's demo style #4.

enter image description here

For your Slider Label of value, you can modify its function _renderThumbImage() to replace default <Image />.

Upvotes: 3

Related Questions