我想创建一个画廊。我知道如何获取所有照片并在网格视图中显示它们。但有人可以解释如何获取和显示文件夹(带照片)?
我启动apk文件后出错了。看看我的xml文件,这可能是错的??? gridview.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<GridView
android:id="@+id/gridView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginBottom="-10dp"
android:layout_marginLeft="-10dp"
android:layout_marginRight="-10dp"
android:layout_marginTop="-10dp"
android:horizontalSpacing="-15dp"
android:numColumns="3"
android:padding="0dp"
android:verticalSpacing="-15dp" >
</GridView>
</LinearLayout>
和grid_item:
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginRight="2dp"
android:layout_marginTop="2dp"
android:gravity="center"
android:scaleType="center"
/>
答案 0 :(得分:27)
编辑:我已经为您举了一个工作示例。它的工作原理如下:
它将在一个目录中开始(在下面的例子中,/storage/sdcard/DCIM/
)。如果目录包含任何图像,则会显示它们。如果它包含任何子目录,它将检查它们是否包含图像或它们自己的子目录。如果是,则会显示文件夹图标。单击文件夹图标将打开文件夹,并显示它包含的图像/子目录。
请注意,这只是为了让您大致了解如何实现它 - 您仍需要稍微处理此代码以提高效率,尤其是在内存使用方面,但我和#39 ;我在我的模拟器上运行它,代码正在运行。
public class MainActivity extends Activity implements OnItemClickListener {
List<GridViewItem> gridItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setGridAdapter("/storage/sdcard/DCIM/");
}
/**
* This will create our GridViewItems and set the adapter
*
* @param path
* The directory in which to search for images
*/
private void setGridAdapter(String path) {
// Create a new grid adapter
gridItems = createGridItems(path);
MyGridAdapter adapter = new MyGridAdapter(this, gridItems);
// Set the grid adapter
GridView gridView = (GridView) findViewById(R.id.gridView);
gridView.setAdapter(adapter);
// Set the onClickListener
gridView.setOnItemClickListener(this);
}
/**
* Go through the specified directory, and create items to display in our
* GridView
*/
private List<GridViewItem> createGridItems(String directoryPath) {
List<GridViewItem> items = new ArrayList<GridViewItem>();
// List all the items within the folder.
File[] files = new File(directoryPath).listFiles(new ImageFileFilter());
for (File file : files) {
// Add the directories containing images or sub-directories
if (file.isDirectory()
&& file.listFiles(new ImageFileFilter()).length > 0) {
items.add(new GridViewItem(file.getAbsolutePath(), true, null));
}
// Add the images
else {
Bitmap image = BitmapHelper.decodeBitmapFromFile(file.getAbsolutePath(),
50,
50);
items.add(new GridViewItem(file.getAbsolutePath(), false, image));
}
}
return items;
}
/**
* Checks the file to see if it has a compatible extension.
*/
private boolean isImageFile(String filePath) {
if (filePath.endsWith(".jpg") || filePath.endsWith(".png"))
// Add other formats as desired
{
return true;
}
return false;
}
@Override
public void
onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (gridItems.get(position).isDirectory()) {
setGridAdapter(gridItems.get(position).getPath());
}
else {
// Display the image
}
}
/**
* This can be used to filter files.
*/
private class ImageFileFilter implements FileFilter {
@Override
public boolean accept(File file) {
if (file.isDirectory()) {
return true;
}
else if (isImageFile(file.getAbsolutePath())) {
return true;
}
return false;
}
}
}
public class MyGridAdapter extends BaseAdapter {
LayoutInflater inflater;
List<GridViewItem> items;
public MyGridAdapter(Context context, List<GridViewItem> items) {
this.items = items;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return items.size();
}
@Override
public Object getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.grid_item, null);
}
TextView text = (TextView) convertView.findViewById(R.id.textView);
text.setText(items.get(position).getPath());
ImageView imageView = (ImageView) convertView.findViewById(R.id.imageView);
Bitmap image = items.get(position).getImage();
if (image != null){
imageView.setImageBitmap(image);
}
else {
// If no image is provided, display a folder icon.
imageView.setImageResource(R.drawable.your_folder_icon);
}
return convertView;
}
}
public class GridViewItem {
private String path;
private boolean isDirectory;
private Bitmap image;
public GridViewItem(String path, boolean isDirectory, Bitmap image) {
this.path = path;
this.isDirectory = isDirectory;
this.image = image;
}
public String getPath() {
return path;
}
public boolean isDirectory() {
return isDirectory;
}
public Bitmap getImage() {
return image;
}
}
public abstract class BitmapHelper {
public static Bitmap decodeBitmapFromFile(String imagePath,
int reqWidth,
int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, options);
// Calculate inSampleSize
options.inSampleSize = calculateSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(imagePath, options);
}
private static int calculateSampleSize(BitmapFactory.Options options,
int reqHeight,
int reqWidth) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
}
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridView"
android:numColumns="auto_fit"
android:gravity="center"
android:columnWidth="150dp"
android:stretchMode="columnWidth"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</GridView>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="150dp"
android:layout_height="150dp"
android:padding="5dp" >
<ImageView
android:id="@+id/imageView"
android:layout_width="150dp"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:src="@drawable/andrew_salgado" >
</ImageView>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="20dp"
android:layout_alignParentBottom="true"
android:alpha="0.8"
android:background="#000000" >
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="start"
android:singleLine="true"
android:textColor="#FFFFFF" />
</RelativeLayout>
</RelativeLayout>
答案 1 :(得分:1)
从此处下载源代码(Get all images from gallery in android programmatically)
<强> activity_main.xml中强>
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
xmlns:android="http://schemas.android.com/apk/res/android">
<GridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/gv_folder"
android:numColumns="2"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"></GridView>
</RelativeLayout>
<强> MainActivity.java 强>
package galleryimages.galleryimages;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public static ArrayList<Model_images> al_images = new ArrayList<>();
boolean boolean_folder;
Adapter_PhotosFolder obj_adapter;
GridView gv_folder;
private static final int REQUEST_PERMISSIONS = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gv_folder = (GridView)findViewById(R.id.gv_folder);
gv_folder.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(getApplicationContext(), PhotosActivity.class);
intent.putExtra("value",i);
startActivity(intent);
}
});
if ((ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) && (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE))) {
} else {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
}else {
Log.e("Else","Else");
fn_imagespath();
}
}
public ArrayList<Model_images> fn_imagespath() {
al_images.clear();
int int_position = 0;
Uri uri;
Cursor cursor;
int column_index_data, column_index_folder_name;
String absolutePathOfImage = null;
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
cursor = getApplicationContext().getContentResolver().query(uri, projection, null, null, orderBy + " DESC");
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
column_index_folder_name = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
Log.e("Column", absolutePathOfImage);
Log.e("Folder", cursor.getString(column_index_folder_name));
for (int i = 0; i < al_images.size(); i++) {
if (al_images.get(i).getStr_folder().equals(cursor.getString(column_index_folder_name))) {
boolean_folder = true;
int_position = i;
break;
} else {
boolean_folder = false;
}
}
if (boolean_folder) {
ArrayList<String> al_path = new ArrayList<>();
al_path.addAll(al_images.get(int_position).getAl_imagepath());
al_path.add(absolutePathOfImage);
al_images.get(int_position).setAl_imagepath(al_path);
} else {
ArrayList<String> al_path = new ArrayList<>();
al_path.add(absolutePathOfImage);
Model_images obj_model = new Model_images();
obj_model.setStr_folder(cursor.getString(column_index_folder_name));
obj_model.setAl_imagepath(al_path);
al_images.add(obj_model);
}
}
for (int i = 0; i < al_images.size(); i++) {
Log.e("FOLDER", al_images.get(i).getStr_folder());
for (int j = 0; j < al_images.get(i).getAl_imagepath().size(); j++) {
Log.e("FILE", al_images.get(i).getAl_imagepath().get(j));
}
}
obj_adapter = new Adapter_PhotosFolder(getApplicationContext(),al_images);
gv_folder.setAdapter(obj_adapter);
return al_images;
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_PERMISSIONS: {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults.length > 0 && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
fn_imagespath();
} else {
Toast.makeText(MainActivity.this, "The app was not allowed to read or write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
}
}
}
}
}
}
<强> adapter_photosfolder.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:background="@drawable/drawable_photofolder"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:layout_height="match_parent">
<ImageView
android:layout_width="150dp"
android:layout_gravity="center"
android:layout_height="150dp"
android:id="@+id/iv_image"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_folder"
android:textStyle="bold"
android:textColor="#000000"
android:layout_marginLeft="10dp"
android:textSize="15dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_folder2"
android:textColor="#dfdfdf"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:textSize="15dp"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:id="@+id/rl_select"
android:alpha="0.5"
android:layout_height="match_parent">
</RelativeLayout>
</RelativeLayout>
<强> Adapter_PhotosFolder.java 强>
package galleryimages.galleryimages;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import java.util.ArrayList;
public class Adapter_PhotosFolder extends ArrayAdapter<Model_images> {
Context context;
ViewHolder viewHolder;
ArrayList<Model_images> al_menu = new ArrayList<>();
public Adapter_PhotosFolder(Context context, ArrayList<Model_images> al_menu) {
super(context, R.layout.adapter_photosfolder, al_menu);
this.al_menu = al_menu;
this.context = context;
}
@Override
public int getCount() {
Log.e("ADAPTER LIST SIZE", al_menu.size() + "");
return al_menu.size();
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getViewTypeCount() {
if (al_menu.size() > 0) {
return al_menu.size();
} else {
return 1;
}
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(getContext()).inflate(R.layout.adapter_photosfolder, parent, false);
viewHolder.tv_foldern = (TextView) convertView.findViewById(R.id.tv_folder);
viewHolder.tv_foldersize = (TextView) convertView.findViewById(R.id.tv_folder2);
viewHolder.iv_image = (ImageView) convertView.findViewById(R.id.iv_image);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv_foldern.setText(al_menu.get(position).getStr_folder());
viewHolder.tv_foldersize.setText(al_menu.get(position).getAl_imagepath().size()+"");
Glide.with(context).load("file://" + al_menu.get(position).getAl_imagepath().get(0))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(viewHolder.iv_image);
return convertView;
}
private static class ViewHolder {
TextView tv_foldern, tv_foldersize;
ImageView iv_image;
}
}
答案 2 :(得分:0)
您可以尝试这样:
public void searchImageFromSpecificDirectory() {
String path = null;
String uri = MediaStore.Images.Media.DATA;
// if GetImageFromThisDirectory is the name of the directory from which image will be retrieved
String condition = uri + " like '%/GetImageFromThisDirectory/%'";
String[] projection = { uri, MediaStore.Images.Media.DATE_ADDED,
MediaStore.Images.Media.SIZE };
Vector additionalFiles = null;
try {
if (additionalFiles == null) {
additionalFiles = new Vector<String>();
}
Cursor cursor = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection,
condition, null, null);
if (cursor != null) {
boolean isDataPresent = cursor.moveToFirst();
if (isDataPresent) {
do {
path = cursor.getString(cursor.getColumnIndex(uri));
System.out.println("...path..."+path);
additionalFiles.add(path);
}while(cursor.moveToNext());
}
if (cursor != null) {
cursor.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
答案 3 :(得分:0)
您可以按照其他代码进行操作。比如
ArrayList<String> f = new ArrayList<String>();// list of file paths
File[] listFile;
public void getFromSdcard()
{
File file= new File(android.os.Environment.getExternalStorageDirectory(),"TMyFolder");
if (file.isDirectory())
{
listFile = file.listFiles();
for (int i = 0; i < listFile.length; i++)
{
f.add(listFile[i].getAbsolutePath());
}
}
}
必须在AndroidMenifest.xml中授予权限。比如
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
答案 4 :(得分:0)
Uri lUri;
Cursor lCursor;
Log.w("ImageUtils: ", "GetAllImagesFoldersCursor");
lUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] lProjection = {"DISTINCT " + MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_TAKEN};
String lSelectionString = MediaStore.Images.Media.BUCKET_DISPLAY_NAME +
" IS NOT NULL) GROUP BY (" + MediaStore.Images.Media.BUCKET_DISPLAY_NAME;
lCursor = aContext.getContentResolver().query(lUri, lProjection, lSelectionString,
null, null);
if (lCursor != null) {
Log.w("ImageUtils: ", "Returning total Folders: " + lCursor.getCount());
}
return lCursor;
答案 5 :(得分:0)
我在我的任务中使用了@deepshikha 的代码,它运行良好,但我们仍然需要一些更改
<块引用>GIFs
NPE
为空时,它会抛出 cursor.getString(column_index_folder_name)
(基本上它是你的根目录,或者我们可以说 /storage/emulated/0/
)所以,我从:
if (boolean_folder) {...
} else {...
}
到:
boolean isGif = absolutePathOfImage.substring(absolutePathOfImage.lastIndexOf(".") + 1).equalsIgnoreCase("gif");
if (!isGif) {
if (boolean_folder) {
ArrayList<String> al_path = new ArrayList<>(albumArrayList.get(int_position).getAlbum_imagePath());
al_path.add(absolutePathOfImage);
albumArrayList.get(int_position).setAlbum_imagePath(al_path);
} else {
ArrayList<String> al_path = new ArrayList<>();
al_path.add(absolutePathOfImage);
Album obj_model = new Album();
if (cursor.getString(column_index_folder_name) == null) {
obj_model.setStr_folder("0");
} else {
obj_model.setStr_folder(cursor.getString(column_index_folder_name));
}
obj_model.setAlbum_imagePath(al_path);
albumArrayList.add(obj_model);
}
}
当 NPE
为空并创建 cursor.getString(column_index_folder_name)
时,此代码将阻止您使用 foldername 0
,即使它阻止列出 GIFs
。这就是我们可以防止应用crash
或NPE
但是下一个问题从这里开始(我之前简单提到的第三个问题)是假设如果您的设备的根路径上有 3 个图像,那么这将创建三个 0
文件夹,现在我不知道如何完成这项任务,我需要帮助(任何帮助将不胜感激)。