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

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

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

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

1回答

933閲覧

検索ボックスでフィルターの効果を有効にした場合のコンテンツ内容取得方方法 listview/searchview

dedede914

総合スコア62

Java

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2023/03/09 02:20

実現したいこと

検索ボックスに文字を入力するとフィルター機能によって、その下にあるリストボックスに表示されるコンテンツが変化します。いずれかのリストをクリックするとそのリスト特有の値をもって画面を遷移させます。 onItemClick()を使用しています
よろしくお願いします

あと検索ボックスに入力したときに入力した文字がトーストみたいに下に出てくるのもなくしたいです。できればこちらもお助けいただければ
質問→検索ボックスに文字を入力するとトーストで文字表示される android studio / SearchView

よろしくお願いします

発生している問題・エラーメッセージ

フィルター機能によって表示される順番が変化するので、実際のインデックスとは異なってしまいます。

入力アリ入力ナシ
イメージ説明イメージ説明

該当のソースコード

java

1public class SearchFragment extends Fragment implements AdapterView.OnItemClickListener { 2 3 private SearchViewModel homeViewModel; 4 private FragmentSearchBinding binding; 5 private DatabaseHelper helper=null; 6 private Cursor cursor=null; 7 private GlobalVariables gl; 8 9 public View onCreateView(@NonNull LayoutInflater inflater, 10 ViewGroup container, Bundle savedInstanceState) { 11 homeViewModel =new ViewModelProvider(this).get(SearchViewModel.class); 12 binding = FragmentSearchBinding.inflate(inflater, container, false); 13 View root = binding.getRoot(); 14 15 searchfunc(helper); 16 17 return root; 18 } 19 20 21 public void searchfunc(DatabaseHelper helper){ 22 //配列アダプターを制作、ListViewに登録 23 final ListView list = binding.list; 24 list.setAdapter(get_wordlist_fromDB(helper)); 25 //フィルター機能有効か 26 list.setTextFilterEnabled(true); 27 28 SearchView sv=binding.searchingbox ; 29 //検索ボックスdefoult入力状態にする 30 sv.requestFocus(); 31 //検索ボックス入力時の動作 32 sv.setOnQueryTextListener(new SearchView.OnQueryTextListener(){ 33 public boolean onQueryTextChange(String text){ 34 if(text==null || text.equals("")){ 35 list.clearTextFilter(); 36 }else{ 37 list.setFilterText(text); 38 } 39 return false; 40 } 41 42 @Override 43 public boolean onQueryTextSubmit(String s) { 44 return false; 45 } 46 }); 47 48 list.setOnItemClickListener(this); 49 } 50 51 52 53 public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 54 Intent intent = new Intent(this.getContext(), ResultsActivity.class); 55//positionがフィルターによって変わるので本来のインデックスと異なる 56 this.cursor.moveToPosition(position); 57 //golobalvariablesにwordをセット 58 gl=(GlobalVariables) getContext().getApplicationContext(); 59 gl.setWord(cursor.getString(0)); 60 // Activity をスイッチする 61 startActivity(intent); 62 Log.e("debug","word: "+gl.getWord()); 63 } 64 65 66 67 //データをリストに入れるための準備 68 //cursorに全部のデータを入れてます 69 public ArrayAdapter<String> get_wordlist_fromDB(DatabaseHelper helper){ 70 //helperを準備 71 helper=new DatabaseHelper(getContext());//元々this 72 try { 73 helper.createDatabase(); 74 } 75 catch (IOException e) { 76 throw new Error("Unable to create database"); 77 } 78 //データベース取得 79 SQLiteDatabase db=helper.getWritableDatabase(); 80 try{ 81 int i =0; 82 String sql="QUERY"; 83 this.cursor=db.rawQuery(sql , null); 84 cursor.moveToFirst(); 85 ArrayList<String> data =new ArrayList<>(); 86 data.add(cursor.getString(i)); 87 while (cursor.moveToNext()) { 88 data.add(cursor.getString(i)); 89 } 90 ArrayAdapter<String> adapter=new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, data); 91 return adapter; 92 }finally{ 93 db.close(); 94 } 95 } 96 97 98 @Override 99 public void onDestroyView() { 100 super.onDestroyView(); 101 binding = null; 102 } 103 104 105}

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

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

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

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

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

jimbe

2023/03/09 03:23 編集

かなり切り貼り感があるコードですが、 DB あり ViewModel ありの上でさらに GlobalVariables とか必要なのでしょうか。 >//cursorに全部のデータを入れてます cursor にはデータは入りません。データが入っているレコードを指しているのが cursor です。 >db.close(); 通常使用では SQLiteDatabase は close する必要はありません。
dedede914

2023/03/09 19:33

初めてアプリを作っていて、何度か挫折して、今また取り組み始めたところです とりあえず自分の欲しい機能が備わったしっかり動くアプリが早くほしくて、意味をしっかり理解せずコピペ改変をしまくっています。ので、ぐちゃぐちゃだとは思います!とりあえず完成させてから体系的に学んでいこうと思っています。 データベースはよく使いそうなのでcursorについてはしっかり勉強してみます globalvariablesを使っている理由としては、 インテントした先がtab表示のあるページなのでpageradapterを一回かましてから、値を受け渡したいfragmentにたどり着きます。なので何度も値を受け渡すよりも一発で値にアクセスできた方が楽だなと思いそうしました。activityからpageradapter、pageradapterからfragmentに値を受け渡していった方がいいですか?
jimbe

2023/03/09 19:45

>インテントした先がtab表示のあるページなのでpageradapterを一回かましてから ~ まず、フラグメントが使えるなら、アクティビティを分ける必要はあるのでしょうか。 アクティビティの代わりに土台となるフラグメントを用意すれば、リストから選択したらインテントでアクティビティを呼ぶ代わりにフラグメントを切り替えるだけです。 そしてアプリ全体でアクティビティが1つで済めば、ビューモデルによって階層構造を跨いでもフラグメント間でデータの共有が可能です。
dedede914

2023/03/09 20:10

すみません一個抜けていました。流れは、activityからactivity2,acticity2からpageradapter、pageradapterからfragmentです。 ちなみに日西辞書のアプリを作っています。どんな感じになっているか、ここに詳細を書かせていただきます MainActivity:navigationbarで3つのfragmentをもっています(その内の一つがSearchFragmentです) SearchFragment:検索ボックスのある問題のやつです。検索結果のリストをクリックするとresultActivityをインテントします。その際に、検索した単語をStringとしてAFragment,BFragmentに受け渡したいです。 ResultActivity:tab表示をします(AFragment,BFragment)。そのためここではSectionsPagerAdapterをViewPagerにsetAdapterするだけです。 SectionsPagerAdapter:AFragment,BFragmentのインスタンスを制作しています AFragment,BFragment:ここで、Activityのstringを使ってデータを表示させたい。 といった感じです。
jimbe

2023/03/09 20:44 編集

どのような階層であれ、アクティビティを1つにすればビューモデルでデータを共有できることに変わりはありません。 SearchView 等を乗せている土台としての MainActivity の機能と ViewPager の土台としての ResultActivity の機能をそれぞれ(例えば)MainFragment と ResultFragment を新規に作成して移し、この二つの土台として(そしてアプリの唯一のアクティビティとして) MainActivity を再設計し、全体的なデータの保持役として(例えば) MainViewModel を作成します。 MainFragment 上の SearchFragment でリストを選択したら MainViewModel にその情報を設定すると共に MainFragment を ResultFragment に切り替え、 ViewPager 内の各フラグメントは MainViewModel からデータを取得する…ということが出来ます。
dedede914

2023/03/10 21:40

クラスとかの関係性でいろいろ勘違いしていることが多かったたみたいで、調べてみていると jimbeさんの言おうとしていることが何となくわかりました ResultActivityをresult fragmentに変更し、うまく動作させることができました viewmodelに関しては今調べている最中です 詳しくありがとうございました!
guest

回答1

0

ベストアンサー

行クリックで呼ばれる onItemClick の position はフィルタリングされた表示上の位置ですが、同時に ListView#getItemAtPosition のパラメータもその範囲になりますので、そのまま指定してデータを取り出すことが出来ます。

データの管理をどのオブジェクトがするのか/しているのかを決める/判断することは、オブジェクト指向としては大事なことです。
リストのデータはデータベースから読んでいますが、リストとして表示する為にそのデータを保持・管理しているのは Adapter ですし、 Adapter のデータを表示しているのは ListView です。
フィルタリングは ListView に指定しているのですから、 ListView も Adapter も飛び越えてデータベースから選択データを得るのでは無く、 ListView から得ることをまず考えられると良いと思います。

java

1import androidx.appcompat.app.AppCompatActivity; 2import androidx.appcompat.widget.SearchView; 3 4import android.os.Bundle; 5import android.text.TextUtils; 6import android.util.Log; 7import android.widget.*; 8 9import java.util.*; 10 11public class MainActivity extends AppCompatActivity { 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 17 ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, 18 Arrays.asList("111","222","333","444","555")); 19 Filter filter = adapter.getFilter(); 20 21 ListView listView = findViewById(R.id.listView); 22 listView.setAdapter(adapter); 23 listView.setTextFilterEnabled(true); 24 listView.setOnItemClickListener((parent, view, position, id) -> { 25 Log.d("onItemClick ***", "position="+position); 26 String text = (String)listView.getItemAtPosition(position); 27 Log.d("onItemClick ***", "text="+text); 28 }); 29 30 SearchView searchView = findViewById(R.id.searchView); 31 searchView.requestFocus(); 32 searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){ 33 public boolean onQueryTextChange(String text) { 34 Log.d("onQueryTextChange ***", "text="+text); 35 if(TextUtils.isEmpty(text)) { 36 //listView.clearTextFilter(); 37 filter.filter(null); 38 } else { 39 //listView.setFilterText(text); 40 filter.filter(text); 41 } 42 return true; 43 } 44 @Override 45 public boolean onQueryTextSubmit(String text) { 46 Log.d("onQueryTextSubmit ***", "text="+text); 47 return false; 48 } 49 }); 50 } 51}

res/layout/activity_main.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 tools:context=".MainActivity"> 8 9 <androidx.appcompat.widget.SearchView 10 android:id="@+id/searchView" 11 android:layout_width="0dp" 12 android:layout_height="wrap_content" 13 app:iconifiedByDefault="false" 14 app:layout_constraintBottom_toTopOf="@id/listView" 15 app:layout_constraintEnd_toEndOf="parent" 16 app:layout_constraintStart_toStartOf="parent" 17 app:layout_constraintTop_toTopOf="parent" /> 18 <ListView 19 android:id="@+id/listView" 20 android:layout_width="0dp" 21 android:layout_height="0dp" 22 app:layout_constraintBottom_toBottomOf="parent" 23 app:layout_constraintEnd_toEndOf="parent" 24 app:layout_constraintStart_toStartOf="parent" 25 app:layout_constraintTop_toBottomOf="@id/searchView" /> 26</androidx.constraintlayout.widget.ConstraintLayout>

実行時ログ(SearchView に "2" を入力、"222" の行を選択)

plain

1D/onQueryTextChange ***: text=2 2D/onItemClick ***: position=0 3D/onItemClick ***: text=222

投稿2023/03/09 05:21

編集2023/03/09 06:56
jimbe

総合スコア12646

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

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

dedede914

2023/03/09 19:22

期待通りに動きましたありがとうございました! これからはデータを持っているオブジェクトから直接データを得られるメゾットがあるかしっかり確認するようにします!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問