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

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

ただいまの
回答率

89.70%

複数の項目がセットされているListViewから特定の項目を抜き出したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 472

tery0203

score 6

お世話になります。
初投稿かつ勉強中の初心者のため質問をうまくまとめられていないかもしれませんがお許しください。

Android Studioを使ってアプリ開発を行なっています。
今回は本体のストレージから画像を参照し、サムネイルとタイトルをListViewで表示するアプリを作成しました。
次はそのListViewをタップすると別画面(今回だとSubActivity)へ遷移し全画面表示出来るようにしたいのですが、複数の項目がセットされているListViewからうまく画像の情報が抜き出せず、実行はできるのですがアプリが落ちてしまいます。

複数の項目が入っているListViewのアダプタから画像の情報を抜き出し、別のインテントへ渡す処理をご教授ください。

該当のソースコード

---OnCreateでのアクセス許可等は省略----

    public void startImageViewer() {

        // レイアウトからリストビューを取得
        final ListView listView = (ListView)findViewById(R.id.list_view);
        // リストビューに表示する要素を設定
        mListItems = new ArrayList<>();

        // 画像情報の取得
        ContentResolver resolver = getContentResolver();
        final Cursor cursor = resolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, // データの種類
                null, // 項目(null 全項目)
                null, // フィルタ条件(null フィルタなし)
                null, // フィルタ用パラメータ
                null // ソート
        );
        Log.v("MEDIA", Arrays.toString(cursor.getColumnNames())); // 項目名一覧
        Log.v("MEDIA", "Image files = " + cursor.getCount()); // 取得件数
        if (cursor.moveToFirst()) {
            String info;
            try {
                do {
                    info = "TITLE : " + cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.TITLE));
                    info += "\nPATH : " + cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));

                    int fieldIndex = cursor.getColumnIndex(MediaStore.Images.Media._ID);
                    Long id = cursor.getLong(fieldIndex);

                    Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI , id);
                    mBmp = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                    SetListview item = new SetListview(mBmp, info);

                    mListItems.add(item);
                } while (cursor.moveToNext());
            }catch (IOException e) {
                System.err.println(e.getMessage());
            }
        }
        cursor.close();
        // 出力結果をリストビューに表示
        // ListView内にサムネイルとタイトルを表示するためにListAdapter.javaに渡す
        ListAdapter adapter = new ListAdapter(this, R.layout.listview_layout, mListItems);
        listView.setAdapter(adapter);

        //クリックした画像の表示
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //インテントの作成
                Intent intent = new Intent(MainActivity.this, SuBActivity.class);
                //データをセットする。デバッグだとここの行のせいでアプリが落ちている
                String currentId = cursor.getString(cursor.getColumnIndex("mBmp"));

                intent.putExtra("sendText",currentId);
                //遷移先の画面を起動
                startActivity(intent);
            }
        });
    };
public class SubActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.imageview_activity);

        Intent intent = this.getIntent();
        String image = intent.getStringExtra("sendText");
        Uri uri = Uri.parse(image);
        ImageView imageview = (ImageView)this.findViewById(R.id.imageView);
        imageview.setImageURI(uri);


    }
}
public class ListAdapter extends ArrayAdapter<SetListview> {
    private int mResource;
    private List<SetListview> mItems;
    private LayoutInflater mInflater;

    /**
     * コンストラクタ
     * @param context コンテキスト
     * @param resource リソースID
     * @param items リストビューの要素
     */
    public ListAdapter(Context context, int resource, List<SetListview> items) {
        super(context, resource, items);

        mResource = resource;
        mItems = items;
        mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;

        if (convertView != null) {
            view = convertView;
        }
        else {
            view = mInflater.inflate(mResource, null);
        }

        // リストビューに表示する要素を取得
        SetListview item = mItems.get(position);

        // サムネイル画像を設定
        ImageView thumbnail = (ImageView)view.findViewById(R.id.thumbnail);
        thumbnail.setImageBitmap(item.getThumbnail());

        // タイトルを設定
        TextView title = (TextView)view.findViewById(R.id.title);
        title.setText(item.getTitle());

        return view;
    }
}

試したこと

String currentId = cursor.getString(cursor.getColumnIndex("mBmp"));
を追加した

『ローカル変数cursorは内部クラスからアクセスされます。finalで宣言される必要があります』というエラーが出たのでListView作成時の情報の取得に使用している
Cursor cursor = resolver.query(
の部分を
final Cursor cursor = resolver.query(
に書き換えた

コンパイルは通るようになったがリストをクリックすると落ちる

補足情報(FW/ツールのバージョンなど)

AndroidStudio3.2.1
Android8.0での動作を想定しています。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

onItemClick 内の

String currentId = cursor.getString(cursor.getColumnIndex("mBmp"));


の cursor は, クリックされて onItemClick が呼ばれた時点で既に cursor.close(); されています.

onItemClick 内でクリックされたデータを得る場合は, パラメータ int position を用いまして adapter.getItem(position) を呼ぶ等するのが良いかと思います.

その為に ListAdapter におきまして

@Override
SetListview getItem(int position) {
    return mItems.get(position);
}


等と追加が必要と思います.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/04 20:34

    返信遅れまして申し訳ありません。回答ありがとうございました。
    上記回答を元にListAdapterを編集し、パスを渡すことで解決いたしました。

    キャンセル

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

  • ただいまの回答率 89.70%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る