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

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

ただいまの
回答率

90.53%

  • Java

    15547questions

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

  • Android

    7179questions

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

  • Android Studio

    4221questions

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

  • Android Emulator

    140questions

    Android EmulatorはアンドロイドのOSで起動しているアンドロイドのデバイスの機能をシミュレートするソフトウェアです。Emulatorは開発者に複数の違う設定を持ったデバイスを必要とすることなくアプリケーションを開発しテストすることが可能になります。

GridViewで写真表示をする際に、表示が遅延しているのか波を打ってしまう

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 579

SmartBuzz

score 73

フォトアルバムのギャラリーを自作しようとしています。
このフォトアルバムには、デジカメで撮影した写真を表示するので、かなり画像が大きくなるので縮小して表示するようにしていますが、それでも重たいのか表示に遅延が発生してしまいます。

スクロールは大変スムーズに動くのですが、スクロール完了後も表示している写真アイテムがスクロール途中の写真をコロコロと表示するような感じです。

public View getView(int position, View convertView, ViewGroup parent) {
        StringBuilder TextView = new StringBuilder();

        ViewHolder viewHolder;

        if(convertView == null){
            convertView = mInflater.inflate(R.layout.list_log_album_content, parent, false);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder)convertView.getTag();
        }
        viewHolder.thumbnail.setPhotoID(mPhotoList.get(position));

        /**
         * TextViewへの表示処理
         */
        // 時間
        if(mPhotoList.get(position).getExifInterface().getAttribute(ExifInterface.TAG_DATETIME)!=null){
            TextView.append(mContext.getString(R.string.text_label_log_album_date)  +
                    mPhotoList.get(position).getExifInterface().getAttribute(ExifInterface.TAG_DATETIME));
        }

        // 緯度
        if(mPhotoList.get(position).getExifInterface().getAttribute(ExifInterface.TAG_GPS_LONGITUDE) != null){
             TextView.append("\n" + mContext.getString(R.string.text_label_log_album_longitude) +
                     mPhotoList.get(position).getExifInterface().getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
        }

        // 経度
        if(mPhotoList.get(position).getExifInterface().getAttribute(ExifInterface.TAG_GPS_LATITUDE) != null){
            TextView.append("\n" + mContext.getString(R.string.text_label_log_album_latitude) +
                    mPhotoList.get(position).getExifInterface().getAttribute(ExifInterface.TAG_GPS_LATITUDE));
        }

        viewHolder.textView.setText(TextView);

        return convertView;
    }

とアダプターの中の「viewHolder.thumbnail.setPhotoID(Xxxx)」で独自に作ったサムネイルイメージビューのクラスに表示したい写真のパスとExifを渡しています。
この独自で作ったサムネイルクラスは、GridViewの中のアイテムに情報を表示するところをつけたかったので、その為に作りました。

public class ThumbnailView extends ImageView {

    static private Photo mPhoto;
    private Bitmap bitmap;

    public ThumbnailView(Context context) {
        super(context);
    }

    public ThumbnailView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int width = getMeasuredWidth();
        setMeasuredDimension(width, width);
    }

    public void setPhotoID(Photo photo){
        mPhoto = photo;

       PhotoTask task = new PhotoTask(this);
        task.execute(mPhoto);
    }

    public String getPhotoID(){
        return mPhoto.getFilePath();
    }

    class PhotoTask extends AsyncTask<Object,Void,Bitmap>{

        private final WeakReference<ThumbnailView> mThumbnailView;
        private Bitmap photos;
        private Bitmap photo_s = null;
        Photo mPhoto;

        public PhotoTask(ThumbnailView thumbnailView){
            mThumbnailView = new WeakReference<ThumbnailView>(thumbnailView);
        }

        @Override
        protected Bitmap doInBackground(Object... params){

            mPhoto = (Photo)params[0];

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(mPhoto.getFilePath(),options);
            int scaleW = options.outWidth / 530 + 1;
            int scaleH = options.outHeight / 570 + 1;

            int scale = Math.max(scaleW, scaleH);
            options.inJustDecodeBounds = false;
            options.inSampleSize = scale;
            try {
                photos = BitmapFactory.decodeFile(mPhoto.getFilePath(), options);
                photo_s = Bitmap.createBitmap(photos,0,0,photos.getWidth(),photos.getHeight(), PhotoRotatedMatrix.getRotatedMatrix(mPhoto.getExifInterface()),true);
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
            }

            return photo_s;
        }

        @Override
        protected void onPostExecute(Bitmap result){
            // メインスレッドの処理
            final ThumbnailView thumbnailView = mThumbnailView.get();
            // デコードしたBitmapをThumbnailViewに設定する
            bitmap = result;
            thumbnailView.setImageBitmap(result);
        }
    }


このイメージビューの中で、バッググラウンドでビットマップを生成するような流れにしました。

動きは高速化できたのですが、表示が遅く一つ一つのイメージビューがスクロール途中の写真をスクロール完了後もローディングしているような状態になってしまいます。

・イメージビューにプログレスバーが表示されるようにする
という方法も検討はしてみたのですが、どこで本来欲しい写真が表示されたかどうかを取れなかったので断念しました。

どうすれば解決できるでしょうか?

ご教授のほどよろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

メモリキャッシュを使ってみてはどうでしょうか。現在の実装だと同じ画像を何回も読み込むことになっているので非効率です。またListViewを使っている以上何回も同じ表示することになると思いますのでメモリキャッシュは有効だと思います。LruCacheというメモリキャッシュのAPIがあるのでライブラリを使わずやるのであればそちらを使ってみてはどうでしょうか?
個人的にはPicassoなどの画像読み込みライブラリを使うことをお勧めします。ライブラリを使えば非同期読み込みやキャッシュを適切にやってくれるので、メモリリークなどをあまり気にしなくてよくなります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/13 09:37

    情報を頂いてありがとうございます。
    調査してみます!

    キャンセル

  • 2017/02/13 17:30

    Picassoは導入もとても簡単で、すぐ導入できました!
    ありがとうございました。

    キャンセル

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

  • Java

    15547questions

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

  • Android

    7179questions

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

  • Android Studio

    4221questions

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

  • Android Emulator

    140questions

    Android EmulatorはアンドロイドのOSで起動しているアンドロイドのデバイスの機能をシミュレートするソフトウェアです。Emulatorは開発者に複数の違う設定を持ったデバイスを必要とすることなくアプリケーションを開発しテストすることが可能になります。