【发布时间】:2015-03-25 06:15:50
【问题描述】:
我已经尝试了所有可以在 SO 上找到的建议,并且我能够在我的 ListView 上成功使用这个确切的代码,但由于某种原因,我无法在我的 @987654322 上设置长点击监听器@。我在方法setupGridViewListener(); 中登录,它甚至没有运行,但我在onCreateView() 中有我的方法。不知道为什么它不起作用。长按后应该会弹出警告对话框,但不会。方法在我的班级底部。
更新:
我没有提到我的onClickListener 工作正常。所以我至少可以单击一下,这会显示我的活动。但是,该代码在我的适配器中,所以也许它们应该在同一个类中?我包括我的适配器和下面的 2 个xmls。
更新 2
我发现了几件值得一提的事情,即使在我的代码再次运行之后也是如此。首先,将我的点击监听器放入我的适配器是一个错误。它大大减慢了速度……如此之多,我很想找到一种方法将事情放在另一个线程上。但最后,我不需要。我意识到我实际上可以让我的两个点击监听器进入我的PhotoTab.java 类。这立即使它更快(恢复正常)。但另一个奇怪的事情是,IDE 不让我使用OnClickListener,而是坚持让我回到OnItemClickListener。所以一旦我把它们改回来,一切都恢复了。所以听众最终在我的GridView变量上,例如gridView.setOnItemClickListener(new OnItemClickListener() {} 不是我的 ImageView 项目变量。也许这就是让事情变得更快的原因?有一个GridView,但有24 个ImageViews(GridView 单元格)。但这只是一个猜测。我已将我的代码更新为当前的工作代码。除了我还在处理长点击代码,所以这还不正确。不过,对话框警报有效,GridView 中的每个项目都是可点击的。
PhotoTab.java
package org.azurespot.cutecollection.phototab;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import org.azurespot.R;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
/**
* Created by mizu on 2/8/15.
*/
public class PhotoTab extends Fragment {
private GridView gridView;
File[] files;
ArrayList<PhotoGridItem> photoList = new ArrayList<>();
ArrayAdapter<PhotoGridItem> adapter;
Bitmap bitmap;
byte[] byteArray = null;
private String[] allSDCardFiles = null;
PhotoGridItem photoGridItem;
public PhotoTab() {
super();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.photo_tab, container, false);
// with fragments, make sure you include the rootView when finding id
gridView = (GridView) v.findViewById(R.id.photo_grid);
// this null check won't instantiate again if it was already
// if(adapter == null)
adapter = new GridViewPhotoAdapter(getActivity(), R.layout.photo_grid_item);
// Set the Adapter to GridView
gridView.setAdapter(adapter);
// load contents of SD card
loadSDCard();
// add the default icons remaining, to GridView, if less than 24 files on SD card
for (int i = 0; i < (24 - allSDCardFiles.length); i++) {
adapter.add(new PhotoGridItem(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_photo_placeholder)));
adapter.notifyDataSetChanged();
i++;
}
//Convert the bitmap to byte array, so can pass through intent
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
final byte[] byteArray = stream.toByteArray();
this.byteArray = byteArray;
setupGridViewListener();
return v;
}
public void loadSDCard() {
try {
// gets directory CutePhotos from sd card
File cutePhotosDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES), "Cute Photos");
// lists all files in CutePhotos, loads in Files[] array
files = cutePhotosDir.listFiles();
for (File singleFile : files) {
String filePath = singleFile.getAbsolutePath();
// this method makes size small for the view (to save memory)
bitmap = decodeImageBitmap(filePath, 270, 270);
photoGridItem = new PhotoGridItem(bitmap);
// Check if this is a new bitmap file
adapter.add(photoGridItem);
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
}
// get number of files in Cute Photos directory
allSDCardFiles = new String[files.length];
}
private void setupGridViewListener(){
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter,
View item, int pos, long id) {
Intent i = new Intent(getActivity(), PhotoViewerActivity.class);
i.putExtra("photo", byteArray);
startActivity(i);
}
});
// to delete a photo item
gridView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> aView, View item,
final int pos, long id) {
new AlertDialog.Builder(getActivity())
.setTitle("Delete")
.setMessage("Delete this cute photo?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// delete from ArrayList first
// PhotoTab.photoList.remove(position);
// get file name then delete it from SD card
File cutePhotosDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES), "CutePhotos/" + photoGridItem);
cutePhotosDir.delete();
// after each item delete, must refresh load so can delete again
// photoTab.loadSDCard();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
dialog.cancel();
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
return true;
}
});
}
// next 2 methods scale the bitmap image to a better size (so not huge)
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
public static Bitmap decodeImageBitmap(String path, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap bm = BitmapFactory.decodeFile(path, options);
return bm;
}
}
GridViewPhotoAdapter
package org.azurespot.cutecollection.phototab;
/**
* Created by mizu on 2/5/15.
*/
// package org.azurespot.cutecollection;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import org.azurespot.R;
/**
* Created by mizu on 2/5/15.
*/
public class GridViewPhotoAdapter extends ArrayAdapter<PhotoGridItem> {
public Context context;
private int resourceId;
ViewHolder holder = null;
int position;
public GridViewPhotoAdapter(Context context, int layoutResourceId) {
super(context, layoutResourceId);
this.context = context;
this.resourceId = layoutResourceId;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
this.position = position;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(resourceId, parent, false);
holder = new ViewHolder();
holder.imageView = (ImageView) row.findViewById(R.id.photo_grid_view);
// stores holder with view
row.setTag(holder);
} else {
holder = (ViewHolder)row.getTag();
}
// gets position of whichever photo you click on in the GridView
final PhotoGridItem photoGridItem = getItem(position);
if (photoGridItem != null) {
Bitmap bm = photoGridItem.getImage();
holder.imageView.setImageBitmap(bm);
// positioning the image in the GridView slot
holder.imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
holder.imageView.setLayoutParams(new LinearLayout.LayoutParams(270, 270));
}
return row;
}
public class ViewHolder{
ImageView imageView;
}
}
photo_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_view"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#2198bb">
<GridView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/photo_grid"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:verticalSpacing="5dp"
android:horizontalSpacing="2dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="25dp"
android:columnWidth="100dp"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:scrollbarStyle="outsideOverlay"
android:verticalScrollbarPosition="right" />
</RelativeLayout>
photo_grid_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/photo_grid_view"
android:focusable="false"
android:focusableInTouchMode="false"/>
</LinearLayout>
【问题讨论】:
-
您好,我查看了您的代码,您想在长按网格视图项目时删除照片。您只需单击即可正常工作,因为您在图像单击中实现了。我建议不要尝试捕捉网格视图长按你可以使用图像视图长按监听器。 :)
-
感谢 Bhavdip,另一位发帖人建议这样做,它奏效了! :)
-
@Noni,我喜欢你的 cmets 关于在适配器中设置侦听器的错误。这似乎很正常(您之前所做的),我已经为 ListView 这样做了,而不是 GridView。 Google 已在 ListView 的适配器中推荐了侦听器。我不知道使用 GridView 会如此不同。现在您在适配器之外设置了侦听器,我怀疑您当前的技术会占用更多内存,但可能不会太多。
-
是的,这是一个令人惊讶的发现。可能我仍然应该将图像加载过程放入
AsyncTask或其他类型的Thread,但是当我将所有内容放入PhotoTab.java类而不是适配器类时,它显示出显着的变化。不过,感谢您的额外见解!
标签: android android-gridview onitemclicklistener onitemlongclicklistener