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

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

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

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

Android Studio

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

Q&A

解決済

1回答

1203閲覧

複数データベースからの情報をまとめてListViewにソート表示し、呼び出し元に応じた個別のクリックイベントを持たせたい

shal0ne

総合スコア51

Android

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

Android Studio

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

0グッド

1クリップ

投稿2018/09/03 18:44

編集2018/09/04 08:13

前提・実現したいこと

ソースコードのような2つのクラスのフィールドを別々のデータベースに保存します。
その後呼び出すときには2つのクラスは同じItemという括りでまとめて、図のようにidの昇順(同じ場合はAが先)にソートして、名前だけをリスト表示し、それぞれのクリックイベントを持たせたいです。

// 9/4 17:15 下部に詳細を追記しました。

発生している問題

図のように同名のインスタンスが出てきた際にそれらを識別する手段がないです。
また、同名でなくてもItemAなのでItemBなのかでもクリックイベントの挙動を変えるため、それも区別しなければならないです。
インスタンス化したものをAdapterに渡すのも手なのですが、Viewには名前しか表示されないにも関わらずインスタンス生成のコスト(今は話を簡略化するためにフィールドを3つにしていますが、実際に動くのは他クラスのインスタンスを含む15以上のもの)をかけるのはもったいないです。
イメージ説明

###解決案
何らかの形でViewに文字列を保持させることができれば正規表現による条件分岐でクリックイベントを変えられます。
例えばItemAのidが1のインスタンス情報なら、文字列をa1とおけばそれで識別できます。

###知りたいこと
Viewにidなどの形で文字列を設定できる方法があればそれを、また上記のようなことを実現できるスマートな手段があればご教授願いたいです。

該当のソースコード

Java

1abstract public class Item { 2 public int id; 3 public String name; 4}

Java

1public class ItemA extends Item { 2 public int id; 3 public String name; 4 public int value; 5}

Java

1public class ItemB extends Item{ 2 public int id; 3 public String name; 4 public String value; 5}

Database

1ItemA 2id|name|value(Int) 31|abc|123 42|ghi|456 5... 6 7ItemB 8id|name|value(String) 91|def|apple 102|abc|banana 11...

###9/4 17:15 追記

Java

1//MainActivity 2 ListView listView; 3 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.activity_main); 8 9 listView = (ListView) findViewById(R.id.listview); 10 ItemAdapter adapter=new ItemAdapter(this); 11 listView.setAdapter(adapter); 12 13 String[] itemNames=... //ItemAとItemBのdatabaseからname要素のみを取り出し、ソートした配列を用意 14 15 for(int i=0;i<itemNames.length;i++){ 16 adapter.add(itemNames[i]); //Itemインスタンスではなく、先ほどのitemNamesの配列をAdapterにセット 17 /*nameのみの配列をAdapterに渡してしまうと、後々ItemAかItemBで別々のクリックイベントを持たせたいときに識別する方法がなくなる。 18 *また、同名のものにも対応ができない。 19 *前もってItemをインスタンス化してその配列をセットしてもいいが、このviewには15個あるフィールドのうちnameしか使わない。 20 なのでnameとは別にdatabaseからもってきたidの配列をカスタムAdapterにインスタンスとして持たせ、getViewの時にidとしてsetできないか考えた。*/ 21 } 22 23 } 24 public class ItemAdapter extends ArrayAdapter<String> { 25 public ItemAdapter(Context context){ 26 super(context,R.layout.list_row); 27 } 28 29 @Override 30 public View getView(int position, View convertView, ViewGroup parent){ 31 if(convertView==null){ 32 convertView=getLayoutInflater().inflate(R.layout.list_row,null); 33 } 34 //ItemAdapterに持たせているItemのnameリストから呼び出し 35 String str =getItem(position); 36 37 //textViewにitemのnameのみをセット、このtextViewにクリックイベントを持たせようとしても識別できない 38 TextView textTitle=(TextView)convertView.findViewById(R.id.text_title); 39 textTitle.setText(str); 40 return convertView; 41 } 42}

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

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

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

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

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

guest

回答1

0

ベストアンサー

ItemAかItemBかを区別したいのであれば、単純に instanceof を使ってみるのはどうでしょう?
Adapterやクリックイベントのところのソースを提示いただいてないので以下はあくまでイメージですが、こんな感じで使えます。

java

1listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 2 @Override 3 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 4 Item item = adapter.getItem(position); 5 if (item instanceof ItemA) { 6 // ItemAだった場合のクリックイベント処理 7 } else if (item instanceof ItemB) { 8 // ItemBだった場合のクリックイベント処理 9 } 10 } 11});

Viewにidなどの形で文字列を設定できる方法があれば

一応、setTag/getTagという任意のオブジェクトを設定できるメソッドがありますが今回の場合は上記の方法で十分ですし、必要ないと思います。

投稿2018/09/04 01:16

編集2018/09/04 01:22
kakajika

総合スコア3131

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

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

shal0ne

2018/09/04 08:19

回答ありがとうございます。 自分の書き方がとても悪かったことを先にお詫びします。 追記を見てもらうとわかると思いますが、コストがかかるためインスタンス化をしたくないという走りから始まっています。 その理由として、従来のリストビューのようにスクロールに応じて表示するものではなく、一気に表示するカスタムされたリストビューを使っていて、onCreate時に負荷がかかり過ぎてしまう恐れがあるからです。 わかりづらい書き方ですみませんでした。
kakajika

2018/09/04 09:19

うーん、なるほど。ItemAやItemBクラスをそのまま利用したくないという話だったのですね。 であれば、リスト表示用にデータを絞ったItemAやItemBを定義すればいいのではないでしょうか?
shal0ne

2018/09/05 05:27

その考えはありませんでした、非常に助かります。 フィールドの少ないクラスを作って負荷を下げるということですね。 やってみたいと思います。 最後まで教えて頂き感謝します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問