Có cách nào để xác định giá trị tối thiểu và tối đa cho EditText trong Android không?


133

Tôi muốn xác định một giá trị tối thiểu và tối đa cho một EditText.

Ví dụ: nếu bất kỳ người nào cố gắng nhập giá trị tháng trong đó, giá trị phải nằm trong khoảng từ 1-12.

Tôi có thể làm điều đó bằng cách sử dụng TextWatchernhưng tôi muốn biết liệu có cách nào khác để làm điều đó trong tệp bố cục hoặc ở nơi khác không.

Chỉnh sửa: Tôi không muốn giới hạn số lượng ký tự. Tôi muốn giới hạn giá trị. Ví dụ: nếu tôi giới hạn các EditTextký tự tháng w khi tôi nhập 12 thì nó sẽ chấp nhận nhưng nếu tôi nhập 22 thì không được chấp nhận khi tôi nhập.


Ai đó nên tạo một thư viện / bộ sưu tập của tất cả các loại bộ lọc đầu vào. Sau đó mọi người có thể làm việc và kiểm tra chúng cùng nhau. Thay vì mỗi người làm việc riêng của họ.
Zapnologica

Sử dụng bộ lọc văn bản chỉnh sửa này để giải quyết vấn đề của bạn. bộ lọc
Taras Smakula

Câu trả lời:


286

Đầu tiên thực hiện lớp này:

package com.test;

import android.text.InputFilter;
import android.text.Spanned;

public class InputFilterMinMax implements InputFilter {

    private int min, max;

    public InputFilterMinMax(int min, int max) {
        this.min = min;
        this.max = max;
    }

    public InputFilterMinMax(String min, String max) {
        this.min = Integer.parseInt(min);
        this.max = Integer.parseInt(max);
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {   
        try {
            int input = Integer.parseInt(dest.toString() + source.toString());
            if (isInRange(min, max, input))
                return null;
        } catch (NumberFormatException nfe) { }     
        return "";
    }

    private boolean isInRange(int a, int b, int c) {
        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }
}

Sau đó sử dụng điều này từ Hoạt động của bạn:

EditText et = (EditText) findViewById(R.id.myEditText);
et.setFilters(new InputFilter[]{ new InputFilterMinMax("1", "12")});

Điều này sẽ cho phép người dùng chỉ nhập các giá trị từ 1 đến 12 .

BIÊN TẬP :

Đặt edittext của bạn với android:inputType="number".

Bạn có thể tìm thêm chi tiết tại https://www.techcompose.com/how-to-set-minimum-and-maximum-value-in-edittext-in-android-app-development/ .

Cảm ơn.


1
@mertaydin chắc chắn. hãy thử sau đó cho tôi biết nếu bạn cần sự giúp đỡ của tôi. Cảm ơn.
Pratik Sharma

12
Aah, tôi cần giúp đỡ. Tôi có một vấn đề trong khi giá trị writig trong khoảng thời gian từ 1930 đến 1999. Khi tôi viết 1, nó kiểm soát giá trị và 1 không nằm trong khoảng từ 1930 đến 1999 vì vậy nó không chấp nhận nó.
mertaydin

1
@mertaydin Xin lỗi nhưng tôi hơi bận rộn với công việc của mình. Tôi mới có chút thời gian để xem xét vấn đề này, tôi nghĩ rằng tôi cần phải sửa đổi thuật toán được áp dụng trong lớp bộ lọc. Tôi sẽ cập nhật cho bạn một khi tôi sẽ làm điều đó.
Pratik Sharma

1
Một số nhân vật từ sourcesẽ thay thế một số nhân vật trong dest. Tôi nghĩ bạn nên mô phỏng sự thay thế, và sau đó, xác nhận nó.
SD

3
@Pratik Sharma, Điều này không hoạt động khi tôi nhập phạm vi từ 1900 đến 2000, Bạn có thể đề xuất điều gì không
EminenT

89

Có một lỗi nhỏ trong mã của Pratik. Chẳng hạn, nếu một giá trị là 10 và bạn thêm 1 vào đầu để tạo 110, hàm bộ lọc sẽ coi giá trị mới là 101.

Xem bên dưới để khắc phục điều này:

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        // Remove the string out of destination that is to be replaced
        String newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length());
        // Add the new string in
        newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length());
        int input = Integer.parseInt(newVal);
        if (isInRange(min, max, input))
            return null;
    } catch (NumberFormatException nfe) { }
    return "";
}

Cảm ơn điều này đã giúp tôi rất nhiều!
joschplusa

4
Tôi nghĩ điều này rõ ràng hơn imho :String replacement = source.subSequence(start, end).toString(); String newVal = dest.subSequence(0, dstart).toString() + replacement + dest.subSequence(dend, dest.length()).toString();
Sven Jacobs

1
+1. Giải pháp này đúng hơn chấp nhận. Để kiểm tra, ví dụ: hãy thử sử dụng InputFilterMinMax với tùy chọn selectAllOnF Focus được bật và so sánh kết quả.
Sash0k

1
Tại sao không String newVal= dest.toString().substring(0, dstart) + source.toString().substring(start, end) + dest.toString().substring(dend, dest.toString().length());, trông sạch sẽ và rõ ràng hơn.
Shishir Gupta

