5

AutoCompleteTextViewが3つあり、それらに2つのString[]アダプターを登録したいと思います。現在、私はこれを行っています:

atw_from.setAdapter(new ArrayAdapter(ctx, android.r.layout.simple_dropdown_item_1line, stages_adapter));

私のユーザーが「Középmező」と入力したいとします。彼は「Közé」と入力し始め、Középmezőを選択するように提案されます。これまでは非常に簡単です。しかし、ユーザーがアクセントを入力するのが面倒である(そしてそれらの多くが怠惰である)場合、彼はKozepmezoのみを入力し、私のString []にKozepmezoがないため、オファーを受け取りません。私が欲しいのは、彼が「Koze」と入力した場合、彼はKözépmezőを提供されるはずなので、アクセントを使用しなくても、彼は常にアクセント付きの実際の単語を提供されます。

現在、私にはかなりばかげた解決策があります。元の[]の2倍のサイズのString []があり、前半にはアクセント付きの単語が含まれ、後半にはアクセントのないバージョンが含まれています。つまり、彼がKözéと入力すると、Középmezőが提供され、Kozeと入力すると、Kozepmezoが提供されます。サーバーは両方のバージョンを処理できるので機能しますが、見た目はばかげているので、解決したいと思います。

私が理解していることから、完全なカスタムアダプタを作成する必要があります。それが最善のアプローチですか、それともSDKに含まれているソリューションはありますか?カスタムアダプタを作成する必要がある場合、その方法について誰かが私を正しい方向に向けることができますか?:)

編集:私自身の答えを追加しました、すべての人のために働くはずです、他の答えを応援してください、それは私を良い方向に導きました!

4

3 に答える 3

1

私は確かにカスタムアダプターを選びます。このアダプターでは、アクセント付きとアクセントなしの両方の表記に一致する独自のフィルター関数を提供します。

それを実行する実装例は、ここにあります。基本的に、実際のフィルタリングを実装する必要がありperformFilteringます。現在、アクセントのないバージョンを使用しているため、クエリのアクセントを解除する方法がすでにあるString[]と思います。アクセントがある場合とない場合のクエリを、配列内のエントリ(アクセントがある場合とない場合で使用する)と比較する必要があります。最終的には、少なくとも次の4つのテストが必要です。

accented(query) -> accented(entry)
accented(query) -> deaccented(entry)
deaccented(query) -> accented(entry)
deaccented(query) -> deaccented(entry)

オンザフライで単語のアクセントを解除することによりString[]、アクセントのある単語を提供するだけで済みますが、(アダプター内の)フィルタリングロジックが(アクセントのない)単語との照合を処理します。

編集:説明したように、進行中のプロジェクトの1つでの実装例を以下に示します。

いくつかのポインタ:

  1. CustomArrayAdapterほとんどの場合、一般的なタスクを簡素化するラッパークラスです。たとえば、行ラッパー/ビューホルダーとの相互作用。基本的に必要なのは、のコンストラクターと実装だけです(これは明らかにスーパークラスのメソッドupdateRowから呼び出されます)。getView
  2. CustomRowWrapperかなり簡単なはずです。
  3. ArrayUtilArrayUtil.FilterFuction実際のフィルタリングに注意してください。簡単に言うと、これらは、いくつかの基準に一致するすべてのアイテムの新しいリストを作成するforループの代わりとして機能します。

public class CARMedicationSuggestionAdapter extends CustomArrayAdapter<CARMedicationInfo, RowWrapper> {

    private List<CARMedicationInfo> mMedications;
    private Filter mFilter;

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
     * constructor
     * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    public CARMedicationSuggestionAdapter(Context context, List<CARMedicationInfo> objects) {
        super(RowWrapper.class, context, R.layout.medication_suggestion_item_layout, objects);
        // keep copy of all items for lookups 
        mMedications = new ArrayList<CARMedicationInfo>(objects);
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
     * update row
     * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    @Override protected void updateRow(RowWrapper wrapper, CARMedicationInfo item) {
        wrapper.getNameTextView().setText(item.toString());
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
     * get filter
     * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    @Override public Filter getFilter() {
        // return if already created
        if (mFilter != null) return mFilter;
        mFilter = new Filter() {
            @Override protected void publishResults(CharSequence constraint, FilterResults results) {
                @SuppressWarnings("unchecked") List<CARMedicationInfo> filtered = (List<CARMedicationInfo>) results.values;
                if (results == null || results.count == 0) return;
                // clear out current suggestions and add all new ones
                clear(); 
                addAll(filtered);
            }

            @Override protected FilterResults performFiltering(final CharSequence constraint) {
                // return empty results for 'null' constraint
                if (constraint == null) return new FilterResults();
                // get all medications that contain the constraint in drug name, trade name or whose string representation start with the constraint
                List<CARMedicationInfo> suggestions = ArrayUtil.filter(mMedications, new ArrayUtil.FilterFunction<CARMedicationInfo>() {
                    @Override public boolean filter(CARMedicationInfo item) {
                        String query = constraint.toString().toLowerCase().trim();
                        return  item.mMedicationDrugName.toLowerCase().contains(query) || 
                                item.mMedicationTradeName.toLowerCase().contains(query) ||
                                item.toString().toLowerCase().startsWith(query); 
                    }
                });
                // set results and size
                FilterResults filterResults = new FilterResults();
                filterResults.values = suggestions;
                filterResults.count = suggestions.size();
                return filterResults;
            }
        };
        return mFilter;
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
     * row wrapper
     * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    static class RowWrapper extends CustomRowWrapper {

        private ImageView mIconImageView;
        private TextView mNameTextView;

        public RowWrapper(View row) {
            super(row);
        }

        public ImageView getIconImageView() {
            if (mIconImageView == null) mIconImageView = (ImageView) mRow.findViewById(R.id.icon_imageview);
            return mIconImageView;
        }

        public TextView getNameTextView() {
            if (mNameTextView == null) mNameTextView = (TextView) mRow.findViewById(R.id.name_textview);
            return mNameTextView;
        }

    }

}
于 2012-04-04T19:38:27.063 に答える
1

さて、これに対処するお尻に多くの苦痛を与えた後、これが私が最後にしたことです。これはまったく良い習慣ではなく、間違っているかもしれませんが、少なくとも今は完全に機能しています。

単にctrl+c、ctrl + v BaseAdapterのソースコード、およびctrl + c、ctrl+ vArrayAdapterのソースコードです。次に、プライベート内部クラスであるArrayFilter、特にperformFilteringメソッドを見てください。必要に応じて変更(オーバーライドしないでください!)します。私の場合は、アクセントを外す部分に.replace( "x"、 "y")をたくさん追加しました。

他に何を試しても、予測できない強制終了(多く、完全にランダムなもの)が生成されたか、保護されているのではなくプライベートなメソッド/変数が多すぎるため、実行できませんでした。私は言わなければならない、Googleはこれらのコードを再検討する必要があります...

注:BaseAdapterコードはパブリック抽象クラスであるため、実際にはctrl + c ctrl + vする必要はありませんが、それほど多くのコードではないため、すべてがそこにあり、はっきりと表示されます。 。

乾杯

于 2012-04-10T09:26:34.473 に答える
0

このスレッドremove-accents-from-stringおよびandroidNormalizerクラスを見てください

[編集]または、両方のアレイでマージアダプターを試すことができます

于 2012-04-01T14:03:59.143 に答える