我有一个gridView的baseadapter,当没有视图时会创建一个视图。这是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");
} 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;
}
正如您所看到的,我根据我的值部分中的xml布局文件为视图提供了新的ID iconImageView_id
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item type="id" name="iconImageView_id"/>
</resources>
我正在尝试在另一个类中使用该imageView,以便我可以像这样为它分配一个位图:
// 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");
}
但是另一个类也是baseadapter。
这是我尝试使用imageView的类的完整部分:
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因为我显然不能只是静态地引用这个视图。
那么我该如何制作它以便我可以在其他类中使用该imageView?
这是堆栈跟踪错误:
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)
第200行:
imageView1.setImageBitmap( bitmap );
增加:
以下是我正在处理的两个完整课程:
AppInfoAdapter.java:
package com.example.awesomefilebuilderwidget;
IMPORTS
public class AppInfoAdapter extends BaseAdapter implements Filterable {
private Context mContext;
private List<ResolveInfo> mListAppInfo;
private PackageManager mPackManager;
private List<ResolveInfo> originalListAppInfo;
private Filter filter;
private String fname;
public AppInfoAdapter(Context c, List<ResolveInfo> listApp,
PackageManager pm) {
mContext = c;
this.originalListAppInfo = this.mListAppInfo = listApp;
mPackManager = pm;
Log.d("AppInfoAdapter", "top");
}
@Override
public int getCount() {
Log.d("AppInfoAdapter", "getCount()");
return mListAppInfo.size();
}
@Override
public Object getItem(int position) {
Log.d("AppInfoAdapter", "getItem");
return mListAppInfo.get(position);
}
@Override
public long getItemId(int position) {
Log.d("AppInfoAdapter", "getItemId");
return position;
}
@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;
}
和GridViewAdapter.java:
package com.example.awesomefilebuilderwidget;
IMPORTS
public class GridViewAdapter extends BaseAdapter {
private Context Context;
// Keep all Images in array list
public ArrayList<Integer> drawables = new ArrayList<Integer>();
CheckBox mCheckBox=null;
// Constructor
public GridViewAdapter(Context c){
Context = c;
Log.d("GridViewAdapter", "Constructor is set");
drawables.add(R.drawable.pattern1);
Log.d("GridViewAdapter", "pattern1 added");
drawables.add(R.drawable.pattern2);
Log.d("GridViewAdapter", "pattern2 added");
drawables.add(R.drawable.trashcan);
Log.d("GridViewAdapter", "trashcan added");
drawables.add(R.drawable.ic_launcher);
Log.d("GridViewAdapter", "ic_launcher added");
}
public void setCheckBox(CheckBox checkbox){
mCheckBox=checkbox;
}
@Override
// How many items are in the data set represented by this Adapter
public int getCount() {
return drawables.size();
}
@Override
// Get the data item associated with the specified position in the
// data set
public Object getItem(int position) {
return drawables.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public boolean isSdReadable() {
boolean mExternalStorageAvailable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = true;
Log.i("isSdReadable", "External storage card is readable.");
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
Log.i("isSdReadable", "External storage card is readable.");
mExternalStorageAvailable = true;
} else {
// Something else is wrong. It may be one of many other
// states, but all we need to know is we can neither read nor write
mExternalStorageAvailable = false;
}
return mExternalStorageAvailable;
}
@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");
} 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;
}
}
答案 0 :(得分:1)
你是如何一起尝试两个适应器的?刚刚开始讨论这个问题,你可能正在获得NPE,因为两个适配器指向的视图并不相同。 (I.E他们每个人都生成自己的视图,传入的视图与适配器不相关)。
如果你真的想按照自己的方式做到这一点,那么你可以通过以下方式找到成功:
定义根布局,root.xml。
在您的MainActivity构造函数中,像这样渗透此视图:
ViewGroup viewRoot = LayoutInfalter.from(this).inflate(R.layout.xml);
setContentView(viewRoot);
在整个应用程序中维护对viewRoot的引用,并且您添加的任何视图都应使用此父视图(或此父视图中的视图)来托管其视图。
当您拨打电话时:
ImageView imageView1 = (ImageView)v.findViewById(R.id.iconImageView_id);
而不是使用传入的视图(我怀疑它来自视图helearchy的pralell部分,它不包含你的视图(因此是NPE))使用这个:
viewRoot.findViewById(R.id.iconImageView_id);
只要您的订购是正确的(I.E.该视图存在于该视图中),您现在应该可以访问。