Create android photo gallery

7

I would like to be able to develop an activity that accesses a folder with photos and creates a gallery to view them. I think I have practically everything done, but for whatever reason it does not finish visualizing itself 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 can see, I pass a number by parameter that is the folder where the photos are.

When executing it, it sometimes gives the typical error of outofmemory and other absolutely nothing appears. Does anyone see the errors?

    
asked by Sergio Cv 16.08.2016 в 12:16
source

2 answers

2

The theme of the galleries created from a widget Gallery has always been a problem, the problems are basically related to the images to be loaded within the execution of getView() , are loaded within ImageView but when the ImageView is not visible they are not released from it, you are actually loading the images and keeping them still without being visualized.

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

miImageView.setBackgroundDrawable(null);

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

I suggest you review these optimization tips: Good resolution image

and in the case of your gallery I recommend you use Picasso or Glide in

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

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

    
answered by 16.08.2016 в 17:03
0

To avoid the error outOfMemory when you have to visualize enough images, you must ensure that those that have been loaded, are removed from memory and use a cache to avoid saturating the request device, I recommend using the Glide library .

In the PageAdapter you can detect when an element is removed and liberize 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 the items that are kept in memory or pre-loaded with setOffscreenPageLimit(número_paginas) , if the photos to be displayed are FullHD, 2K, 4K, 8K etc. depending on the device Go more fluid, 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

    
answered by 19.04.2017 в 13:10