5
Như OP @mertaydin đã đề cập trong một nhận xét về câu trả lời của @Patrick, giải pháp này vẫn còn một lỗ hổng lớn, tôi tự hỏi tại sao nó không được báo cáo: Nếu min==3sau đó không thể nhập bất kỳ số nào bắt đầu bằng 1 hoặc 2 (ví dụ: 15, 23)
Guerneen4

10

Về những gì tôi đã thấy về giải pháp của @ Patrik và bổ sung của @ Zac, mã được cung cấp vẫn còn một vấn đề lớn:

Nếu min==3sau đó không thể nhập bất kỳ số nào bắt đầu bằng 1 hoặc 2 (ví dụ: 15, 23)
Nếu min>=10sau đó không thể nhập bất cứ thứ gì vì mọi số sẽ phải bắt đầu bằng 1,2,3 ...

Theo hiểu biết của tôi, chúng tôi không thể đạt được giới hạn tối thiểu của EditTextgiá trị của một lớp với việc sử dụng đơn giản lớp InputFilterMinMax, ít nhất là không cho Giá trị tối thiểu, bởi vì khi người dùng nhập một số dương, giá trị sẽ tăng lên và chúng tôi có thể dễ dàng thực hiện kiểm tra nhanh để kiểm tra xem nó có đạt đến giới hạn hay vượt ra ngoài phạm vi và chặn các mục không tuân thủ hay không. Kiểm tra giá trị tối thiểu là một câu chuyện khác nhau vì chúng tôi không thể chắc chắn liệu người dùng đã nhập xong hay chưa và do đó không thể quyết định liệu chúng tôi có nên chặn hay không.

Đó không phải là chính xác những gì OP yêu cầu nhưng với mục đích xác thực tôi đã kết hợp trong giải pháp của mình InputFilterđể kiểm tra các giá trị tối đa, với OnFocusChangeListenerviệc kiểm tra lại giá trị tối thiểu khi EditTextmất tiêu điểm giả sử người dùng đã gõ xong và nó giống như thế này:

package test;


import android.text.InputFilter;

import android.text.Spanned;

public class InputFilterMax implements InputFilter {

private int max;

public InputFilterMax(int max) {
    this.max = max;
}

public InputFilterMax(String max) {
    this.max = Integer.parseInt(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {   
    try {
        String replacement = source.subSequence(start, end).toString(); 

        String newVal = dest.toString().substring(0, dstart) + replacement +dest.toString().substring(dend, dest.toString().length());

        int input = Integer.parseInt(newVal);

        if (input<=max)
            return null;
    } catch (NumberFormatException nfe) { }   
//Maybe notify user that the value is not good      
return "";
}
}

OnFocusChangeListenerMin

package test;

import android.text.TextUtils;
import android.view.View;
import android.view.View.OnFocusChangeListener;

public class OnFocusChangeListenerMin implements OnFocusChangeListener {

private int min;

public OnFocusChangeListenerMin(int min) {
    this.min = min;
}

public OnFocusChangeListenerMin(String min) {
    this.min = Integer.parseInt(min);
}


@Override
public void onFocusChange(View v, boolean hasFocus) {
    if(!hasFocus) {
        String val = ((EditText)v).getText().toString();
        if(!TextUtils.isEmpty(val)){
            if(Integer.valueOf(val)<min){
                //Notify user that the value is not good
            }

        }
    }
}
}

Sau đó, trong Hoạt động thiết lập InputFilterMaxOnFocusChangeListenerMinđể EditText lưu ý: Bạn có thể 2 cả min và max trong onFocusChangeListener.

mQteEditText.setOnFocusChangeListener( new OnFocusChangeListenerMin('20');
mQteEditText.setFilters(new InputFilter[]{new InputFilterMax(getActivity(),'50')});

OnF FocusChangeListenerMin không hoạt động, nó đặt tất cả các giá trị từ 0
EminenT

1
Bạn có phiền chi tiết hơn một chút không? ý bạn là gì khi đặt tất cả các giá trị từ 0 ?
Guerneen4

từ mã OnF FocusChangeListenerMin phải hoạt động trên 20 như đã thảo luận trong vấn đề khi nó chấp nhận tất cả các giá trị nhỏ hơn 20 như 0, 1, 2, ------ 19, v.v.
EminenT

bạn đã tìm ra được giải pháp nào chưa?
EminenT

Tôi đã sử dụng OnFoncusChangeListener nhằm mục đích xác thực, trong trường hợp của tôi, tôi hiển thị lỗi trên EditText thông báo cho người dùng bằng Toast rằng giá trị không tốt và mời anh ta nhập giá trị mới if(Integer.valueOf(val)<min){ //Notify user that the value is not good } Bạn có thể làm những gì bạn muốn ở đó, thông báo cho người dùng và đặt EditText để trống, tôi không biết điều này có trả lời câu hỏi của bạn không
Guerneen4

9

Mở rộng câu trả lời của Pratik và Zac. Zac đã sửa một lỗi nhỏ của Pratik trong câu trả lời của mình. Nhưng tôi đã thông báo rằng mã không hỗ trợ các giá trị âm, nó sẽ đưa ra NumberFormatException. Để khắc phục điều đó và cho phép MIN âm, sử dụng mã sau đây.

Thêm dòng này (in đậm) giữa hai dòng còn lại:

newVal = newVal.subopes (0, dstart) + source.toString () + newVal.subopes (dstart, newVal.length ());

if (newVal.equalsIgnoreCase ("-") && min <0) trả về null;

int input = Integer.parseInt (newVal);

public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        // Remove the string out of destination that is to be replaced
        String newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length());
        // Add the new string in
        newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length());
        //****Add this line (below) to allow Negative values***// 
        if(newVal.equalsIgnoreCase("-") && min < 0)return null;
        int input = Integer.parseInt(newVal);
        if (isInRange(min, max, input))
            return null;
    } catch (NumberFormatException nfe) {
        nfe.printStackTrace();
    }
    return "";
}

