Continuando con mi publicación anterior sobre GridView con librería Picasso, voy a implementar:
- Usar las imágenes de nuestro móvil
- Posibilidad de controlar el número de columnas del
GridView
- Permitir ver la imagen con la aplicación por defecto
- Mejorar la visualización en función del tamaño de pantalla
Usar imágenes de nuestro móvil.
Para obtener las imágenes que tenemos en nuestro teléfono usaremos un método estático que nos devuelve un ArrayList
de String
. El método lo implementamos dentro de MainActivity.java
. Su código:
/**
* Getting All Images Path
*
* @param activity
* @return ArrayList with images Path
*/
public static ArrayList<String> getAllShownImagesPath(Activity activity) {
Uri uri;
Cursor cursor;
int column_index_data, column_index_folder_name;
ArrayList<String> listOfAllImages = new ArrayList<String>();
String absolutePathOfImage = null;
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaColumns.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME };
cursor = activity.getContentResolver().query(uri, projection, null,
null, MediaStore.Images.Media.DATE_ADDED);
column_index_data = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
column_index_folder_name = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
listOfAllImages.add(absolutePathOfImage);
}
Collections.reverse(listOfAllImages);
return listOfAllImages;
}
Necesitamos ahora modificar el código del adaptador, ya que su constructor recibía como uno de sus parámetros un Array
de String
. Por tanto
- La variable que contiene las imágenes será
private ArrayList
items; - El contructor será del tipo
public GridviewAdapter(Context context, ArrayList
.items) {...} - Para determinar cuantos elementos tiene el
Array
ahora serápublic int getCount() { return items.length; }
- Para conocer sobre que imagen se itera dentro de
getView
necesitaremos cambiarlo apublic Object getItem(int position) { return items.get(position); }
- Para hacer uso de la librería Picasso modificaremos el método que obtiene la imagen a procesar
.load("file://"+items.get(position))
. Concatenamos antes de la ruta de la imagen un trozo deString
para referenciarla correctamente:file://
Hasta aquí ya usamos las imágenes de nuestro móvil para crear el GridView
.
Controlar el número de columnas.
Necesitaremos crear y modificar varios archivos.
- Crear el menú de opciones, sobre esto ya hice un [vídeo](https://www.youtube.com/watch?v=4r7RNfK89lg&list=UUgAVPB3yw74JP5UEEXHgccA "Vídeo menú de opciones")
- Registramos el menú en el
MainActivity.java
conpublic boolean onCreateOptionsMenu(Menu menu) {...}
- Le damos funcionalidad a los ítems del menú con
public boolean onOptionsItemSelected(MenuItem item) {...}
- Establecemos al comienzo todos los ítems como no seleccionados
item.setChecked(false);
- Según ítem seleccionado, pasamos
numColumn
a una variable el valor de columnas y establecemos el ítem comochecked
item.setChecked(true);
- Después del SWITCH le comunicamos al
GridView
el número de columnas:.setNumColumns(numColumn);
y el adaptador actualizado:.setAdapter(new GridviewAdapter(MainActivity.this, getAllShownImagesPath(this), numColumn));
- Añadimos nueva variable al adaptador y modificamos el constructor para que reciba el tercer parámetro que indica el número de columnas:
public GridviewAdapter(Context context, ArrayList
items, int numColumn) {..}
- Establecemos al comienzo todos los ítems como no seleccionados
Código XML del menú:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="eu.ivanalbizu.picassogridviewgallery.MainActivity" >
<group android:id="@+id/group1" android:checkableBehavior="single">
<item
android:id="@+id/oneColumn"
android:orderInCategory="100"
android:title="@string/one_column"
app:showAsAction="never"/>
<item
android:id="@+id/twoColumn"
android:orderInCategory="200"
android:title="@string/two_column"
app:showAsAction="never"/>
<item
android:id="@+id/threeColumn"
android:orderInCategory="300"
android:title="@string/three_column"
app:showAsAction="never" android:checked="true"/>
<item
android:id="@+id/fourColumn"
android:orderInCategory="400"
android:title="@string/four_column"
app:showAsAction="never"/>
</group>
</menu>
Código de creación y control del menú:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
getOverflowMenu();
return super.onCreateOptionsMenu(menu);
}
private void getOverflowMenu() {
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
item.setChecked(false);
switch (item.getItemId()) {
case R.id.oneColumn:
numColumn=1;
item.setChecked(true);
break;
case R.id.twoColumn:
numColumn=2;
item.setChecked(true);
break;
case R.id.threeColumn:
numColumn=3;
item.setChecked(true);
break;
case R.id.fourColumn:
numColumn=4;
item.setChecked(true);
break;
default:
break;
}
gridView.setNumColumns(numColumn);
gridView.setAdapter(new GridviewAdapter(MainActivity.this,
getAllShownImagesPath(this),numColumn));
return super.onOptionsItemSelected(item);
}
Permitir ver la imagen con la aplicación por defecto.
Dentro del método onCreate(...)
incluimos listener al GridView del tipo "ítem seleccionado". Su código:
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String rutaDeLaImagen = gridAdapter.getItem(position).toString();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + rutaDeLaImagen), "image/*");
startActivity(intent);
}
});
Mejorar la visualización en función del tamaño de pantalla.
Para optimizar el ancho de pantalla del móvil y el número de columnas a mostrar modificaremos el código del getView
del adaptador. Se necesita obtener el ancho de pantalla del teléfono (detecta si está vertical u horizontal el móvil). Al método resize(...)
de la librería Picasso le pasamos como parámetros el resultado de dividir el ancho del móvil entre el número de columnas int imageWidth = (int) (width / numColumn);
.
El método completo del getView
es:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int imageWidth = (int) (width / numColumn);
//Declaramos el ImageView
ImageView img = null;
if (convertView == null) {
//Referenciamos el ImageView
img = new ImageView(context);
//Referenciamos el ImageView al convertView
img.setPadding(10,0,10,0);
convertView = img;
} else {
img = (ImageView) convertView;
}
//Uso de la librería Picasso
Picasso.with(context)
//Cargamos la imagen sobre la que se esté iterando
.load("file://"+items.get(position))
//Imagen por defecto usada mientras se cargan las imágenes
.placeholder(R.drawable.picture)
.noFade()
.resize(imageWidth, imageWidth)
.centerCrop()
//Se aplica sobre la imagen (ImageView - se hizo referencia a "convertView")
.into(img);
return convertView;
}
Vídeo del proyecto: