Create android Photo Gallery

I would like to be able to develop an activity that accesses a folder with photos and creates a gallery to be able to view them. I think I have practically everything done, but for what it is it does not end up visualizing well.

Layout :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.oftecnica2.agendajose.GaleriaFotos"
    android:orientation="vertical">

    <Gallery
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/galeria" />

    <ImageView
        android:id="@+id/imagengaleria"
        android:layout_width="133dp"
        android:layout_height="194dp"
        android:layout_gravity="center_horizontal"
        android:background="#cfcfcf"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"/>

</LinearLayout>

Java class :

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;

import java.io.File;

public class GaleriaFotos extends AppCompatActivity {

    File[]fotos=null;
    String id="";
    Gallery galeria;
    ImageView imagengaleria;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_galeria_fotos);
        id=getIntent().getExtras().getString("id");
        imagengaleria=(ImageView)findViewById(R.id.imagengaleria);

        cargoLista();

        galeria.setAdapter(new ImageAdapter(this));
        galeria.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

                ImageView imagengaleria=(ImageView)findViewById(R.id.imagengaleria);
                Bitmap foto = BitmapFactory.decodeFile(fotos[i].getAbsolutePath());
                imagengaleria.setImageBitmap(foto);

            }
        });
    }

    public void cargoLista(){
        try{
            File fichero=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"Reuniones"+File.separator+String.valueOf(id)+File.separator+"fotos");
            fotos=fichero.listFiles();
            galeria=(Gallery)findViewById(R.id.galeria);
            System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
            for (File f:fotos){
                System.out.println(f.getAbsolutePath());
            }
        }catch (Exception e){
            System.out.println("NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
        }
    }

    private class ImageAdapter extends BaseAdapter {
        private Context context;
        private int itemBackground;
        public ImageAdapter(Context c)
        {
            context = c;
            // sets a grey background; wraps around the images
            TypedArray a =obtainStyledAttributes(R.styleable.MyGallery);
            itemBackground = a.getResourceId(R.styleable.MyGallery_android_galleryItemBackground, 0);
            a.recycle();
        }
        // returns the number of images
        public int getCount() {
            return fotos.length;
        }
        // returns the ID of an item
        public Object getItem(int position) {
            return position;
        }
        // returns the ID of an item
        public long getItemId(int position) {
            return position;
        }
        // returns an ImageView view
        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imageView = new ImageView(context);
            Bitmap bitmap = BitmapFactory.decodeFile(fotos[position].getAbsolutePath());
            imageView.setImageBitmap(bitmap);
            imageView.setLayoutParams(new Gallery.LayoutParams(100, 100));
            imageView.setBackgroundResource(itemBackground);
            return imageView;
        }
    }
}

As you see, I pass by parameter a number that is the folder where the photos are.

When running it sometimes gives the typical error of outofmemory and others does not appear absolutely nothing. Does anyone see the mistakes?

 7
Author: Joacer, 2016-08-16

2 answers

The subject of the galleries created from a widget Gallery has always been a problem, the problems are basically related to the images to load within the execution of getView(), are loaded in the ImageView but when the ImageView is not visible, these are not released from the same, you are actually loading the images and manteniendolas yet to be visualized.

A quick solution is to remove the image from the ImageView when it is not displayed using setBackgroundDrawable () assigning it a null value:

miImageView.setBackgroundDrawable(null);

But there are other important considerations such as the weight of the image, in small devices it is sometimes not necessary to load a large image since its manipulation in memory is difficult and even more if we have several instances will cause OutofMemory.

I suggest you check out these optimization tips: good image resolution

And in the case of your gallery recommend uses Picasso o Glide within

 public View getView(int position, View convertView, ViewGroup parent) {
 ...
 ...

To load the images inside the ImageView, I am not to recommend libraries but in this case are 2 good options that I recommend, they actually optimize the image they load inside the ImageView, this results in a low memory consumption which will avoid problems related to OutofMemory.

 2
Author: Jorgesys, 2017-04-13 13:00:52

To avoid the error outOfMemory when enough images should be displayed, you must ensure that those that have been loaded, are removed from memory and use a cache so as not to clutter the device with requests, I recommend using the Glide library.

In the PageAdapter you can detect when an element is removed and release the resource.

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        Log.i(TAG, "destroyItem: ");
        container.removeView((View) object);
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

If you use a viewPage as a container, you can specify items that are kept in memory or preloaded with setOffscreenPageLimit(nĂºmero_paginas), if the photos to show are FullHD,2K, 4K, 8K etc.. it depends on the device that goes more smoothly, if you define it to 1:

                | pantalla disp |
pagina anterior | pagina actual | pagina siguiente

Small demotration of an image viewer using viewpager, glide and zoom, rotate over the imageView GitHub

 0
Author: Webserveis, 2017-04-19 11:16:13