5

Nếu bạn cần phạm vi với các số âm như -90: 90, bạn có thể sử dụng giải pháp này.

public class InputFilterMinMax implements InputFilter {

private int min, max;

public InputFilterMinMax(int min, int max) {
    this.min = min;
    this.max = max;
}

public InputFilterMinMax(String min, String max) {
    this.min = Integer.parseInt(min);
    this.max = Integer.parseInt(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        String stringInput = dest.toString() + source.toString();
        int value;
        if (stringInput.length() == 1 && stringInput.charAt(0) == '-') {
            value = -1;
        } else {
            value = Integer.parseInt(stringInput);
        }
        if (isInRange(min, max, value))
            return null;
    } catch (NumberFormatException nfe) {
    }
    return "";
}

private boolean isInRange(int min, int max, int value) {
    return max > min ? value >= min && value <= max : value >= max && value <= min;
}
}

5

Tôi đã mở rộng mã @Pratik Sharmas để sử dụng các đối tượng BigDecimal thay vì ints để nó có thể chấp nhận số lượng lớn hơn và tính đến mọi định dạng trong EditText không phải là số (như định dạng tiền tệ, ví dụ như dấu cách, dấu phẩy và dấu chấm)

EDIT: lưu ý rằng việc triển khai này có 2 là số liệu có ý nghĩa tối thiểu được đặt trên BigDecimal (xem hằng số MIN_SIG_FIG) khi tôi sử dụng nó cho tiền tệ, vì vậy luôn có 2 số đứng đầu trước dấu thập phân. Thay đổi hằng số MIN_SIG_FIG khi cần thiết cho việc triển khai của riêng bạn.

public class InputFilterMinMax implements InputFilter {
private static final int MIN_SIG_FIG = 2;
private BigDecimal min, max;

public InputFilterMinMax(BigDecimal min, BigDecimal max) {
    this.min = min;
    this.max = max;
}

public InputFilterMinMax(String min, String max) {
    this.min = new BigDecimal(min);
    this.max = new BigDecimal(max);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart,
        int dend) {
    try {
        BigDecimal input = formatStringToBigDecimal(dest.toString()
                + source.toString());

        if (isInRange(min, max, input)) {

            return null;
        }
    } catch (NumberFormatException nfe) {

    }
    return "";
}

private boolean isInRange(BigDecimal a, BigDecimal b, BigDecimal c) {
    return b.compareTo(a) > 0 ? c.compareTo(a) >= 0 && c.compareTo(b) <= 0
            : c.compareTo(b) >= 0 && c.compareTo(a) <= 0;
}

public static BigDecimal formatStringToBigDecimal(String n) {

    Number number = null;
    try {
        number = getDefaultNumberFormat().parse(n.replaceAll("[^\\d]", ""));

        BigDecimal parsed = new BigDecimal(number.doubleValue()).divide(new BigDecimal(100), 2,
                BigDecimal.ROUND_UNNECESSARY);
        return parsed;
    } catch (ParseException e) {
        return new BigDecimal(0);
    }
}

private static NumberFormat getDefaultNumberFormat() {
    NumberFormat nf = NumberFormat.getInstance(Locale.getDefault());
    nf.setMinimumFractionDigits(MIN_SIG_FIG);
    return nf;
}

4

Tôi tìm thấy câu trả lời của riêng tôi. Bây giờ là rất muộn nhưng tôi muốn chia sẻ nó với bạn. Tôi thực hiện giao diện này:

import android.text.TextWatcher;


public abstract class MinMaxTextWatcher implements TextWatcher {
    int min, max;
    public MinMaxTextWatcher(int min, int max) {
        super();
        this.min = min;
        this.max = max;
    }

}

Và sau đó thực hiện nó theo cách này trong hoạt động của bạn:

private void limitEditText(final EditText ed, int min, int max) {
    ed.addTextChangedListener(new MinMaxTextWatcher(min, max) {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            String str = s.toString();
            int n = 0;
            try {
                n = Integer.parseInt(str);
                if(n < min) {
                    ed.setText(min);
                    Toast.makeText(getApplicationContext(), "Minimum allowed is " + min, Toast.LENGTH_SHORT).show();
                }
                else if(n > max) {
                    ed.setText("" + max);
                    Toast.makeText(getApplicationContext(), "Maximum allowed is " + max, Toast.LENGTH_SHORT).show();
                }
            }
            catch(NumberFormatException nfe) {
                ed.setText("" + min);
                Toast.makeText(getApplicationContext(), "Bad format for number!" + max, Toast.LENGTH_SHORT).show();
            }
        }
    });
}

Đây là một câu trả lời rất đơn giản, nếu có tốt hơn xin vui lòng cho tôi biết.


int n = 0; là dư thừa. Vì giá trị mặc định của n là 0.
Kenny Dabiri

1
Tại sao int n = 0 lại dư thừa ở đây? nó là một biến cục bộ và không phải là biến thể ở đây.
Người dùng12111111

