如何禁止在 GridView 中点击特定图像 - Android
How to disable the click of a specific image in GridView - Android
整晚都在复习逻辑,就是得不到答案。我需要我的可绘制占位符图像不可点击,并且我的真实图像(来自 SD 卡的照片)对于常规点击和长按都可以点击。我已经记录了关于如何编写 if 条件的一百万个版本,它会说这样的话:if the image Bitmap
is the drawable and equal to the position clicked on,然后处理点击监听器。但这永远不可能发生!他们永远不平等。当我将可绘制位图与单击位置的位图进行比较时,Bitmap
数字总是不同(这对我来说毫无意义)。
所以我尝试了另一种方法。我想尝试使用我发现的方法 here 直接在其位置禁用可绘制对象。这些方法,我放在我的adapter中class.
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return true;
}
但是这些方法对我来说毫无意义。 Where/how 我会根据我的情况给他们打电话吗?我不明白这些应该如何禁用我的自定义 GridView
中的 select 项。如果您有任何想法,谢谢。
这是我来自 logcat. 的日志语句值 我通过单击 GridView
中的可绘制图像获得了这些值,但如您所见, 图片 Bitmap
和适配器位置项不一样。那么我如何识别我的可绘制对象以便我知道禁用那里的点击?
Value of adapter position item: android.graphics.Bitmap@430706e0
Value of drawableObject: android.graphics.Bitmap@4301fff0
Value of photoGridItem: android.graphics.Bitmap@4301a768
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.util.Log;
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;
private String[] numberSDCardFiles = null;
PhotoGridItem drawableObject;
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);
adapter = new GridViewPhotoAdapter(getActivity(), photoList);
// with fragments, make sure you include the rootView when finding id
gridView = (GridView) v.findViewById(R.id.photo_grid);
gridView.setAdapter(adapter);
if(adapter.getCount() == 0) {
// 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 - numberSDCardFiles.length); i++) {
drawableObject = new PhotoGridItem(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_photo_placeholder));
adapter.add(drawableObject);
adapter.notifyDataSetChanged();
}
}
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
numberSDCardFiles = new String[files.length];
}
private void setupGridViewListener(){
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView,
View item, int pos, long id) {
//Convert the bitmap to byte array, so can pass through intent
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap bm = adapter.getItem(pos).getImage();
bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
final byte[] byteArray = stream.toByteArray();
Intent i = new Intent(getActivity(), PhotoViewerActivity.class);
i.putExtra("photo", byteArray);
startActivity(i);
Log.d("TAG", "Value of bm: " + bm);
Log.d("TAG", "Value of adapter position item: " + adapter.getItem(pos));
Log.d("TAG", "Value of drawableObject: " + drawableObject);
}
});
// 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
photoList.remove(pos);
// get file name then delete it from SD card
String name = files[pos].getName();
File file = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES), "Cute Photos" + "/" + name);
file.delete();
// after each item delete, replace with default icon
adapter.add(new PhotoGridItem(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_photo_placeholder)));
adapter.notifyDataSetChanged();
}
})
.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.java
package org.azurespot.cutecollection.phototab;
/**
* Created by mizu on 2/5/15.
*/
// package org.azurespot.cutecollection;
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;
import java.util.ArrayList;
/**
* Created by mizu on 2/5/15.
*/
public class GridViewPhotoAdapter extends ArrayAdapter<PhotoGridItem> {
ViewHolder holder = null;
int position;
public GridViewPhotoAdapter(Context context, ArrayList<PhotoGridItem> photos) {
super(context, 0, photos);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
this.position = position;
if (v == null) {
v = LayoutInflater.from(getContext())
.inflate(R.layout.photo_grid_item, parent, false);
holder = new ViewHolder();
holder.imageView = (ImageView) v.findViewById(R.id.photo_grid_view);
// stores holder with view
v.setTag(holder);
} else {
holder = (ViewHolder)v.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 v;
}
public class ViewHolder{
ImageView imageView;
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return true;
}
}
在 IsEnabled 方法中添加您的逻辑,如下所示
@Override
public boolean isEnabled(int position) {
if(position == POSITION_U_WANT_TO_DISABLE) {
return false;
}
return true;
}
根据您的代码,您总是在该方法中返回 true(已启用)。
难以置信,但我终于找到了正确的逻辑。我不需要上面提到的 2 个 List 方法,因为这些方法依赖于我在 GridView
定位中识别可绘制对象与照片。因此,在将我的占位符可绘制对象添加到我的网格时,我还将它们全部放入 ArrayList<Bitmap>
中,以便我可以搜索列表并在需要时提取可绘制对象的值。
然后我在点击侦听器的代码中添加了一个条件,如果我的 ArrayList
或 Bitmaps
包含在被点击的视图位置找到的位图,则不要继续执行点击侦听器的代码。如果它不包含 ArrayList
中的 Bitmap
,则继续处理它。
我检查了我是否仍然可以在 GridView
中添加和删除项目并且仍然可以进行有条件的工作,我确实可以。以下是上下文中的新增内容。
ArrayList<Bitmap> bmList = new ArrayList<>();
...
// add the default icons remaining, to GridView, if less than 24 files on SD card
for (int i = 0; i < (24 - numberSDCardFiles.length); i++) {
drawableObject = new PhotoGridItem(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_photo_placeholder));
// adds each drawable Bitmap to an ArrayList
bmList.add(drawableObject.getImage());
// adds to adapter
adapter.add(drawableObject);
adapter.notifyDataSetChanged();
}
...
private void setupGridViewListener(){
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView,
View item, int pos, long id) {
if(!bmList.contains(adapter.getItem(pos).getImage())) {
//Convert the bitmap to byte array, so can pass through intent
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap bm = adapter.getItem(pos).getImage();
bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
final byte[] byteArray = stream.toByteArray();
Intent i = new Intent(getActivity(), PhotoViewerActivity.class);
i.putExtra("photo", byteArray);
startActivity(i);
}
}
});
整晚都在复习逻辑,就是得不到答案。我需要我的可绘制占位符图像不可点击,并且我的真实图像(来自 SD 卡的照片)对于常规点击和长按都可以点击。我已经记录了关于如何编写 if 条件的一百万个版本,它会说这样的话:if the image Bitmap
is the drawable and equal to the position clicked on,然后处理点击监听器。但这永远不可能发生!他们永远不平等。当我将可绘制位图与单击位置的位图进行比较时,Bitmap
数字总是不同(这对我来说毫无意义)。
所以我尝试了另一种方法。我想尝试使用我发现的方法 here 直接在其位置禁用可绘制对象。这些方法,我放在我的adapter中class.
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return true;
}
但是这些方法对我来说毫无意义。 Where/how 我会根据我的情况给他们打电话吗?我不明白这些应该如何禁用我的自定义 GridView
中的 select 项。如果您有任何想法,谢谢。
这是我来自 logcat. 的日志语句值 我通过单击 GridView
中的可绘制图像获得了这些值,但如您所见, 图片 Bitmap
和适配器位置项不一样。那么我如何识别我的可绘制对象以便我知道禁用那里的点击?
Value of adapter position item: android.graphics.Bitmap@430706e0
Value of drawableObject: android.graphics.Bitmap@4301fff0
Value of photoGridItem: android.graphics.Bitmap@4301a768
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.util.Log;
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;
private String[] numberSDCardFiles = null;
PhotoGridItem drawableObject;
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);
adapter = new GridViewPhotoAdapter(getActivity(), photoList);
// with fragments, make sure you include the rootView when finding id
gridView = (GridView) v.findViewById(R.id.photo_grid);
gridView.setAdapter(adapter);
if(adapter.getCount() == 0) {
// 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 - numberSDCardFiles.length); i++) {
drawableObject = new PhotoGridItem(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_photo_placeholder));
adapter.add(drawableObject);
adapter.notifyDataSetChanged();
}
}
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
numberSDCardFiles = new String[files.length];
}
private void setupGridViewListener(){
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView,
View item, int pos, long id) {
//Convert the bitmap to byte array, so can pass through intent
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap bm = adapter.getItem(pos).getImage();
bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
final byte[] byteArray = stream.toByteArray();
Intent i = new Intent(getActivity(), PhotoViewerActivity.class);
i.putExtra("photo", byteArray);
startActivity(i);
Log.d("TAG", "Value of bm: " + bm);
Log.d("TAG", "Value of adapter position item: " + adapter.getItem(pos));
Log.d("TAG", "Value of drawableObject: " + drawableObject);
}
});
// 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
photoList.remove(pos);
// get file name then delete it from SD card
String name = files[pos].getName();
File file = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES), "Cute Photos" + "/" + name);
file.delete();
// after each item delete, replace with default icon
adapter.add(new PhotoGridItem(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_photo_placeholder)));
adapter.notifyDataSetChanged();
}
})
.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.java
package org.azurespot.cutecollection.phototab;
/**
* Created by mizu on 2/5/15.
*/
// package org.azurespot.cutecollection;
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;
import java.util.ArrayList;
/**
* Created by mizu on 2/5/15.
*/
public class GridViewPhotoAdapter extends ArrayAdapter<PhotoGridItem> {
ViewHolder holder = null;
int position;
public GridViewPhotoAdapter(Context context, ArrayList<PhotoGridItem> photos) {
super(context, 0, photos);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
this.position = position;
if (v == null) {
v = LayoutInflater.from(getContext())
.inflate(R.layout.photo_grid_item, parent, false);
holder = new ViewHolder();
holder.imageView = (ImageView) v.findViewById(R.id.photo_grid_view);
// stores holder with view
v.setTag(holder);
} else {
holder = (ViewHolder)v.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 v;
}
public class ViewHolder{
ImageView imageView;
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return true;
}
}
在 IsEnabled 方法中添加您的逻辑,如下所示
@Override
public boolean isEnabled(int position) {
if(position == POSITION_U_WANT_TO_DISABLE) {
return false;
}
return true;
}
根据您的代码,您总是在该方法中返回 true(已启用)。
难以置信,但我终于找到了正确的逻辑。我不需要上面提到的 2 个 List 方法,因为这些方法依赖于我在 GridView
定位中识别可绘制对象与照片。因此,在将我的占位符可绘制对象添加到我的网格时,我还将它们全部放入 ArrayList<Bitmap>
中,以便我可以搜索列表并在需要时提取可绘制对象的值。
然后我在点击侦听器的代码中添加了一个条件,如果我的 ArrayList
或 Bitmaps
包含在被点击的视图位置找到的位图,则不要继续执行点击侦听器的代码。如果它不包含 ArrayList
中的 Bitmap
,则继续处理它。
我检查了我是否仍然可以在 GridView
中添加和删除项目并且仍然可以进行有条件的工作,我确实可以。以下是上下文中的新增内容。
ArrayList<Bitmap> bmList = new ArrayList<>();
...
// add the default icons remaining, to GridView, if less than 24 files on SD card
for (int i = 0; i < (24 - numberSDCardFiles.length); i++) {
drawableObject = new PhotoGridItem(BitmapFactory.decodeResource(getResources(),
R.drawable.ic_photo_placeholder));
// adds each drawable Bitmap to an ArrayList
bmList.add(drawableObject.getImage());
// adds to adapter
adapter.add(drawableObject);
adapter.notifyDataSetChanged();
}
...
private void setupGridViewListener(){
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView,
View item, int pos, long id) {
if(!bmList.contains(adapter.getItem(pos).getImage())) {
//Convert the bitmap to byte array, so can pass through intent
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap bm = adapter.getItem(pos).getImage();
bm.compress(Bitmap.CompressFormat.PNG, 100, stream);
final byte[] byteArray = stream.toByteArray();
Intent i = new Intent(getActivity(), PhotoViewerActivity.class);
i.putExtra("photo", byteArray);
startActivity(i);
}
}
});