Search code examples
androidseekbar

Updating seekbar value


I have a seekbar where which have following intervals: minimum value = 100000 and max value is 2500000 and interval is 25000

I need to update my seekbar on edittext change and also validate for figure which does not fall in range of 25000.

Here is my code:

int mininumloan_amount = 100000;
int maximum_loan_amount = 2500000;

int interval = 25000;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_seekbar);


    loanAmountSeekbar = findViewById(R.id.loanAmountSeekbar);
    loanAmountValue = findViewById(R.id.loanAmountValue);

    setEditText();
    setSeekBar();
}

private void setEditText() {

    loanAmountValue.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            int porgress = Math.round((int) Double.parseDouble(charSequence.toString()));
            if (porgress > mininumloan_amount)
                loanAmountSeekbar.setProgress(porgress);
        }

        @Override
        public void afterTextChanged(Editable editable) {

        }
    });
}

private void setSeekBar() {

    loanAmountSeekbar.setMax((maximum_loan_amount - mininumloan_amount) / interval);
    loanAmountSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            double value = mininumloan_amount + (i * interval);

            loanAmountValue.setText(value + "");
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });
}

Solution

  • I find it easiest to work with the progress bar based on a percentage of 100.

    So simply put, I would convert the input to a percentage of the maximum number you want to allow for the loan.

    Here is the code I used for my demo to have a proof of concept:

      private void setEditText() {
    
        loanAmountValue.addTextChangedListener(new TextWatcher() {
          @Override
          public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    
          }
    
          @Override
          public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
              double actualProgress = computeProgress(charSequence);
              Log.d(TAG, "Progress: " + actualProgress);
    
              // if the progress is 100 or less its in range
              if(actualProgress <= 100) {
                loanAmountSeekbar.setProgress((int) actualProgress);
              }
          }
    
          @Override
          public void afterTextChanged(Editable editable) {
    
          }
        });
      }
    
      /* 
          Mostly where all the magic is, we convert input to percent
          then check against minimum value, tell user to enter more.
          If the percent is more than 100, we default to 100%.
      */
      private Double computeProgress(CharSequence charSequence) {
        try {
          // Parse the value, also, used android:inputType="decimalNumber" in xml
          double editTextNumber = Double.parseDouble(charSequence.toString());
    
          if(editTextNumber < interval){
            Toast.makeText(MainActivity.this, "Please enter a value greater than "+ interval, Toast.LENGTH_SHORT).show();
            return 0.0;
          }
    
          // Turn the number into a percentage of the max value
          double percentageOfMax = editTextNumber / maximum_loan_amount;
    
          // Turn the percentage back into a number between 0 and 100
          double percent = 100 * percentageOfMax;
    
          // handle the max percent
          if(percent > 100){
            return 100.0;
          }else {
            return percent;
          }
    
        } catch (NumberFormatException ex) { // just in case something odd
          ex.printStackTrace();
          Toast.makeText(MainActivity.this, "Unable to parse: " + charSequence.toString(), Toast.LENGTH_SHORT).show();
        }catch(ArithmeticException ex){ // extra since we check a min above, probably can exlude this 
          Toast.makeText(MainActivity.this, "value must not be 0 ", Toast.LENGTH_SHORT).show();
        }
    
        return 0.0;
      }
    
      private void setSeekBar() {
    
        loanAmountSeekbar.setMax(100);
        loanAmountSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
          @Override
          public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            if(b){
              double value = interval * i;
              loanAmountValue.setText(value + "");
            }
          }
    
          @Override
          public void onStartTrackingTouch(SeekBar seekBar) {
    
          }
    
          @Override
          public void onStopTrackingTouch(SeekBar seekBar) {
    
          }
        });
      }
    

    Disclaimer This was a pretty quick solution, so you may need to explore additional error handling. But the basic idea is, take the input, convert it to a percent of 100.

    Good Luck and Happy Coding!