4

Có một cái gì đó sai trong câu trả lời được chấp nhận.

int input = Integer.parseInt(dest.toString() + source.toString());

Nếu tôi di chuyển con trỏ vào giữa văn bản, sau đó nhập một cái gì đó, thì câu lệnh trên sẽ tạo ra kết quả sai. Ví dụ: nhập "12" trước, sau đó nhập "0" trong khoảng từ 1 đến 2, sau đó câu lệnh được đề cập ở trên sẽ tạo ra "120" thay vì 102. Tôi đã sửa đổi câu lệnh này thành câu lệnh dưới đây:

String destString = dest.toString();
  String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);
  int input = Integer.parseInt(inputString);

4

Kotlin nếu có ai cần nó (Sử dụng tiện ích)

class InputFilterMinMax: InputFilter {
    private var min:Int = 0
    private var max:Int = 0
    constructor(min:Int, max:Int) {
        this.min = min
        this.max = max
    }
    constructor(min:String, max:String) {
        this.min = Integer.parseInt(min)
        this.max = Integer.parseInt(max)
    }
    override fun filter(source:CharSequence, start:Int, end:Int, dest: Spanned, dstart:Int, dend:Int): CharSequence? {
        try
        {
            val input = Integer.parseInt(dest.toString() + source.toString())
            if (isInRange(min, max, input))
                return null
        }
        catch (nfe:NumberFormatException) {}
        return ""
    }
    private fun isInRange(a:Int, b:Int, c:Int):Boolean {
        return if (b > a) c in a..b else c in b..a
    }
}

Sau đó sử dụng cái này từ lớp Kotlin của bạn

percentage_edit_text.filters = arrayOf(Utilities.InputFilterMinMax(1, 100))

EditText này cho phép từ 1 đến 100.

Sau đó sử dụng cái này từ XML của bạn

android:inputType="number"

Tôi sử dụng nguồn trả về và làm việc cho tôi ==> if (isInRange (min, max, input)) nguồn trả về
Muzafferus

3

Tôi đã thực hiện một cách đơn giản hơn để đặt min / max thành Edittext. Tôi sử dụng bàn phím số học và tôi làm việc với phương pháp này:

 private int limit(EditText x,int z,int limin,int limax){

    if( x.getText().toString()==null || x.getText().toString().length()==0){
        x.setText(Integer.toString(limin));
        return z=0;
    }
    else{
        z = Integer.parseInt(x.getText().toString());
         if(z <limin || z>limax){
             if(z<10){
                 x.setText(Integer.toString(limin));
                return  z=0;
             }
            else{
                x.setText(Integer.toString(limax));
                return z=limax;
            }

         }
         else
            return z = Integer.parseInt(x.getText().toString());
    }
 }

Phương thức chấp nhận tất cả các giá trị của bạn nhưng nếu giá trị của người dùng không tuân thủ giới hạn của bạn, nó sẽ được đặt tự động thành giới hạn tối thiểu / tối đa. Dành cho người cũ giới hạn limin = 10, limax = 80 nếu người dùng đặt 8, tự động 10 được lưu vào một biến và EditText được đặt thành 10.


3

Tôi biết đã có một triệu câu trả lời cho điều này rồi, với một câu được chấp nhận. Tuy nhiên, có rất nhiều lỗi trong câu trả lời được chấp nhận và hầu hết phần còn lại chỉ đơn giản là sửa một (hoặc có thể hai) trong số đó, mà không mở rộng cho tất cả các trường hợp sử dụng có thể.

Vì vậy, về cơ bản tôi đã biên dịch hầu hết các bản sửa lỗi được đề xuất trong các câu trả lời hỗ trợ cũng như thêm một phương thức để cho phép nhập số liên tục ngoài phạm vi theo hướng 0 (nếu phạm vi không bắt đầu từ 0), ít nhất là cho đến khi chắc chắn rằng nó không còn có thể trong phạm vi. Bởi vì rõ ràng, đây là lần duy nhất thực sự gây rắc rối với nhiều giải pháp khác.

Đây là cách khắc phục:

public class InputFilterIntRange implements InputFilter, View.OnFocusChangeListener {

    private final int min, max;

