在 GridView 中加载异步图像 (Android)
我有一个带有图片/文本的 GridView,从不同的服务器加载(我只知道 URL)。 我尝试根据 修改我的代码ryac教程。
在我的 Activity 文件中,我将 GAdapter
设置为我的 GridView
,如下所示:
GridView mGridMain = (GridView)findViewById(R.id.gvMain);
mGridMain.setAdapter(new GAdapter(this, listAppInfo));
我修改了自己的适配器并尝试调整它:
public class GAdapter extends BaseAdapter {
private Context mContext;
private List<SiteStaff> mListAppInfo;
private HashMap<Integer, ImageView> views;
/**
* @param context
* @param list
*/
public GAdapter(Context context, List<SiteStaff> list) {
mContext = context;
mListAppInfo = list;
}
@Override
public int getCount() {
return mListAppInfo.size();
}
@Override
public Object getItem(int position) {
return mListAppInfo.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
SiteStaff entry = mListAppInfo.get(position);
if(convertView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(R.layout.list_g, null);
}
ImageView v;
// get the ImageView for this position in the GridView..
v = (ImageView)convertView.findViewById(R.id.ivIcon);
//set default image
v.setImageResource(android.R.drawable.ic_menu_gallery);
TextView tvName = (TextView)convertView.findViewById(R.id.tvName);
tvName.setText(entry.getName());
Bundle b = new Bundle ();
b.putString("file", "http://www.test.com/mypict.jpg");
b.putInt("pos", position);
// this executes a new thread, passing along the file
// to load and the position via the Bundle..
new LoadImage().execute(b);
// puts this new ImageView and position in the HashMap.
views.put(position, v);
// return the view to the GridView..
// at this point, the ImageView is only displaying the
// default icon..
return v;
}
// this is the class that handles the loading of images from the cloud
// inside another thread, separate from the main UI thread..
private class LoadImage extends AsyncTask<Bundle, Void, Bundle> {
@Override
protected Bundle doInBackground(Bundle... b) {
// get the file that was passed from the bundle..
String file = b[0].getString("file");
URL UrlImage;
Bitmap bm=null;
try {
UrlImage = new URL (file);
HttpURLConnection connection;
connection = (HttpURLConnection) UrlImage.openConnection();
bm= BitmapFactory.decodeStream(connection.getInputStream());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// now that we have the bitmap (bm), we'll
// create another bundle to pass to 'onPostExecute'.
// this is the method that is called at the end of
// our task. like a callback function..
// this time, we're not passing the filename to this
// method, but the actual bitmap, not forgetting to
// pass the same position along..
Bundle bundle = new Bundle();
bundle.putParcelable("bm", bm);
bundle.putInt("pos", b[0].getInt("pos"));
bundle.putString("file", file); // this is only used for testing..
return bundle;
}
@Override
protected void onPostExecute(Bundle result) {
super.onPostExecute(result);
// just a test to make sure that the position and
// file name are matching before and after the
// image has loaded..
Log.d("test", "*after: " + result.getInt("pos") + " | " + result.getString("file"));
// here's where the photo gets put into the
// appropriate ImageView. we're retrieving the
// ImageView from the HashMap according to
// the position..
ImageView view = views.get(result.getInt("pos"));
// then we set the bitmap into that view. and that's it.
view.setImageBitmap((Bitmap) result.getParcelable("bm"));
}
}
}
但显示以下错误:
11-16 06:16:08.285: E/AndroidRuntime(517): FATAL EXCEPTION: main
11-16 06:16:08.285: E/AndroidRuntime(517): java.lang.NullPointerException
11-16 06:16:08.285: E/AndroidRuntime(517): at common.adapter.GAdapter.getView(GAdapter.java:139)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.AbsListView.obtainView(AbsListView.java:1315)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.GridView.onMeasure(GridView.java:932)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.view.View.measure(View.java:8171)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.view.View.measure(View.java:8171)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.view.View.measure(View.java:8171)
直到现在,我从来没有在Android中使用过Threads。如果有人能帮助我,我将不胜感激。
I have a GridView
with pictures/text, loaded from different servers (I only know the URL).
I tried to modify my code, based on the tutorial of ryac.
In my Activity file, I set the GAdapter
to my GridView
like this:
GridView mGridMain = (GridView)findViewById(R.id.gvMain);
mGridMain.setAdapter(new GAdapter(this, listAppInfo));
I have modified my own adapter and try to adapt it:
public class GAdapter extends BaseAdapter {
private Context mContext;
private List<SiteStaff> mListAppInfo;
private HashMap<Integer, ImageView> views;
/**
* @param context
* @param list
*/
public GAdapter(Context context, List<SiteStaff> list) {
mContext = context;
mListAppInfo = list;
}
@Override
public int getCount() {
return mListAppInfo.size();
}
@Override
public Object getItem(int position) {
return mListAppInfo.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
SiteStaff entry = mListAppInfo.get(position);
if(convertView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(R.layout.list_g, null);
}
ImageView v;
// get the ImageView for this position in the GridView..
v = (ImageView)convertView.findViewById(R.id.ivIcon);
//set default image
v.setImageResource(android.R.drawable.ic_menu_gallery);
TextView tvName = (TextView)convertView.findViewById(R.id.tvName);
tvName.setText(entry.getName());
Bundle b = new Bundle ();
b.putString("file", "http://www.test.com/mypict.jpg");
b.putInt("pos", position);
// this executes a new thread, passing along the file
// to load and the position via the Bundle..
new LoadImage().execute(b);
// puts this new ImageView and position in the HashMap.
views.put(position, v);
// return the view to the GridView..
// at this point, the ImageView is only displaying the
// default icon..
return v;
}
// this is the class that handles the loading of images from the cloud
// inside another thread, separate from the main UI thread..
private class LoadImage extends AsyncTask<Bundle, Void, Bundle> {
@Override
protected Bundle doInBackground(Bundle... b) {
// get the file that was passed from the bundle..
String file = b[0].getString("file");
URL UrlImage;
Bitmap bm=null;
try {
UrlImage = new URL (file);
HttpURLConnection connection;
connection = (HttpURLConnection) UrlImage.openConnection();
bm= BitmapFactory.decodeStream(connection.getInputStream());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// now that we have the bitmap (bm), we'll
// create another bundle to pass to 'onPostExecute'.
// this is the method that is called at the end of
// our task. like a callback function..
// this time, we're not passing the filename to this
// method, but the actual bitmap, not forgetting to
// pass the same position along..
Bundle bundle = new Bundle();
bundle.putParcelable("bm", bm);
bundle.putInt("pos", b[0].getInt("pos"));
bundle.putString("file", file); // this is only used for testing..
return bundle;
}
@Override
protected void onPostExecute(Bundle result) {
super.onPostExecute(result);
// just a test to make sure that the position and
// file name are matching before and after the
// image has loaded..
Log.d("test", "*after: " + result.getInt("pos") + " | " + result.getString("file"));
// here's where the photo gets put into the
// appropriate ImageView. we're retrieving the
// ImageView from the HashMap according to
// the position..
ImageView view = views.get(result.getInt("pos"));
// then we set the bitmap into that view. and that's it.
view.setImageBitmap((Bitmap) result.getParcelable("bm"));
}
}
}
But the below error is displayed:
11-16 06:16:08.285: E/AndroidRuntime(517): FATAL EXCEPTION: main
11-16 06:16:08.285: E/AndroidRuntime(517): java.lang.NullPointerException
11-16 06:16:08.285: E/AndroidRuntime(517): at common.adapter.GAdapter.getView(GAdapter.java:139)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.AbsListView.obtainView(AbsListView.java:1315)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.GridView.onMeasure(GridView.java:932)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.view.View.measure(View.java:8171)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1012)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.LinearLayout.measureVertical(LinearLayout.java:381)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.LinearLayout.onMeasure(LinearLayout.java:304)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.view.View.measure(View.java:8171)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3132)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)
11-16 06:16:08.285: E/AndroidRuntime(517): at android.view.View.measure(View.java:8171)
Until now, I never used Threads in Android. I would be grateful if someone can help me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我在 getView() 中发现你正在做的最后
,但它的视图从未初始化。这就是为什么您会收到
java.lang.NullPointerException
为了避免这种情况,请在 GAdapter 构造函数中初始化哈希映射对象
如果您检查问题中引用的示例,您会发现
I fount in getView() at the end you are doing
But it
views
never initialized. That's why you are gettingjava.lang.NullPointerException
To avoid this please initialized hash map object in your in GAdapter Constructor
If you check the example you are refering in your question you will find