আমি জানি যে এর একটি মিলিয়ন উত্তর ইতিমধ্যে গ্রহণ করা আছে। যাইহোক, গৃহীত উত্তরে অসংখ্য বাগ রয়েছে এবং সমস্ত সম্ভাব্য ব্যবহারের ক্ষেত্রে প্রসারিত না করেই বাকিগুলির বেশিরভাগই কেবল তার মধ্যে একটি (বা দুটি) ঠিক করতে পারেন।
সুতরাং আমি মূলত সমর্থন উত্তরগুলিতে প্রস্তাবিত বেশিরভাগ বাগ ফিক্সগুলি সংকলন করার পাশাপাশি 0 এর দিকে সীমার বাইরে সংখ্যার একটানা ইনপুটকে অনুমতি দেওয়ার জন্য একটি পদ্ধতি যুক্ত করে (যদি রেঞ্জটি 0 থেকে শুরু না হয়) তবে কমপক্ষে এটি না হওয়া পর্যন্ত নিশ্চিত যে এটি আর সীমাতে থাকতে পারে না। পরিষ্কার হওয়ার কারণ, এটি কেবলমাত্র অন্যান্য সময়গুলির সমাধানের সাথেই সমস্যা সৃষ্টি করে।
এখানে ঠিক আছে:
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("");
}
}
}
নোট করুন যে কিছু ইনপুট কেসগুলি "সক্রিয়ভাবে" পরিচালনা করা অসম্ভব (যেমন, ব্যবহারকারী এটি আউটপুট দিচ্ছে), তাই ব্যবহারকারীকে পাঠ্য সম্পাদনা করার পরে আমাদের তাদের অবশ্যই এড়ানো এবং সেগুলি পরিচালনা করতে হবে।
আপনি এটি কীভাবে ব্যবহার করতে পারেন তা এখানে:
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);
এখন, ব্যবহারকারী যখন পরিসরের অনুমতি চেয়ে 0 এর কাছাকাছি একটি সংখ্যা টাইপ করার চেষ্টা করবে, তখন দুটি জিনিসের একটি ঘটবে:
যদি min
এবংmax
একই সংখ্যার সংখ্যা থাকে তবে তারা চূড়ান্ত অঙ্কটিতে পৌঁছানোর পরে একে একে ইনপুট করার অনুমতি পাবে না।
পাঠ্যটি ফোকাস হারিয়ে ফেললে যদি ক্ষেত্রের মধ্যে যদি রেঞ্জের বাইরের একটি নম্বর ছেড়ে যায় তবে এটি স্বয়ংক্রিয়ভাবে নিকটতম সীমানায় সামঞ্জস্য হবে।
এবং অবশ্যই, ব্যবহারকারীর দ্বারা পরিসীমা অনুমতি দেয় না তার চেয়ে বেশি 0 থেকে একটি মান ইনপুট করার অনুমতি দেওয়া হবে না এবং এই জাতীয় সংখ্যার পক্ষে "দুর্ঘটনাক্রমে" এই কারণে পাঠ্য ক্ষেত্রে থাকতে পারে না।
জ্ঞাত সমস্যা?)
- এটি কেবল
EditText
তখনই কার্যকর হয় যখন ব্যবহারকারীর সাথে এটি করা হয়ে গেলে ফোকাস হারায়।
অন্য বিকল্পটি স্যানিটাইজিং হয় যখন ব্যবহারকারী "সম্পন্ন" / রিটার্ন কীটি হিট করে তবে অনেক বা এমনকি বেশিরভাগ ক্ষেত্রেই এটি ফোকাস হ্রাস করে causes
তবে নরম কীবোর্ড বন্ধ করা স্বয়ংক্রিয়ভাবে উপাদানটিকে আন-ফোকাস করবে না । আমি নিশ্চিত যে ৯৯.৯৯% অ্যান্ড্রয়েড বিকাশকারী এটি করতে চান (এবং যে EditText
উপাদানগুলিতে ফোকাস পরিচালনা করা সাধারণভাবে একটি চৌম্বক কম ছিল) তবে এখনও এর জন্য কোনও অন্তর্নির্মিত কার্যকারিতা নেই। এটির সন্ধান করার জন্য আমি সবচেয়ে সহজ পদ্ধতিটি খুঁজে পেয়েছি, যদি আপনার প্রয়োজন হয় তবে তা EditText
এই জাতীয় কিছু প্রসারিত করুন :
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);
}
}
এটি ফিল্টারটিকে "চালিত করে" ইনপুটটিকে স্বাস্থ্যকরকরণে সক্রিয় করবে যদিও ভিউ আসলে ফোকাসটি হারিয়েছে না । পরে যদি দৃষ্টিভঙ্গিটি তার নিজের মনোযোগ হারিয়ে ফেলতে পারে তবে ইনপুট স্যানিটেশন আবার ট্রিগার করবে, তবে এটি ইতিমধ্যে ঠিক হয়ে যাওয়ার পরে কিছুই পরিবর্তন হবে না।
বন্ধ
রক্ষে। এটা অনেক ছিল। মূলত যা দেখে মনে হচ্ছিল এটি একটি খুব তুচ্ছ সহজ সমস্যা ভ্যানিলা অ্যান্ড্রয়েডের কিছুটা কুরুচিপূর্ণ টুকরো উন্মুক্ত করে (অন্তত জাভাতে)। এবং আবারও, আপনাকে কেবল শ্রোতা যুক্ত করতে হবে এবং প্রসারিত করতে হবে EditText
যদি আপনার পরিসরটি কোনও উপায়ে 0 টি অন্তর্ভুক্ত না করে। (এবং বাস্তববাদী, যদি আপনার পরিসীমা 0 টি অন্তর্ভুক্ত না করে তবে 1 বা -1 থেকে শুরু হয় তবে আপনি সমস্যাগুলির মধ্যেও পড়বেন না))
একটি সর্বশেষ নোট হিসাবে, এটি কেবল ints জন্য কাজ করে । দশমিক ( double
, float
) দিয়ে কাজ করার জন্য এটি অবশ্যই বাস্তবায়নের একটি উপায় রয়েছে তবে যেহেতু আমার বা মূল জিজ্ঞাসাকারীর কোনওটির প্রয়োজন নেই, তাই আমি বিশেষভাবে এটি সমস্ত গভীরভাবে পেতে চাই না। নিম্নলিখিত লাইনগুলির সাথে কেবল সমাপ্তির পরবর্তী ফিল্টারিংটি ব্যবহার করা খুব সহজ হবে:
// 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;
আপনি শুধুমাত্র পরিবর্তিত করতে হবে int
করতে float
(বা double
), একটি একক ঢোকানোর অনুমতি .
(অথবা ,
, দেশের উপর নির্ভর করে?), এবং একটি পরিবর্তে দশমিক ধরনের এক হিসাবে পার্স int
।
এটি বেশিরভাগ কাজ পরিচালনা করে যাইহোক, তাই এটি খুব একইভাবে কাজ করবে would