    public InputFilterIntRange(int min, int max) {
        if (min > max) {
            // Input sanitation for the filter itself
            int mid = max;
            max = min;
            min = mid;
        }
        this.min = min;
        this.max = max;
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

        // Determine the final string that will result from the attempted input
        String destString = dest.toString();
        String inputString = destString.substring(0, dstart) + source.toString() + destString.substring(dstart);

        // Don't prevent - sign from being entered first if min is negative
        if (inputString.equalsIgnoreCase("-") && min < 0) return null;

        try {
            int input = Integer.parseInt(inputString);
            if (mightBeInRange(input))
                return null;
        } catch (NumberFormatException nfe) {}

        return "";
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {

        // Since we can't actively filter all values
        // (ex: range 25 -> 350, input "15" - could be working on typing "150"),
        // lock values to range after text loses focus
        if (!hasFocus) {
            if (v instanceof EditText) sanitizeValues((EditText) v);
        }
    }

    private boolean mightBeInRange(int value) {
        // Quick "fail"
        if (value >= 0 && value > max) return false;
        if (value >= 0 && value >= min) return true;
        if (value < 0 && value < min) return false;
        if (value < 0 && value <= max) return true;

        boolean negativeInput = value < 0;

        // If min and max have the same number of digits, we can actively filter
        if (numberOfDigits(min) == numberOfDigits(max)) {
            if (!negativeInput) {
                if (numberOfDigits(value) >= numberOfDigits(min) && value < min) return false;
            } else {
                if (numberOfDigits(value) >= numberOfDigits(max) && value > max) return false;
            }
        }

        return true;
    }

    private int numberOfDigits(int n) {
        return String.valueOf(n).replace("-", "").length();
    }

    private void sanitizeValues(EditText valueText) {
        try {
            int value = Integer.parseInt(valueText.getText().toString());
            // If value is outside the range, bring it up/down to the endpoint
            if (value < min) {
                value = min;
                valueText.setText(String.valueOf(value));
            } else if (value > max) {
                value = max;
                valueText.setText(String.valueOf(value));
            }
        } catch (NumberFormatException nfe) {
            valueText.setText("");
        }
    }

}

Lưu ý rằng một số trường hợp đầu vào không thể xử lý "chủ động" (nghĩa là, vì người dùng đang nhập nó), vì vậy chúng tôi phải bỏ qua chúng và xử lý chúng sau khi người dùng hoàn thành chỉnh sửa văn bản.

Đây là cách bạn có thể sử dụng nó:

EditText myEditText = findViewById(R.id.my_edit_text);
InputFilterIntRange rangeFilter = new InputFilterIntRange(25, 350);
myEditText.setFilters(new InputFilter[]{rangeFilter});

// Following line is only necessary if your range is like [25, 350] or [-350, -25].
// If your range has 0 as an endpoint or allows some negative AND positive numbers, 
// all cases will be handled pre-emptively.
myEditText.setOnFocusChangeListener(rangeFilter);

Bây giờ, khi người dùng cố gắng nhập một số gần bằng 0 hơn phạm vi cho phép, một trong hai điều sẽ xảy ra:

  1. Nếu minmaxcó cùng số chữ số, họ sẽ không được phép nhập số đó một khi họ đến chữ số cuối cùng.

  2. Nếu một số bên ngoài phạm vi được để lại trong trường khi văn bản mất tiêu điểm, nó sẽ tự động được điều chỉnh đến ranh giới gần nhất.

Và tất nhiên, người dùng sẽ không bao giờ được phép nhập giá trị xa hơn 0 so với phạm vi cho phép, cũng như không thể để một số như thế "vô tình" nằm trong trường văn bản vì lý do này.

Vấn đề đã biết (s?)

  1. Điều này chỉ hoạt động nếu EditTextmất tập trung khi người dùng được thực hiện với nó.

Tùy chọn khác là vệ sinh khi người dùng nhấn phím "hoàn thành" / trả lại, nhưng trong nhiều hoặc thậm chí hầu hết các trường hợp, điều này gây ra sự mất tập trung dù sao đi nữa.

Tuy nhiên, việc đóng bàn phím mềm sẽ không tự động bỏ tiêu điểm. Tôi chắc chắn 99,99% các nhà phát triển Android mong muốn điều đó (và việc xử lý tập trung vào EditTextcác yếu tố nói chung không phải là một vấn đề khó khăn), nhưng cho đến nay vẫn chưa có chức năng tích hợp cho nó. Phương pháp đơn giản nhất mà tôi đã tìm thấy để giải quyết vấn đề này, nếu bạn cần, là mở rộng EditTextmột cái gì đó như thế này:

public class EditTextCloseEvent extends AppCompatEditText {

    public EditTextCloseEvent(Context context) {
        super(context);
    }

    public EditTextCloseEvent(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditTextCloseEvent(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            for (InputFilter filter : this.getFilters()) {
                if (filter instanceof InputFilterIntRange)
                    ((InputFilterIntRange) filter).onFocusChange(this, false);
            }
        }
        return super.dispatchKeyEvent(event);
    }
}

Điều này sẽ "đánh lừa" bộ lọc trong việc vệ sinh đầu vào mặc dù chế độ xem chưa thực sự mất tiêu điểm. Nếu chế độ xem xảy ra sau đó tự mất tập trung, vệ sinh đầu vào sẽ kích hoạt lại, nhưng sẽ không có gì thay đổi vì nó đã được sửa.

Đóng cửa

Phù Đó là rất nhiều. Điều ban đầu có vẻ như là một vấn đề khá dễ dàng đã kết thúc bằng việc phát hiện ra nhiều mảnh vani xấu xí của Android (ít nhất là trong Java). Và một lần nữa, bạn chỉ cần thêm người nghe và mở rộng EditTextnếu phạm vi của bạn không bao gồm 0 theo một cách nào đó. (Và thực tế, nếu phạm vi của bạn không bao gồm 0 mà bắt đầu từ 1 hoặc -1, bạn cũng sẽ không gặp vấn đề.)

Như một lưu ý cuối cùng, điều này chỉ hoạt động cho ints . Chắc chắn có một cách để thực hiện nó để làm việc với số thập phân ( double, float), nhưng vì cả tôi và người hỏi ban đầu đều không có nhu cầu đó, tôi đặc biệt không muốn tìm hiểu sâu về nó. Sẽ rất dễ dàng khi chỉ cần sử dụng bộ lọc sau hoàn thành cùng với các dòng sau:

// Quick "fail"
if (value >= 0 && value > max) return false;
if (value >= 0 && value >= min) return true;
if (value < 0 && value < min) return false;
if (value < 0 && value <= max) return true;

Bạn sẽ chỉ phải thay đổi từ intđến float(hoặc double), cho phép chèn của một đơn .(hoặc ,, tùy thuộc vào quốc gia?), Và phân tích cú pháp là một trong những loại thập phân thay vì một int.

Điều đó xử lý hầu hết các công việc, vì vậy nó sẽ hoạt động rất giống nhau.


2
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        String prefix = dest.toString().substring(0, dstart);
        String insert = source.toString();
        String suffix = dest.toString().substring(dend);
        String input_string = prefix + insert + suffix;
        int input = Integer.parseInt(input_string);

