La aplicación Galería es una de las aplicaciones más utilizadas que viene preinstalada en muchos dispositivos Android y hay varias aplicaciones diferentes que están presentes en Google Play para ver los archivos multimedia presentes en su dispositivo. En este artículo, simplemente crearemos una aplicación de Galería en la que podamos ver todas las fotos que tenemos almacenadas en nuestro dispositivo. Junto con eso, también podemos ver las fotos individuales en nuestra aplicación.
¿Qué vamos a construir en este artículo?
Construiremos una aplicación simple en la que simplemente mostraremos la lista de fotos en el formato de cuadrícula y al hacer clic en la foto podemos ver esa foto y podemos hacer zoom en la foto para verla correctamente. A continuación se muestra el video0 en el que veremos lo que vamos a construir en este artículo.
Implementación paso a paso
Paso 1: Crear un nuevo proyecto
Para crear un nuevo proyecto en Android Studio, consulte Cómo crear/iniciar un nuevo proyecto en Android Studio . Tenga en cuenta que seleccione Java como lenguaje de programación.
Paso 2: agregue la dependencia en el archivo build.gradle
Vaya a la aplicación > Gradle Scripts > build.gradle(:app) y agréguele la siguiente dependencia. Estamos usando Picasso para cargar imágenes desde rutas en nuestro ImageView .
// debajo de la dependencia para usar la biblioteca de carga de imágenes de Picasso
implementación ‘com.squareup.picasso:picasso:2.71828’
Ahora sincronice su proyecto y avanzaremos hacia la adición de permisos en nuestro archivo AndroidManifest.xml .
Paso 3: Agregar permisos en nuestro archivo AndroidManifest.xml
Vaya a la aplicación > archivo AndroidManifest.xml y agréguele los siguientes permisos.
XML
<!-- permissions for reading external storage --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Como estamos cargando todas las imágenes de nuestro almacenamiento a la vez, tenemos que agregar 2 atributos a nuestra etiqueta de aplicación en el archivo AndroidManifest.xml. Navegue hasta el archivo AndroidManifest.xml y agregue debajo de dos líneas en la etiqueta de su aplicación del archivo Manifest.
XML
android:hardwareAccelerated="false" android:largeHeap="true"
Paso 4: trabajar con el archivo activity_main.xml
Vaya a la aplicación > res > diseño > actividad_principal.xml y agregue el siguiente código a ese archivo. A continuación se muestra el código para el archivo activity_main.xml .
XML
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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:layout_gravity="center" android:gravity="center" android:orientation="vertical" tools:context=".MainActivity"> <!--recycler view for displaying the list of images--> <androidx.recyclerview.widget.RecyclerView android:id="@+id/idRVImages" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
Paso 5: crear un elemento para mostrar en un RecyclerView
Vaya a la aplicación > res > diseño > haga clic con el botón derecho en él > Nuevo > archivo de recursos de diseño y cree un nuevo archivo de recursos de diseño. Nombra el archivo como card_layout y agrega el siguiente código. Se agregan comentarios en el código para conocer con más detalle.
XML
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="3dp" android:elevation="8dp" app:cardCornerRadius="8dp"> <!--Image view for displaying the image in our card layout in recycler view--> <ImageView android:id="@+id/idIVImage" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center" android:scaleType="centerCrop" /> </androidx.cardview.widget.CardView>
Paso 6: Creación de una nueva actividad para mostrar una sola imagen
Vaya a la aplicación > java > el nombre del paquete de su aplicación > haga clic con el botón derecho en él > Nuevo > Actividad vacía y nombre su actividad como ImageDetailActivity y cree una nueva actividad. Usaremos esta actividad para mostrar nuestra imagen única de la lista de imágenes diferentes.
Paso 7: crear una clase de adaptador para configurar datos para cada elemento en nuestro RecyclerView
Vaya a la aplicación > java > el nombre del paquete de su aplicación > haga clic con el botón derecho en él > Nueva clase de Java y nombre su clase como RecyclerViewAdapter y agréguele el siguiente código. Se agregan comentarios en el código para conocer con más detalle.
Java
import android.content.Context; import android.content.Intent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.squareup.picasso.Picasso; import java.io.File; import java.util.ArrayList; public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> { // creating a variable for our context and array list. private final Context context; private final ArrayList<String> imagePathArrayList; // on below line we have created a constructor. public RecyclerViewAdapter(Context context, ArrayList<String> imagePathArrayList) { this.context = context; this.imagePathArrayList = imagePathArrayList; } @NonNull @Override public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { // Inflate Layout in this method which we have created. View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_layout, parent, false); return new RecyclerViewHolder(view); } @Override public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) { // on below line we are getting th file from the // path which we have stored in our list. File imgFile = new File(imagePathArrayList.get(position)); // on below line we are checking if the file exists or not. if (imgFile.exists()) { // if the file exists then we are displaying that file in our image view using picasso library. Picasso.get().load(imgFile).placeholder(R.drawable.ic_launcher_background).into(holder.imageIV); // on below line we are adding click listener to our item of recycler view. holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // inside on click listener we are creating a new intent Intent i = new Intent(context, ImageDetailActivity.class); // on below line we are passing the image path to our new activity. i.putExtra("imgPath", imagePathArrayList.get(position)); // at last we are starting our activity. context.startActivity(i); } }); } } @Override public int getItemCount() { // this method returns // the size of recyclerview return imagePathArrayList.size(); } // View Holder Class to handle Recycler View. public static class RecyclerViewHolder extends RecyclerView.ViewHolder { // creating variables for our views. private final ImageView imageIV; public RecyclerViewHolder(@NonNull View itemView) { super(itemView); // initializing our views with their ids. imageIV = itemView.findViewById(R.id.idIVImage); } } }
Paso 8: trabajar con el archivo MainActivity.java
Vaya al archivo MainActivity.java y consulte el siguiente código. A continuación se muestra el código del archivo MainActivity.java . Se agregan comentarios dentro del código para comprender el código con más detalle.
Java
import android.content.pm.PackageManager; import android.database.Cursor; import android.os.Bundle; import android.provider.MediaStore; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import static android.Manifest.permission.READ_EXTERNAL_STORAGE; public class MainActivity extends AppCompatActivity { // on below line we are creating variables for // our array list, recycler view and adapter class. private static final int PERMISSION_REQUEST_CODE = 200; private ArrayList<String> imagePaths; private RecyclerView imagesRV; private RecyclerViewAdapter imageRVAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // we are calling a method to request // the permissions to read external storage. requestPermissions(); // creating a new array list and // initializing our recycler view. imagePaths = new ArrayList<>(); imagesRV = findViewById(R.id.idRVImages); // calling a method to // prepare our recycler view. prepareRecyclerView(); } private boolean checkPermission() { // in this method we are checking if the permissions are granted or not and returning the result. int result = ContextCompat.checkSelfPermission(getApplicationContext(), READ_EXTERNAL_STORAGE); return result == PackageManager.PERMISSION_GRANTED; } private void requestPermissions() { if (checkPermission()) { // if the permissions are already granted we are calling // a method to get all images from our external storage. Toast.makeText(this, "Permissions granted..", Toast.LENGTH_SHORT).show(); getImagePath(); } else { // if the permissions are not granted we are // calling a method to request permissions. requestPermission(); } } private void requestPermission() { //on below line we are requesting the rea external storage permissions. ActivityCompat.requestPermissions(this, new String[]{READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE); } private void prepareRecyclerView() { // in this method we are preparing our recycler view. // on below line we are initializing our adapter class. imageRVAdapter = new RecyclerViewAdapter(MainActivity.this, imagePaths); // on below line we are creating a new grid layout manager. GridLayoutManager manager = new GridLayoutManager(MainActivity.this, 4); // on below line we are setting layout // manager and adapter to our recycler view. imagesRV.setLayoutManager(manager); imagesRV.setAdapter(imageRVAdapter); } private void getImagePath() { // in this method we are adding all our image paths // in our arraylist which we have created. // on below line we are checking if the device is having an sd card or not. boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); if (isSDPresent) { // if the sd card is present we are creating a new list in // which we are getting our images data with their ids. final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID}; // on below line we are creating a new // string to order our images by string. final String orderBy = MediaStore.Images.Media._ID; // this method will stores all the images // from the gallery in Cursor Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, orderBy); // below line is to get total number of images int count = cursor.getCount(); // on below line we are running a loop to add // the image file path in our array list. for (int i = 0; i < count; i++) { // on below line we are moving our cursor position cursor.moveToPosition(i); // on below line we are getting image file path int dataColumnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA); // after that we are getting the image file path // and adding that path in our array list. imagePaths.add(cursor.getString(dataColumnIndex)); } imageRVAdapter.notifyDataSetChanged(); // after adding the data to our // array list we are closing our cursor. cursor.close(); } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { // this method is called after permissions has been granted. switch (requestCode) { // we are checking the permission code. case PERMISSION_REQUEST_CODE: // in this case we are checking if the permissions are accepted or not. if (grantResults.length > 0) { boolean storageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED; if (storageAccepted) { // if the permissions are accepted we are displaying a toast message // and calling a method to get image path. Toast.makeText(this, "Permissions Granted..", Toast.LENGTH_SHORT).show(); getImagePath(); } else { // if permissions are denied we are closing the app and displaying the toast message. Toast.makeText(this, "Permissions denied, Permissions are required to use the app..", Toast.LENGTH_SHORT).show(); } } break; } } }
Paso 9: trabajar con el archivo activity_image_detail.xml.
Vaya a la aplicación > res > diseño > activity_image_detail.xml y agregue el siguiente código a ese archivo. A continuación se muestra el código para el archivo activity_image_detail.xml .
XML
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" tools:context=".ImageDetailActivity"> <!--image view to display our image--> <ImageView android:id="@+id/idIVImage" android:layout_width="match_parent" android:layout_height="300dp" android:layout_centerInParent="true" /> </RelativeLayout>
Paso 10: trabajar con el archivo ImageDetailActivity.java
Vaya al archivo ImageDetailActivity.java y consulte el siguiente código. A continuación se muestra el código del archivo ImageDetailActivity.java . Se agregan comentarios dentro del código para comprender el código con más detalle.
Java
import android.os.Bundle; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.widget.ImageView; import androidx.appcompat.app.AppCompatActivity; import com.squareup.picasso.Picasso; import java.io.File; public class ImageDetailActivity extends AppCompatActivity { // creating a string variable, image view variable // and a variable for our scale gesture detector class. String imgPath; private ImageView imageView; private ScaleGestureDetector scaleGestureDetector; // on below line we are defining our scale factor. private float mScaleFactor = 1.0f; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_image_detail); // on below line getting data which we have passed from our adapter class. imgPath = getIntent().getStringExtra("imgPath"); // initializing our image view. imageView = findViewById(R.id.idIVImage); // on below line we are initializing our scale gesture detector for zoom in and out for our image. scaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener()); // on below line we are getting our image file from its path. File imgFile = new File(imgPath); // if the file exists then we are loading that image in our image view. if (imgFile.exists()) { Picasso.get().load(imgFile).placeholder(R.drawable.ic_launcher_background).into(imageView); } } @Override public boolean onTouchEvent(MotionEvent motionEvent) { // inside on touch event method we are calling on // touch event method and passing our motion event to it. scaleGestureDetector.onTouchEvent(motionEvent); return true; } private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { // on below line we are creating a class for our scale // listener and extending it with gesture listener. @Override public boolean onScale(ScaleGestureDetector scaleGestureDetector) { // inside on scale method we are setting scale // for our image in our image view. mScaleFactor *= scaleGestureDetector.getScaleFactor(); mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f)); // on below line we are setting // scale x and scale y to our image view. imageView.setScaleX(mScaleFactor); imageView.setScaleY(mScaleFactor); return true; } } }
Ahora ejecute su aplicación y vea el resultado de la aplicación.
Producción:
Nota: asegúrese de otorgar permisos de almacenamiento de lectura.
Publicación traducida automáticamente
Artículo escrito por chaitanyamunje y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA