讀取相簿縮圖

  • AndroidManifest.xml

向系統要求這兩個權限 READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE,因這兩種權限屬於 Android 規範的 danger permission,故在主程式還需要額外提供程式向user要求一次

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application> ... </application> </manifest>
  • activity_main.xml

建立一個 GridView 來呈現縮圖,另一個 ImageView 呈現點擊後要展開全螢幕的原圖

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" android:layout_width= "fill_parent" android:layout_height= "fill_parent" tools:context=".MainActivity"> <GridView android:id= "@+id/gridView1" android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:gravity= "center" android:horizontalSpacing= "1dp" android:numColumns= "4" android:verticalSpacing= "1dp" > </GridView > <ImageView android:id= "@+id/imageView1" android:layout_width= "fill_parent" android:layout_height= "fill_parent" android:gravity= "center" android:visibility= "gone" android:background= "#00000000" /> </RelativeLayout>
  • item_photo.xml

針對大圖做客製化事件

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id= "@+id/rl_item_photo" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id= "@+id/imageView1" android:layout_width= "fill_parent" android:layout_height= "fill_parent" /> </RelativeLayout>
  • MainActivity.java

    • 點大圖的事件(畫面變回 GridView)寫在此處
    • 向user要求權限 askPermission()
package com.example.myapplication; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import android.app.Activity; import android.content.ContentResolver; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.provider.MediaStore; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.GridView; import android.widget.ImageView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { // 自訂對應的授權代碼, 實際上要override權限相關的函式時才會使用到, 如: onRequestPermissionsResult(). 不過系統在向user要求權限時仍要填入. private static final int REQ_PERMISSIONS = 0; private GridView gridView; private ImageView imageView; private List<String> thumbs; //存放縮圖的id private List<String> imagePaths; //存放圖片的路徑 private ImageAdapter imageAdapter; //用來顯示縮圖 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); askPermission(); gridView = (GridView) findViewById(R.id.gridView1); imageView = (ImageView) findViewById(R.id.imageView1); ContentResolver cr = getContentResolver(); String[] projection = { MediaStore.Images.Media._ID, // 每個資料列唯一ID MediaStore.Images.Media.DATA // 圖片真實路徑 }; //查詢SD卡的圖片 Cursor cursor = cr.query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, // 圖片存放的URI projection, // 擷取的資料欄位 null, null, null ); thumbs = new ArrayList<String>(); imagePaths = new ArrayList<String>(); for (int i = 0; i < cursor.getCount(); i++) { cursor.moveToPosition(i); int id = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media._ID));// ID thumbs.add(id + ""); String filepath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));//抓路徑 imagePaths.add(filepath); } cursor.close(); imageAdapter = new ImageAdapter(MainActivity.this, thumbs); gridView.setAdapter(imageAdapter); imageAdapter.notifyDataSetChanged(); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub imageView.setVisibility(View.GONE); gridView.setVisibility(View.VISIBLE); } }); imageView.setVisibility(View.GONE); } private void askPermission() { String[] permissions = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; // 建立一個Set來存放所有判斷完畢,但尚未取得的權限 Set<String> permissionsRequest = new HashSet<>(); for (String p : permissions) { // 系統檢查您要求的權限是否有被同意 int result = ContextCompat.checkSelfPermission(this, p); if (result != PackageManager.PERMISSION_GRANTED) { permissionsRequest.add(p); } } if (!permissionsRequest.isEmpty()) { ActivityCompat.requestPermissions( MainActivity.this, permissionsRequest.toArray(new String[permissionsRequest.size()]), // 轉為String REQ_PERMISSIONS ); } else { Toast.makeText(MainActivity.this, "已經拿到權限囉!", Toast.LENGTH_SHORT).show(); } } public void setImageView(int position){ Bitmap bm = BitmapFactory.decodeFile(imagePaths.get(position)); imageView.setImageBitmap(bm); imageView.setVisibility(View.VISIBLE); gridView.setVisibility(View.GONE); } }
  • ImageAdapter.java

點小圖的事件(畫面變成 ImageView)寫在此處

package com.example.myapplication; import java.util.List; import android.content.Context; import android.graphics.Bitmap; import android.provider.MediaStore; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.ImageView; import android.widget.Toast; public class ImageAdapter extends BaseAdapter { private ViewGroup layout; private Context context; private List coll; public ImageAdapter(Context context, List coll) { super(); this.context = context; this.coll = coll; } public View getView(final int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rowview = inflater.inflate(R.layout.item_photo, parent, false); layout = (ViewGroup) rowview.findViewById(R.id.rl_item_photo); ImageView imageView = (ImageView) rowview.findViewById(R.id.imageView1); DisplayMetrics dm = context.getResources().getDisplayMetrics(); float dd = dm.density; float px = 25 * dd; float screenWidth = dm.widthPixels; int newWidth = (int) (screenWidth - px) / 4; // 一行顯示四個縮圖 layout.setLayoutParams(new GridView.LayoutParams(newWidth, newWidth)); imageView.setId(position); // Bitmap bm = BitmapFactory.decodeFile((String)coll.get(position)); // Bitmap newBit = Bitmap.createScaledBitmap(bm, newWidth, newWidth, // true); // 透過id向系統取得縮圖 Bitmap bm = MediaStore.Images.Thumbnails.getThumbnail( context.getApplicationContext().getContentResolver(), Long.parseLong((String) coll.get(position)), MediaStore.Images.Thumbnails.MICRO_KIND, // 縮圖有另一種類型: MediaStore.Images.Thumbnails.MINI_KIND, 此解析度高於 MICRO_KIND null ); imageView.setImageBitmap(bm); imageView.setScaleType(ImageView.ScaleType.FIT_XY); //點擊照片 imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(context, "index:" + position, Toast.LENGTH_SHORT).show(); ((MainActivity)context).setImageView(position); } }); return rowview; } @Override public int getCount() { // TODO Auto-generated method stub return coll.size(); } @Override public Object getItem(int arg0) { // TODO Auto-generated method stub return coll.get(arg0); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } }

Ref.

Android 使用gridview 顯示相簿中的縮圖

tags: IO相關