        if (isInRange(min, max, input) || input_string.length() < String.valueOf(min).length())
            return null;
    } catch (NumberFormatException nfe) { }
    return "";
}

private boolean isInRange(int a, int b, int c) {
    return b > a ? c >= a && c <= b : c >= b && c <= a;
}

2

Ví dụ rất đơn giản trên Kotlin:

import android.text.InputFilter
import android.text.Spanned

class InputFilterRange(private var range: IntRange) : InputFilter {

    override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int) = try {
        val input = Integer.parseInt(dest.toString() + source.toString())
        if (range.contains(input)) null else ""
    } catch (nfe: NumberFormatException) {
        ""
    }
}

1

vui lòng kiểm tra mã này

    String pass = EditText.getText().toString(); 
    if(TextUtils.isEmpty(pass) || pass.length < [YOUR MIN LENGTH]) 
    { 
       EditText.setError("You must have x characters in your txt"); 
        return; 
    }

    //continue processing



edittext.setOnFocusChangeListener( new OnFocusChangeListener() {

       @Override
       public void onFocusChange(View v, boolean hasFocus) {
          if(hasFocus) {
           // USE your code here 
  }

Sử dụng liên kết dưới đây để biết thêm chi tiết về edittext và edittextfilteres với trình xem văn bản ..

http://www.mobisoftinfotech.com/blog/android/android-edittext-setfilters-example-numeric-text-field-potypes-and-length-restriction/


OP muốn xác thực nó khi giá trị được nhập. Tôi nghĩ rằng bạn đã cung cấp giải pháp cho kịch bản sau khi giá trị được nhập
MysticMagicϡ

Tôi không phải là người hỏi. Tôi chỉ nghi ngờ về câu trả lời của bạn, vì vậy tôi đã làm rõ nó.
MysticMagicϡ

Tôi không muốn kiểm tra số lượng nhân vật. Tôi nghĩ rằng bạn đang cố kiểm tra số đếm trong mã này: if (TextUtils.isEmpty (pass) || pass.length <[MIN MIN LENGTH]) Tôi chỉ giới hạn giá trị ví dụ cho giá trị tháng, người dùng phải ghi giá trị giữa 1-12 chứ không phải 13,14, v.v ... Vì vậy, 12,13,14, cho đến 99 là 2 ký tự.
mertaydin

hi @mertaydin bạn đã thử với liên kết tôi đã cung cấp cho bạn .. xem ví dụ đó .. có thể đó là những gì bạn muốn. nó sẽ xem văn bản trong khi bạn đang nhập ..
Itsrajesh4uguys

Ok cảm ơn, tôi sẽ thử câu trả lời của bạn và câu trả lời của @Pratik Sharma.
mertaydin

1

Nếu bạn chỉ quan tâm đến giới hạn tối đa thì chỉ cần thêm dòng dưới đây vào

android:maxLength="10" 

Nếu bạn cần thêm giới hạn tối thiểu thì bạn có thể thực hiện theo cách này trong trường hợp này giới hạn tối thiểu là 7. người dùng bị hạn chế nhập ký tự giữa giới hạn tối thiểu và tối đa (trong khoảng từ 8 đến 10)

public final static boolean isValidCellPhone(String number){
        if (number.length() < 8 || number.length() >10 ) {
            return false;
        } else {

           return android.util.Patterns.PHONE.matcher(number).matches();
        }
    }

Nếu bạn cũng cần hạn chế người dùng nhập 01 khi bắt đầu thì hãy sửa đổi nếu điều kiện như cách này

if (!(number.startsWith("01")) || number.length() < 8 || number.length() >10 ) {  
.
.
.
}

Ở cuối phương thức gọi như

   ....else if (!(Helper.isValidMobilePhone(textMobileNo))){
                        Helper.setEditTextError(etMobileNo,"Invalid Mobile Number");
                    }......

2
Đó không phải là vlaue, đó là chiều dài
portfoliobuilder

1

@Pratik Sharma

Để hỗ trợ các số âm , hãy thêm mã sau vào phương thức lọc :

package ir.aboy.electronicarsenal;

import android.text.InputFilter;
import android.text.Spanned;

public class InputFilterMinMax implements InputFilter {

  private int min, max;
  int input;

  InputFilterMinMax(int min, int max) {
    this.min = min;
    this.max = max;
  }

  public InputFilterMinMax(String min, String max) {
    this.min = Integer.parseInt(min);
    this.max = Integer.parseInt(max);
  }

  @Override
  public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {

      if ((dest.toString() + source.toString()).equals("-")) {
        source = "-1";
      }

      input = Integer.parseInt(dest.toString() + source.toString());
      if (isInRange(min, max, input))
        return null;

    } catch (NumberFormatException ignored) {
    }
    return "";
  }

  private boolean isInRange(int a, int b, int c) {
    return b > a ? c >= a && c <= b : c >= b && c <= a;
  }

}

Sau đó sử dụng điều này từ Hoạt động của bạn:

findViewById(R.id.myEditText).setFilters(new InputFilter[]{ new InputFilterMinMax(1, 12)});

Đặt edittext của bạn với:

android:inputType="number|numberSigned"

0

// vẫn có một số vấn đề nhưng ở đây bạn có thể sử dụng min, max ở bất kỳ phạm vi nào (dương hoặc âm)

// in filter calss
 @Override
 public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        try {
            // Remove the string out of destination that is to be replaced
            int input;
            String newVal = dest.toString() + source.toString();
            if (newVal.length() == 1 && newVal.charAt(0) == '-') {
                input = min; //allow
            }
            else {
                newVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend, dest.toString().length());
                // Add the new string in
                newVal = newVal.substring(0, dstart) + source.toString() + newVal.substring(dstart, newVal.length());
                input = Integer.parseInt(newVal);
            }

            //int input = Integer.parseInt(dest.toString() + source.toString());

            if (isInRange(min, max, input))
                return null;
        } catch (NumberFormatException nfe) {
        }
        return "";
    }

