質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

2376閲覧

Androidアプリのリストのフィルタリングについて

luckyclock

総合スコア73

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2016/02/15 15:38

リストビューにRSSから取得したデータを表示するアンドロイドアプリを作っています。
titleとdescriptionに検索文字を含むリストだけを1文字入力するたびに
フィルタリングしていきたいのですが、フィルタリングがうまくいきません。
(下記のコードはとりあえずタイトルだけ比較してます。)
CustomAdapter.javaのgetFilterメソッド内のコメントアウトされているclear()を実行すると
元のobjects(リストデータ)が全部消えてしまって、検索文字を削除したときや2文字目以降の
入力したときの動きがうまくないです。(リストが復帰しない)
どうすればよろしいでしょうか?

CustomAdapter.java

java

1public class CustomAdapter extends ArrayAdapter<RssLine> { 2 private LayoutInflater layoutInflater_; 3 private List<RssData> objects; 4 private List<RssData> mDisplayedValues; 5 private Context context; 6 private int layoutId; 7 8 public CustomAdapter(Context context, int textViewResourceId, List<RssData> objects) { 9 super(context, textViewResourceId, objects); 10 layoutInflater_ = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 11 12 this.objects = objects; 13 this.context = context; 14 layoutId = textViewResourceId; 15 } 16 @Override 17 public View getView(int position, View convertView, ViewGroup parent) { 18 //省略 19 } 20 21 @Override 22 public Filter getFilter() { 23 Filter filter = new Filter() { 24 25 @SuppressWarnings("unchecked") 26 @Override 27 protected void publishResults(CharSequence constraint,FilterResults results) { 28 if(results.count > 0) { 29 mDisplayedValues = (ArrayList<RssData>) results.values; // has the filtered values 30// clear(); 31 addAll(mDisplayedValues); 32 notifyDataSetChanged(); // notifies the data with new filtered values 33 } 34 else { 35 notifyDataSetInvalidated(); 36 } 37 } 38 39 @Override 40 protected FilterResults performFiltering(CharSequence constraint) { 41 FilterResults results = new FilterResults(); // Holds the results of a filtering operation in values 42 ArrayList<RssData> FilteredArrList = new ArrayList<RssData>(); 43 44 if (objects == null) { 45 objects = new ArrayList<RssLine>(mDisplayedValues); // saves the original data in mOriginalValues 46 } 47 48 /******** 49 * 50 * If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values 51 * else does the Filtering and returns FilteredArrList(Filtered) 52 * 53 ********/ 54 if (constraint == null || constraint.length() == 0) { 55 56 // set the Original result to return 57 results.count = objects.size(); 58 results.values = objects; 59 } 60 else { 61 constraint = constraint.toString().toLowerCase(); 62 for (int i = 0; i < objects.size(); i++) { 63 RssData item = getItem(i); 64 String data = objects.get(i).getTitle(); 65 if((data != null && data.contains(constraint))) { 66 FilteredArrList.add(item); 67 } 68 } 69 // set the Filtered result to return 70 results.count = FilteredArrList.size(); 71 results.values = FilteredArrList; 72 } 73 return results; 74 } 75 }; 76 return filter; 77 } 78}

MainActivity.java

java

1 public CustomAdapter adapter; 2 @SuppressWarnings("unchecked") 3 @Override 4 public boolean onQueryTextChange(String newText) { 5 // 文字が入力されるたびにフィルタを更新します 6 adapter.getFilter().filter(newText); 7 return true; 8 }

以下はリストに持たせるクラスです。
RssData.java

java

1public class RssData { 2 private Bitmap imageData; 3 private String title; 4 private String description; 5 6 public void setImagaData(Bitmap image) { 7 imageData = image; 8 } 9 10 public Bitmap getImageData() { 11 return imageData; 12 } 13 14 public void setTitle(String text) { 15 title = text; 16 } 17 18 public String getTitle() { 19 return title; 20 } 21 22 public void setDescription(String text) { 23 description = text; 24 } 25 26 public String getDescription() { 27 return description; 28 } 29}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Adapter#clearはAdapter内で保持している情報を全て削除するメソッドです。フィルターは内部に保持する情報を絞り込むための機能なのでclearをしてはいけません。
また、Adapter#addAllも同様に内部のリストを書き換えてしまうのでしてはいけません。

実装はAdptet#getViewのなかでgetItemをしているところをフィルター済みリストから取得するようになっているかを確認してください。

投稿2016/02/16 02:09

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

luckyclock

2016/02/16 11:30

@Override public DeadLine getItem(int position) { return objects.get(position); } @Override public View getView(int position, View convertView, ViewGroup parent) { // 特定の行(position)のデータを得る RssData item = (RssData)getItem(position);    //以下省略 } getItemしているところはフィルタ前のオリジナルのアレイから取得するようになっています。 ただgetItemの戻り値をフィルタされたリストのmDisplayedValuesとした場合、positionはオリジナルのアレイの位置が入ってくるため、mDisplayedValuesのとんでもない位置を参照してしまいアプリが落ちてしまいます。 おしいところまで来ている気がするのですが。後一歩うまくいきません。
yona

2016/02/16 13:44

とりあえず、filterをフィールドにしたほうがいいでしょう。 最初のコメントは誤っていました、申し訳ない。clear()する必要がありますね。 条件が変わる前と後でobjectsとmDisplayedValuesの内容を確認してみてください。
luckyclock

2016/02/16 15:19

やはりclear()を実行するとリスト復帰用に保存していたはずのobjectsがmDisplayedValuesと同じ値になってリストが復帰しません。 試したコードです。 protected void publishResults(CharSequence constraint, FilterResults results) { // Adapterのメソッドでデータの内容を更新する if(results.count > 0) { List<RssData> items = (List<RssData>) results.values; clear(); addAll(items); notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } }  @Override public RssData getItem(int position) { //フィルタしたアイテムを返す return mDisplayedValues.get(position); }
yona

2016/02/17 00:26 編集

具体的にどのタイミングでリストの内容が同じになるか特定できますか? 下記のコードが怪しいです if (objects == null) { objects = new ArrayList<RssLine>(mDisplayedValues); // saves the original data in mOriginalValues }
luckyclock

2016/02/17 13:24

今日いろいろやってみてなんとか動きました。 修正したところは protected void publishResults(CharSequence constraint,FilterResults results) { mDisplayedValues = (ArrayList<DeadLine>) results.values; // has the filtered values notifyDataSetChanged(); // notifies the data with new filtered values } clear()とかはいらなかったみたいです。 さらにCustomAdapterクラスのgetCountがオリジナルのリストのサイズを返すように なっていたため、フィルタしたリストのサイズを返すように変更しました。 @Override public int getCount() { // return objects.size(); ←よくなかった。 return mDisplayedValues.size(); } さらに一番最初に指摘を受けたようにgetItemはフィルタしたリストを返すようにしました。最初に試したときgetCountも修正すべきでしたが気づきませんでした。 public RssData getItem(int position) { return mDisplayedValues.get(position); } いろいろ親身になっていただきありがとうございました。
yona

2016/02/17 13:37

力になれず申し訳ないです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問