AutoCompleteTextView
ユーザーに提案を表示するためにを提供しました。ユーザーが選択したアイテムに基づいて、アイテムのIDを取得し、データベース側で使用しています。今私の問題は、ユーザーに選択を強制することですAutoCompleteTextView
(つまり、ユーザーは自分のテキストを入力しないでください)。これはクライアントの要件です。これを行う方法?
9 に答える
これは非常に簡単な解決策です:
で設定することにより、選択した値を格納する変数を作成できsetOnItemClickListener
ますAutoCompleteTextView
。次にnull
、ユーザーがフィールドにaを追加することで、フィールドに入力するたびにその値を指定できますTextWatcher
。最後に、続行する前に、変数がnullでないことを検証できます。
String my_var; //keep track!
AutoCompleteTextView tv = (AutoCompleteTextView) layout.findViewById(R.id.tv);
tv.setAdapter(my_adapter);
tv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
my_var = my_adapter.getItem(position).toString();
}
});
/**
* Unset the var whenever the user types. Validation will
* then fail. This is how we enforce selecting from the list.
*/
tv.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
my_var = null;
}
@Override
public void afterTextChanged(Editable s) {}
});
私が取り組んでいるプロジェクトには、たまたまそのような要件が必要でした。必要なものを実装した方法を皆さんと共有しますが。
オートコンプリートテキストビューにフォーカス変更リスナーを追加し、ユーザーがオートコンプリートからフォーカスを変更したかどうかを確認し、状況を簡単に処理しました。
autoTextViewCountry.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
if(!b) {
// on focus off
String str = autoTextViewCountry.getText().toString();
ListAdapter listAdapter = autoTextViewCountry.getAdapter();
for(int i = 0; i < listAdapter.getCount(); i++) {
String temp = listAdapter.getItem(i).toString();
if(str.compareTo(temp) == 0) {
return;
}
}
autoTextViewCountry.setText("");
}
}
});
したがって、私の実装は次のとおりです。入力したテキストが配列アダプターに存在しない場合は、フォーカスを変更してテキストビューを空にし、後で登録の次の段階に進むときに、このテキストビューが空かどうかを確認します。
このアプローチが誰かに役立つことを願っています。
ハッピーコーディング。
NiceAutoCompleteTextViewを使用すると、を呼び出すことにより、ドロップダウンポップアップから選択が行われたかどうかを確認できます。isSelectionFromPopup()
このプロパティをAutoCompleteTextViewに追加するだけです。
android:focusable = "false"
私のコードは次のようになります:
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/menu"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Mode">
<AutoCompleteTextView
android:id="@+id/mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
/>
</com.google.android.material.textfield.TextInputLayout>
Java側:
AutoCompleteTextView mode = findViewById(R.id.mode);
final List<String> modeList = new ArrayList();
modeList.add("YEARLY");
modeList.add("HALF-YEARLY");
modeList.add("QUARTER-YEARLY");
modeList.add("MONTHLY");
mode.setAdapter(new ArrayAdapter(getApplicationContext(),R.layout.list_item,modeList));
AutoCompleteTextViewのテキストを取得するには:
mode.getText().toString()
わかりました。ユーザーの入力を、提案ボックスにリストされている項目のリストに含まれているテキストに制限したいと思います。
たとえば、次の場合:
- 1
- 二
- 三
その場合、ユーザーは最初の文字「O」と「T」のみを入力できます。前に入力したテキストに従って、以下同様に続きます。
これを実現するには、 TextViewのsetFiltersメソッドを利用できます。
editBox = (TextView) findViewById(R.id.editBox);
editBox.setFilters(getFilters());
editBox.addTextChangedListener(this);
editBox.setOnFocusChangeListener(this);
さらに、新しい文字が入力されたときに、フィルターされたリストに反応して更新するために、テキスト変更リスナーとフォーカスリスナーが必要になる可能性があります...さらに、フィルターを更新します。
プロジェクトで使用した10進数フィルターの例を次に示します。
protected InputFilter[] getFilters()
{
InputFilter[] filters = new InputFilter[1];
filters[0] = new InputFilter()
{
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
{
// limit input to digits and decimal / thousand separator only
// in case thousand separator is pressed, change it to decimal
// separator instead
String output = "";
if (number.isFocused())
{
for (int i = start; i < end; i++)
{
char c = source.charAt(i);
if (isDecimalOrThousandSeparator(c))
{
output = output + Character.toString(decimalSeparator);
}
else if (Character.isDigit(c))
{
output = output + Character.toString(c);
}
}
return output == "" ? null : output;
}
return null;
}
};
return filters;
}
簡単な解決策は、現在の入力がアダプタの項目の1つであるかどうかを確認することです。あなたはこのようにそれを行うことができます:
val AutoCompleteTextView.isValid: Boolean
get() {
for (i in 0 until adapter.count) {
if (adapter.getItem(i) == text.toString()) {
return true
}
}
return false
}
これが、このプロAutoCompleteTextView.Validator
が有効な値を確保するための別の解決策です。編集テキストがフォーカスを失うと、バリデーターが呼び出されます。
autoCompleteTextView.validator = object : AutoCompleteTextView.Validator {
override fun isValid(text: CharSequence?): Boolean {
return optionsList.contains(text.toString())
}
override fun fixText(invalidText: CharSequence?): CharSequence {
return ""
}
}
optionsList
有効な値のリストはどこにありますか。
私は同じ要件を持っていたので、ここに私の実装があります:
autoCompleteTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
autoCompleteTextView.showDropDown();
}
});
xmlセットfocusable=false
とfocusableInTouchMode=false
。
ハッピーコーディング
AutoCompleteTextViewの編集不可能なバリエーションを使用するには、AutoCompleteTextViewでのユーザー入力を無効にする必要があります。これは、AutoCompleteTextViewでandroid:inputType="none"を設定することで実現できます。