//also the filler must set as below: in the edit createview
// to allow enter number and backspace.
et.setFilters(new InputFilter[]{new InputFilterMinMax(min >= 10 ?  "0" : String.valueOf(min), max >-10 ? String.valueOf(max) :"0" )});



//and at same time must check range in the TextWatcher()
et.addTextChangedListener(new
 TextWatcher() {

      @Override
      public void afterTextChanged (Editable editable)
      {
         String tmpstr = et.getText().toString();
         if (!tmpstr.isEmpty() && !tmpstr.equals("-") ) {
             int datavalue = Integer.parseInt(tmpstr);
             if ( datavalue >= min || datavalue <= max) {
               // accept data ...     
             }
         }
      }
 });

0

Để thêm vào câu trả lời của Pratik, đây là phiên bản sửa đổi, trong đó người dùng có thể nhập tối thiểu 2 chữ số, ví dụ: 15 đến 100:

 import android.text.InputFilter;
 import android.text.Spanned;

public class InputFilterMinMax implements InputFilter {

    private int min, max;

    public InputFilterMinMax(int min, int max) {
        this.min = min;
        this.max = max;
    }

    public InputFilterMinMax(String min, String max) {
        this.min = Integer.parseInt(min);
        this.max = Integer.parseInt(max);
    }

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

        try {
            if(end==1)
                min=Integer.parseInt(source.toString());
            int input = Integer.parseInt(dest.toString() + source.toString());
            if (isInRange(min, max, input))
                return null;
        } catch (NumberFormatException nfe) {
        }
        return "";
    }

    private boolean isInRange(int a, int b, int c) {

        return b > a ? c >= a && c <= b : c >= b && c <= a;
    }}

đã thêm: if (end == 1) min = Integer.parseInt (source.toString ());

Hi vọng điêu nay co ich. vui lòng không downvote mà không có lý do.


0

Đây là cách tôi đã sử dụng, nó hoạt động cho số âm

Đầu tiên, tạo lớp MinMaxFIlter.java với mã sau:

import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;

/**
* Created by 21 on 4/5/2016.
*/
public class MinMaxFilter implements InputFilter {

private double mIntMin, mIntMax;

public MinMaxFilter(double minValue, double maxValue) {
    this.mIntMin = minValue;
    this.mIntMax = maxValue;
}

public MinMaxFilter(String minValue, String maxValue) {
    this.mIntMin = Double.parseDouble(minValue);
    this.mIntMax = Double.parseDouble(maxValue);
}

@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
    try {
        Boolean isNeg = false;
        String provi = dest.toString() + source.toString();
        if("-".equals(provi.substring(0,1))){
            if(provi.length()>1) {
                provi = provi.substring(1, provi.length());
                isNeg = true;
            }
            else{
                if("".equals(source)){
                    return null;
                }
                return "-";
            }
        }

        double input = Double.parseDouble(provi); 
        if(isNeg){input = input * (-1);}

        if (isInRange(mIntMin, mIntMax, input)) {
            return null;
        }
    } catch (Exception nfe) {}
    return "";
}

private boolean isInRange(double a, double b, double c) {
    if((c>=a && c<=b)){
        return true;
    }
    else{
        return false;
    }
}
}

Sau đó, tạo và đặt bộ lọc của bạn thành edittext của bạn như thế này:

EditText edittext = new EditText(context);
editext.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
eInt.setFilters(new InputFilter[]{new MinMaxFilter(min, max)});

0

đây là mã của tôi max = 100, min = 0

xml

<TextView
                    android:id="@+id/txt_Mass_smallWork"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="#000"
                    android:textSize="20sp"
                    android:textStyle="bold" />

java

EditText ed = findViewById(R.id.txt_Mass_smallWork);
    ed.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) {
            if(!charSequence.equals("")) {
                int massValue = Integer.parseInt(charSequence.toString());
                if (massValue > 10) {
                    ed.setFilters(new InputFilter[]{new InputFilter.LengthFilter(2)});
                } else {
                    ed.setFilters(new InputFilter[]{new InputFilter.LengthFilter(3)});
                }
            }
        }

        @Override
        public void afterTextChanged(Editable editable) {

        }
    });

