-1

リストのフィルタリング中に問題に直面しています.onTextChange()メソッドを使用しています.正常に動作していますが、編集テキストに1文字を入力するとソフトキーボードが消え、編集テキストをもう一度タップして入力する必要があるという問題があります完全な文字列。テキストの変更後にソフトキーボードが消えないようにコードも作成しましたが、入力するにはテキストの編集をタップする必要があります。コードは次のとおりです。

 search.addTextChangedListener(new TextWatcher() {
        @ Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub
            String startwith = s.toString();
            ArrayList < Myshares > filterList = new ArrayList < Myshares > ();
            for (int i = 0; i < fileList.size(); i++) {
                if (fileList.get(i).getName().toLowerCase().startsWith(startwith) || fileList.get(i).getName().toUpperCase().startsWith(startwith)) {
                    filterList.add(fileList.get(i));
                }
            }
            adapter = new MListAdapter(PlayListActivity.this, filterList);

            playListView.setAdapter(adapter);
            adapter.notifyDataSetChanged();

        }
        @
        Override
        public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {    
        }
        @
        Override
        public void afterTextChanged(Editable s) {
            search.setSelection(search.getText().length());
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.showSoftInput(search, InputMethodManager.SHOW_IMPLICIT);
        }
    });

編集テキストのxmlコードは次のとおりです。

<EditText
         android:ems="10"
        android:id="@+id/search_bar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:layout_weight="2"
        android:background="@drawable/searchbox"
        android:editable="true"
        android:focusable="true"
        android:inputType="textFilter"
        android:hint="Search"
        android:keepScreenOn="true"
        android:paddingLeft="10dp"
        android:textSize="15dp" />

また、リスト ビューで android:focusable="false " プロパティを設定して、ソフト キーボードと重ならないようにしました。しかし、編集テキストの問題は依然として同じです。スクリーンショットは次のとおりです。

ここに画像の説明を入力

挿入すると、単一の文字リストがフィルターを取得し、編集テキスト ボックスからカーソルが消えます。

ここに画像の説明を入力

4

3 に答える 3

1

ArrayAdapter の実際のソース コードを調べたところ、実際にはそのように動作するように記述されているようです。

ArrayAdapter にはまず、mObjects と mOriginalValues の 2 つのリストがあります。mObjects は、アダプタが使用する主要なデータ セットです。たとえば、 add() 関数を使用します。

public void add(T object) {
    if (mOriginalValues != null) {
    synchronized (mLock) {
        mOriginalValues.add(object);
        if (mNotifyOnChange) notifyDataSetChanged();
    }
 } else {
    mObjects.add(object);
    if (mNotifyOnChange) notifyDataSetChanged();
 }

}

mOriginalValues は最初は null であるため、すべての操作 (追加、挿入、削除、クリア) はデフォルトで mObject を対象としています。これは、リストでフィルタリングを有効にして実際に実行することを決定するまでは問題ありません。初めてフィルタリングすると、mOriginalValues が mObjects が持っているもので初期化されます。

 private class ArrayFilter extends Filter {
     @Override
     protected FilterResults performFiltering(CharSequence prefix) {
    FilterResults results = new FilterResults();
    if (mOriginalValues == null) {
        synchronized (mLock) {
            mOriginalValues = new ArrayList<T>(mObjects);
            //mOriginalValues is no longer null
        }
    }
    if (prefix == null || prefix.length() == 0) {
        synchronized (mLock) {
            ArrayList<T> list = new ArrayList<T>(mOriginalValues);
            results.values = list;
            results.count = list.size();
        }
     } else {
        //filtering work happens here and a new filtered set is stored in newValues
        results.values = newValues;
        results.count = newValues.size();
     }
     return results;
  }
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
    //noinspection unchecked
    mObjects = (List<T>) results.values;
    if (results.count > 0) {
        notifyDataSetChanged();
     } else {
        notifyDataSetInvalidated();
     }
  }
 }

mOriginalValues には、元の値/アイテムのコピーが含まれるようになったため、アダプターはその作業を実行し、事前にフィルター処理されたデータを失うことなく、mObjects を介してフィルター処理されたリストを表示できます。

私の考えが間違っている場合は申し訳ありませんが、mOriginalValues が null ではなくなったため、以降のすべてのアダプター操作の呼び出しで mOriginalValues のみが変更されるため、これは奇妙に感じます。ただし、アダプタは mObjects をプライマリ データ セットとして参照するように設定されているため、何も起こっていないように画面に表示されます。それは、別のラウンドのフィルタリングを実行するまでです。フィルターを削除すると、次のようになります。

    if (prefix == null || prefix.length() == 0) {
        synchronized (mLock) {
            ArrayList<T> list = new ArrayList<T>(mOriginalValues);
            results.values = list;
            results.count = list.size();
        }
    }

最初のフィルター以降に変更してきた mOriginalValues は (画面上では確認できませんでしたが) 別のリストに保存され、mObjects にコピーされ、最終的に行われた変更が表示されます。それでも、この時点からはこのようになります。すべての操作は mOriginalValues で行われ、変更はフィルタリング後にのみ表示されます。

解決策として、現時点で私が思いついたのは、(1) 進行中のフィルタリングがあるかどうかをアダプター操作に伝えるブール値フラグを配置することです。フィルタリングが完了した場合は、コンテンツをコピーします。 mOriginalValues を mObjects に変換するか、(2) 単にアダプターの Filter オブジェクトを呼び出し、空の文字列 *.getFilter().filter("") を渡して、すべての操作の後にフィルターを強制します [Santhosh も提案しています]。

誰かがこの問題にさらに光を当てたり、私がしたことを確認したりしていただければ幸いです。ありがとうございました!

于 2013-05-17T07:01:49.030 に答える
0
//ArrayAdapter Definition. Make it activity class field.
ArrayAdapter<String> adapter;

//initialize the adapter by loading complete data and set Adapter to ListView.
//**Note: I have used ArrayList<String> below.**
ArrayList <String> filterList = new ArrayList <Myshares> ();

for (int i = 0; i < fileList.size(); i++) {
            if (fileList.get(i).getName().toLowerCase() || fileList.get(i).getName().toUpperCase()) {
                filterList.add(fileList.get(i));
            }
        }

adapter = new ArrayAdapter<String>(this, R.layout.searchresult_item, R.id.search_item_name,filterList);

//Here, searchresult_item is the layout file name. and search_item_name is the Textview inside it.

search.addTextChangedListener(new TextWatcher() {

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

        YourActivity.this.Youradapter.getFilter().filter(cs);

}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {


}

@Override
public void afterTextChanged(Editable s) {


}
});
于 2013-05-14T13:15:07.230 に答える
0

addView() メソッドでリスト ビューに編集テキストを追加したと思います。すべてのビューが再描画されるため、実際に発生しているため、以前にフォーカスされていた行を表す編集テキストは、完全に異なるオブジェクトになりました。アダプターで変数を設定します。int currentlyFocusedRow;

アダプターの getView で: 編集テキストに onFocusChanged リスナーを追加し、その編集テキストがフォーカスを得たら、currentFocusedRow (int 変数) = フォーカスされた (含まれる) 編集テキストが存在する行を設定します。 currentlyFocusedRow がフォーカスされます。

これに問題がある場合は、返信してください。

于 2013-05-25T11:30:09.000 に答える