達成された効果を見てみましょう。
[外部リンクの画像転送に失敗しました。ソースサイトに盗難防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-MUbDEIhT-1614134109259)(https:/ /img-blog.csdn.net / 20161219001816589?watermark / 2 / text / aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbmV3X0FpZGVu / font / 5a6L5L2T / fontsize / 400 / fill / I0JBQkFCMA == / dissolve / 70 / gravity / Southチェーン画像、盗難防止メカニズム画像を保存して直接アップロードすることをお勧めします(img-exmfZ1S3-1614134109262)(https://img-blog.csdn.net/20161219001827886?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbmV3X0FpZGVu/font/ 5a6L5L2T / font0size = 400 / resolve / 70 / gravity / SouthEast)]
私たちが言うように、それは自動プロンプト機能です。ここで、AppCompatAutoCompleteTextViewをクリックすると、プロンプトボックスがポップアップし、コンテンツが入力されていないときにプロンプトボックスが表示されることに気付きました。ここでは主に使用法に精通しています。APIは他にもたくさんありますので、ご自身でご理解ください。。。
例で提案されている内容は言語であるため、クラス
Language.javaが作成されます
public class Language {
public String name;
public int icon;
}
子アイテムのレイアウトファイルitem.xml。ここはとても簡単なようです。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:gravity="center_vertical"
android:layout_weight="1"
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="50dp" />
<ImageView
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:id="@+id/icon"/>
</LinearLayout>
アクティビティレイアウトファイルactivity_main.xml
<com.test.MyAutoCompleteTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv_test"
android:layout_width="match_parent"
android:layout_height="80dp"
android:dropDownHeight="200dp"
android:hint="language" />
AppCompatAutoCompleteTextViewを継承する必要があるのはなぜですか?その理由は、システムにAppCompatAutoCompleteTextViewが付属している場合、入力ボックスのコンテンツの長さは少なくとも1より大きくなければならないためです。ただし、コンテンツを入力せずにプロンプトを表示する必要がある場合があるため、AppCompatAutoCompleteTextViewを書き直す必要があります。
MyAutoCompleteTextView .java
public class MyAutoCompleteTextView extends AppCompatAutoCompleteTextView {
public MyAutoCompleteTextView(Context context) {
super(context);
}
public MyAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean enoughToFilter() {
return true;
}
}
実際、MyAutoCompleteTextViewクラスが少し冗長であることを示しています。つまり、十分なToFilter()メソッドを書き換えて、常にtrueを返します。興味がある場合は、付属のAutoCompleteTextViewが返すものを確認できます。
次に、Adapter forMyAutoCompleteTextViewを記述します。ここで直接ArrayAdapterを使用します。実際、特別なニーズがない場合、ArrayAdapterは私たちの大きなニーズを満たすことができます。実際、上記の関数は必ずフィルター(フィルタリング関数)を使用する必要があります。ArrayAdapterは、Filterableインターフェイスを実装することを宣言しました。しかし、関数をよりよく理解するために、私はまだFilterableインターフェースを実装することを宣言します。
MyAdapter.javaは、
最初にいくつかの変数を宣言する必要があります
// 经过过滤的数组
private ArrayList<Language> languages;
// 没有经过过滤的数组
private ArrayList<Language> origin;
private Context context;
private int layoutId;
コア変数は言語と起源です。
コンストラクターは、これらの変数に順番に値を割り当てます。
public MyAdapter(Context context, int resource, ArrayList<Language> languages) {
super(context, resource);
this.languages = languages;
this.origin = languages;
this.context = context;
this.layoutId = resource;
}
ここで2つのメソッドを書き直すのが最善です。1つはgetItem()で、もう1つはgetCount()です。書かないと表示されない場合があります
@Override
public Language getItem(int position) {
return languages == null ? null : languages.get(position);
}
@Override
public int getCount() {
return languages == null ? 0 : languages.size();
}
キャッシュを実現するには、getViewメソッドを作成する必要があります。したがって、最初にviewHolderをMyAdapterの内部クラスとして定義する必要があります。
private class ViewHolder {
TextView name;
ImageView icon;
}
さて、getView()を書いてください
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
ViewHolder holder;
if(null == convertView) {
convertView = LayoutInflater.from(context).inflate(layoutId, parent, false);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.name.setText(languages.get(position).name);
holder.icon.setBackgroundResource(languages.get(position).icon);
return convertView;
}
ビューに付属するsetTagメソッドとgetTagメソッドを使用して、ビューの再利用を実現します。
前述のように、MyAdapterの宣言は次のようになります
public class MyAdapter extends ArrayAdapter implements Filterable
getFilter()メソッドを書き直す。
最初にフィルターをカスタマイズしましょう
private class MyFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if(null == constraint || 0 == constraint.length()) {
constraint = "";
}
// 这里做一些简单的过滤
String condition = String.valueOf(constraint).toLowerCase();
List<Language> temp = new ArrayList<>();
for (Language language : origin) {
if (language.name.toLowerCase().contains(condition)) {
temp.add(language);
}
}
results.values = temp;
results.count = temp.size();
// 返回的results会在publishResult()函数中得到
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
languages = (ArrayList<Language>) results.values;
// 更新视图
notifyDataSetChanged();
}
}
これは簡単で、getFilter()メソッドからMyFilterオブジェクトを返すだけです。
public Filter getFilter() {
return new MyFilter();
}
さて、上記の言葉、MyAdapterが完成しました。
その後、アクティビティで使用できます。
MainActivity.java
// 初始化数据
final ArrayList<Language> languages = new ArrayList<>();
Language one = new Language();
one.name = "Java";
one.icon = R.mipmap.java;
languages.add(one);
Language two = new Language();
two.name = "c";
two.icon = R.mipmap.c;
languages.add(two);
Language three = new Language();
three.name = "Python";
three.icon = R.mipmap.python;
languages.add(three);
Language four = new Language();
four.name = "gradle";
four.icon = R.mipmap.gradle;
languages.add(four);
Language five = new Language();
five.name = "php";
five.icon = R.mipmap.php;
languages.add(five);
Language six = new Language();
six.name = "groovy";
six.icon = R.mipmap.groovy;
languages.add(six);
上記のアイコンはすべて自分でダウンロードしているので、自由にダウンロードしました。
アダプターを使用する
MyAdapter myAdapter = new MyAdapter(this, R.layout.item, languages);
final MyAutoCompleteTextView textView = (MyAutoCompleteTextView) this.findViewById(R.id.tv_test);
textView.setAdapter(myAdapter);
インタラクションプロセスをさらに改善するために、MyAutoCompleteTextViewをクリックすると、プロンプトコンテンツもポップアップ表示されます。
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textView.showDropDown();
}
});
また、MyAutoCompleteTextViewのサブアイテムは、クリックされたときにも表示されますか?幸いなことに、MyAutoCompleteTextViewにはsetOnItemClickListenerメソッドがあります。これはListViewに少し似ています。
textView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Language language = myAdapter.getItem(position);
textView.setText(language.name);
}
});
最後に、ここでAutoCompleteTextViewの代わりにAppCompatAutoCompleteTextViewを使用する理由。AppCompatAutoCompleteTextViewはAndroidシステムの優れたバージョンとの互換性が高いため、AppCompatAutoCompleteTextViewを使用してください
AppCompatAutoCompleteTextViewに関しては、他にも強力な関数があります。自分で調べて、基本的な使用法を知っている必要があります。他の関数は難しくありません。
実際、AppCompatAutoCompleteTextView内にListPopupWindowがあり、プロンプトの内容はListPopupWindowによって実現されます。また、ListPopupWindowはListView + PopupWindowとして理解できます。実際、つまり、AppCompatAutoCompleteTextViewを自分で実装し、入力ボックスとPopupWindowを含むViewをカスタマイズでき、PopupWindowにはListViewがあります。。。互換性の問題を考慮しなければ、実装はそれほど難しくないはずです。