0

Bạn có thể làm điều này với InputFilter. Rõ ràng chỉ có Giao diện bộ lọc đầu vào mà bạn có thể sử dụng. Trước khi bạn thực hiện theo cách khó chịu khi tạo Lớp mới mở rộng bộ lọc Đầu vào, bạn có thể sử dụng lối tắt này với tính năng khởi tạo Giao diện trong lớp.

Vì vậy, bạn chỉ cần làm điều này:

EditText subTargetTime = (EditText) findViewById(R.id.my_time);
subTargetTime.setFilters( new InputFilter[] {
                new InputFilter() {
                    @Override
                    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                        int t = Integer.parseInt(source.toString());
                        if(t <8) { t = 8; }
                        return t+"";

                    }
                }
        });

Trong ví dụ này, tôi kiểm tra xem giá trị của EditText có lớn hơn 8. Nếu không, nó sẽ được đặt thành 8. Vì vậy, bạn cần phải tự mình kiểm tra tối đa hoặc bất kỳ logic bộ lọc nào. Nhưng ít nhất bạn có thể viết logic bộ lọc khá gọn gàng và ngắn trực tiếp vào EditText.

Hi vọng điêu nay co ich


0

Để xác định giá trị tối thiểu của EditText, tôi đã sử dụng:

if (message.trim().length() >= 1 && message.trim().length() <= 12) {
  // do stuf
} else {
  // Too short or too long
}

0

Mã của @ Patrik có một ý tưởng hay nhưng có rất nhiều lỗi. @Zac và @Anthony B (giải pháp số âm) đã giải quyết một số trong số chúng, nhưng mã của @ Zac vẫn có 3 lỗi thị trưởng:

1. Nếu người dùng xóa tất cả các mục trong EditText, bạn không thể nhập lại bất kỳ số nào .. Tất nhiên điều này có thể được kiểm soát bằng cách sử dụng trình nghe đã thay đổi EditText trên mỗi trường, nhưng nó sẽ xóa đi vẻ đẹp của việc sử dụng lớp InputFilter chung cho mỗi EditText trong ứng dụng của bạn.

2. Có @ Guernee4 nói, nếu ví dụ min = 3, không thể nhập bất kỳ số nào bắt đầu bằng 1.

3. Nếu ví dụ min = 0, bạn có thể nhập có nhiều số không bạn muốn, đó không phải là kết quả tao nhã. Hoặc cũng vậy, nếu không có giá trị tối thiểu là gì, người dùng có thể đặt con trỏ ở kích thước bên trái của số đầu tiên, đặt một số các số 0 đứng đầu bên trái, cũng không thanh lịch.

Tôi đã đưa ra những thay đổi nhỏ trong mã của @ Zac để giải quyết 3 lỗi này. Về lỗi số 3, tôi vẫn chưa thể loại bỏ hoàn toàn các số 0 đứng đầu bên trái; Nó luôn luôn có thể là một, nhưng 00, 01, 0100, v.v. trong trường hợp đó, thanh lịch hơn một giá trị hợp lệ là 000000, 001, 000100, v.v. Vân vân.

Đây là mã:

@Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        try {

            // Using @Zac's initial solution
            String lastVal = dest.toString().substring(0, dstart) + dest.toString().substring(dend);
            String newVal = lastVal.substring(0, dstart) + source.toString() + lastVal.substring(dstart);
            int input = Integer.parseInt(newVal);

            // To avoid deleting all numbers and avoid @Guerneen4's case
            if (input < min && lastVal.equals("")) return String.valueOf(min);

            // Normal min, max check
            if (isInRange(min, max, input)) {

                // To avoid more than two leading zeros to the left
                String lastDest = dest.toString();
                String checkStr = lastDest.replaceFirst("^0+(?!$)", "");
                if (checkStr.length() < lastDest.length()) return "";

                return null;
            }
        } catch (NumberFormatException ignored) {}
        return "";
    }

Chúc một ngày tốt lành!


-1

Đây là câu trả lời của tôi cho câu trả lời của Pratik Sharma KotlinDoublenếu có ai cần nó

class InputFilterMinMax : InputFilter {

private var min: Double = MIN_LIMIT
private var max: Double = MIN_LIMIT

constructor(min: Int, max: Int) {
    this.min = min.toDouble()
    this.max = max.toDouble()
}

constructor(min: String, max: String) {
    this.min = min.toDouble()
    this.max = max.toDouble()
}

constructor(min: Double, max: Double) {
    this.min = min
    this.max = max
}

override fun filter(
    source: CharSequence,
    start: Int,
    end: Int,
    dest: Spanned,
    dstart: Int,
    dend: Int
): CharSequence? {
    try {
        val input = (dest.toString() + source.toString()).toDouble()
        if (isInRange(min, max, input))
            return null
    } catch (nfe: NumberFormatException) {
        Timber.e(nfe)
    }

    return ""
}

private fun isInRange(a: Double, b: Double, c: Double): Boolean {
    return if (b > a) c in a..b else c in b..a
}
}

Bộ lọc đầu vào này sai, nó bỏ qua các chỉ số bắt đầu, kết thúc, dstart, dend của văn bản, vì vậy nếu bạn thay đổi văn bản chỉnh sửa bằng cách chèn một ký tự ở giữa, nó sẽ không hoạt động chính xác
Radu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.