我有两个不同的适配器:一个用于gridView,另一个用于listView。在我的listView中,我有一个用户安装的应用程序列表,旁边有应用程序图标。在每个listView项中,我也有一个复选框。选中此复选框后,我希望它获取该特定应用程序的图标,然后将其发送到gridView,其中图标将出现在gridView中。
问题是当我点击复选框时,我得到了这个NPE:
FATAL EXCEPTION: main
12-22 15:58:45.782: E/AndroidRuntime(28793): java.lang.NullPointerException
12-22 15:58:45.782: E/AndroidRuntime(28793): at com.example.awesomefilebuilderwidget.AppInfoAdapter$1.onClick(AppInfoAdapter.java:200)
12-22 15:58:45.782: E/AndroidRuntime(28793): at android.view.View.performClick(View.java:2532)
12-22 15:58:45.782: E/AndroidRuntime(28793): at android.widget.CompoundButton.performClick(CompoundButton.java:99)
12-22 15:58:45.782: E/AndroidRuntime(28793): at android.view.View$PerformClick.run(View.java:9308)
12-22 15:58:45.782: E/AndroidRuntime(28793): at android.os.Handler.handleCallback(Handler.java:587)
12-22 15:58:45.782: E/AndroidRuntime(28793): at android.os.Handler.dispatchMessage (Handler.java:92)
12-22 15:58:45.782: E/AndroidRuntime(28793): at android.os.Looper.loop(Looper.java:150)
12-22 15:58:45.782: E/AndroidRuntime(28793): at android.app.ActivityThread.main(ActivityThread.java:4333)
12-22 15:58:45.782: E/AndroidRuntime(28793): at java.lang.reflect.Method.invokeNative(Native Method)
12-22 15:58:45.782: E/AndroidRuntime(28793): at java.lang.reflect.Method.invoke(Method.java:507)
12-22 15:58:45.782: E/AndroidRuntime(28793): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
12-22 15:58:45.782: E/AndroidRuntime(28793): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
12-22 15:58:45.782: E/AndroidRuntime(28793): at dalvik.system.NativeStart.main(Native Method)
以下是复选框的onClick方法部分:
addCheckbox
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (addCheckbox.isChecked()) {
System.out.println("Checked");
PackageManager pm = mContext.getPackageManager();
final int DEST_IMAGE_WIDTH = 100;
final int DEST_IMAGE_HEIGHT = 100;
ApplicationInfo appInfo = mContext.getApplicationInfo();
Drawable appIcon = pm.getApplicationIcon(appInfo);
Bitmap appBmp = Bitmap.createBitmap(DEST_IMAGE_WIDTH, DEST_IMAGE_HEIGHT, Config.ARGB_8888);
// Creates a new canvas based on the image specification
// created just above.
Canvas canvas = new Canvas(appBmp);
// (optional) Fills the entire canvas
canvas.drawColor(Color.WHITE);
// You need to set bounds otherwise a 0,0 sized image would be drawn.
appIcon.setBounds(0, 0, DEST_IMAGE_WIDTH, DEST_IMAGE_HEIGHT);
appIcon.draw(canvas);
/// Let's save to a .jpg file ...
File file = new File(mContext.getFilesDir().getAbsolutePath() + "/test2.jpg");
FileOutputStream out;
try
{
file.createNewFile();
out = new FileOutputStream(file);
appBmp.compress(Bitmap.CompressFormat.JPEG, 80, out);
Log.i("AppInfoAdapter", "The icon for use in gridView is saved");
out.close();
// Load back the image file to confirms it works
Bitmap bitmap = BitmapFactory.decodeFile( file.getAbsolutePath() );
ImageView imageView1 = (ImageView)v.findViewById(R.id.iconImageView_id);
imageView1.setImageBitmap( bitmap );
Log.i("AppInfoAdapter", "The icon image has been set into the gridView");
}
catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
catch (IOException e2)
{
e2.printStackTrace();
}
} else {
System.out.println("Un-Checked");
}
}
这是第200行:
ImageView imageView1 = (ImageView)v.findViewById(R.id.iconImageView_id);
这是我的gridView适配器的getView()部分,我想将图标图像放入视图中:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Try to reuse the views
ImageView view = (ImageView) convertView;
boolean checked = (mCheckBox==null)?false:(((CheckBox) mCheckBox).isChecked());
// if convert view is null then create a new instance else reuse it
if (view == null) {
view = new ImageView(Context);
Log.d("GridViewAdapter", "new imageView added");
view.setId(R.id.iconImageView_id);
}
if(checked == true){
isSdReadable();
Log.i("GridViewAdapter", "checkbox is checked");
/*FileInputStream in = null;
try {
in = Context.openFileInput("BitmapImage");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Load back the image file to confirm it works
Bitmap bitmap = BitmapFactory.decodeStream(in);
view.setImageBitmap(bitmap);
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
} else {
Log.i("GridView", "Icons not for use/checkbox not checked");
}
view.setImageResource(drawables.get(position));
view.setScaleType(ImageView.ScaleType.CENTER_CROP);
view.setLayoutParams(new android.widget.GridView.LayoutParams(70, 70));
view.setTag(String.valueOf(position));
return view;
}
});
我试图为新视图分配一个ID,然后在图像中设置((在我的ONCLICK注意:
ImageView imageView1 = (ImageView)v.findViewById(R.id.iconImageView_id);
在我的网格中:
view.setId(R.id.iconImageView_id);
)) 但这不起作用,只给我一个NPE,因为两个适配器指向的视图heirachies是不一样的。
那么有没有办法可以让他们指向相同的视图heirachy? (实际上,现在考虑它与我第一次想到这个时相比......
我可以在gridView适配器上使用FileinputStream来获取图像吗?如果是这样,请告诉我如何解决这个问题。我已经尝试过使用OpenfileInput这样的东西,但我无法让它工作。)
增加:
这是listView适配器的整个getView():
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// get the selected entry
final ResolveInfo entry = (ResolveInfo) mListAppInfo.get(position);
// reference to convertView
View v = convertView;
// inflate new layout if null
if (v == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
v = inflater.inflate(R.layout.layout_appinfo, null);
Log.d("AppInfoAdapter", "New layout inflated");
}
// load controls from layout resources
ImageView ivAppIcon = (ImageView) v.findViewById(R.id.ivIcon);
TextView tvAppName = (TextView) v.findViewById(R.id.tvName);
TextView tvPkgName = (TextView) v.findViewById(R.id.tvPack);
final CheckBox addCheckbox = (CheckBox) v
.findViewById(R.id.addCheckbox);
Log.d("AppInfoAdapter", "Controls from layout Resources Loaded");
// set data to display
ivAppIcon.setImageDrawable(entry.loadIcon(mPackManager));
tvAppName.setText(entry.activityInfo.loadLabel(mPackManager));
tvPkgName.setText(entry.activityInfo.packageName);
Log.d("AppInfoAdapter", "Data Set To Display");
addCheckbox
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (addCheckbox.isChecked()) {
System.out.println("Checked");
PackageManager pm = mContext.getPackageManager();
final int DEST_IMAGE_WIDTH = 100;
final int DEST_IMAGE_HEIGHT = 100;
ApplicationInfo appInfo = mContext.getApplicationInfo();
Drawable appIcon = pm.getApplicationIcon(appInfo);
Bitmap appBmp = Bitmap.createBitmap(DEST_IMAGE_WIDTH, DEST_IMAGE_HEIGHT, Config.ARGB_8888);
// Creates a new canvas based on the image specification
// created just above.
Canvas canvas = new Canvas(appBmp);
// (optional) Fills the entire canvas
canvas.drawColor(Color.WHITE);
// You need to set bounds otherwise a 0,0 sized image would be drawn.
appIcon.setBounds(0, 0, DEST_IMAGE_WIDTH, DEST_IMAGE_HEIGHT);
appIcon.draw(canvas);
/// Let's save to a .jpg file ...
File file = new File(mContext.getFilesDir().getAbsolutePath() + "/test2.jpg");
FileOutputStream out;
try
{
file.createNewFile();
out = new FileOutputStream(file);
appBmp.compress(Bitmap.CompressFormat.JPEG, 80, out);
Log.i("AppInfoAdapter", "The icon for use in gridView is saved");
out.close();
// Load back the image file to confirms it works
Bitmap bitmap = BitmapFactory.decodeFile( file.getAbsolutePath() );
ImageView imageView1 = (ImageView)v.findViewById(R.id.iconImageView_id);
imageView1.setImageBitmap( bitmap );
Log.i("AppInfoAdapter", "The icon image has been set into the gridView");
}
catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
catch (IOException e2)
{
e2.printStackTrace();
}
} else {
System.out.println("Un-Checked");
}
}
});
// return view
return v;
}
增加: 新NPE:
02-22 22:56:26.852: E/AndroidRuntime(29276): FATAL EXCEPTION: main
02-22 22:56:26.852: E/AndroidRuntime(29276): java.lang.NullPointerException
02-22 22:56:26.852: E/AndroidRuntime(29276): at com.example.awesomefilebuilderwidget.AppInfoAdapter$1.onClick(AppInfoAdapter.java:201)
02-22 22:56:26.852: E/AndroidRuntime(29276): at android.view.View.performClick(View.java:2532)
02-22 22:56:26.852: E/AndroidRuntime(29276): at android.widget.CompoundButton.performClick(CompoundButton.java:99)
02-22 22:56:26.852: E/AndroidRuntime(29276): at android.view.View$PerformClick.run(View.java:9308)
02-22 22:56:26.852: E/AndroidRuntime(29276): at android.os.Handler.handleCallback(Handler.java:587)
02-22 22:56:26.852: E/AndroidRuntime(29276): at android.os.Handler.dispatchMessage(Handler.java:92)
02-22 22:56:26.852: E/AndroidRuntime(29276): at android.os.Looper.loop(Looper.java:150)
02-22 22:56:26.852: E/AndroidRuntime(29276): at android.app.ActivityThread.main(ActivityThread.java:4333)
02-22 22:56:26.852: E/AndroidRuntime(29276): at java.lang.reflect.Method.invokeNative(Native Method)
02-22 22:56:26.852: E/AndroidRuntime(29276): at java.lang.reflect.Method.invoke(Method.java:507)
02-22 22:56:26.852: E/AndroidRuntime(29276): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-22 22:56:26.852: E/AndroidRuntime(29276): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-22 22:56:26.852: E/AndroidRuntime(29276): at dalvik.system.NativeStart.main(Native Method)
增加2: ids.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="iconImageView_id"/>
</resources>
答案 0 :(得分:1)
只需将v
方法上onClick
的名称更改为v1
或其他任何内容,
View v = convertView;
和
public void onClick(View v)
在onClick方法中使用v
时,您在代码中使用了v
CheckBox
,但在这种情况下您没有v.findViewById()
因为{{ 1}}请参阅v
,因此您需要更改其中一个的名称。
//更新
你有新的NPE,就像你在201号线那样,
CheckBox
存在两种可能性:
1-位图为空
2- imageView1为空
首先检查imageView1.setImageBitmap( bitmap );
上是否存在iconImageView_id
,如果存在则检查位图
//更新2
正如我所见,您尝试将图像从一个适配器添加到另一个适配器,因此您有2个选项。
1 - 在网格适配器上完成这项工作(获取位图)(我不知道你想要什么,但你必须发送一些内容才能获得正确的位图)
2-在layout_appinfo
上获取Bitmap
的一个列表,然后用GridAdapter
填充Grid
,并将bitmap
ListAdapter
添加到该列表并致电gridAdapter.notifyDataSetChanged()
要刷新gridAdapter
秒解决方案必须为您服务。