I'm trying to refresh my Listview after my app downloads new data, parses it, and adds it to an array list, which is displayed in the listView. This all happens when the user pulls down to refresh. Except I can't figure out how to refresh my listView, and when I use notifyDataSetChanged, it just throws a null pointer exception at this line. How can I refresh my ListView?
holder.imageView.setImageResource(R.drawable.science);
Here is the logcat
07-30 21:08:25.588: E/AndroidRuntime(26202): FATAL EXCEPTION: main
07-30 21:08:25.588: E/AndroidRuntime(26202): Process: com.bernard.beaconportal, PID: 26202
07-30 21:08:25.588: E/AndroidRuntime(26202): java.lang.NullPointerException
07-30 21:08:25.588: E/AndroidRuntime(26202): at com.bernard.beaconportal.Due_Today_Fragment$Due_TodayAdapter.getView(Due_Today_Fragment.java:753)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.AbsListView.obtainView(AbsListView.java:2343)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.ListView.makeAndAddView(ListView.java:1812)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.ListView.fillDown(ListView.java:698)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.ListView.fillSpecific(ListView.java:1359)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.ListView.layoutChildren(ListView.java:1623)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.AbsListView.onLayout(AbsListView.java:2186)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:343)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.FrameLayout.onLayout(FrameLayout.java:450)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1594)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1160)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.FrameLayout.onLayout(FrameLayout.java:450)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.FrameLayout.onLayout(FrameLayout.java:450)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:801)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.FrameLayout.onLayout(FrameLayout.java:450)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:374)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.FrameLayout.layoutChildren(FrameLayout.java:515)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.widget.FrameLayout.onLayout(FrameLayout.java:450)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.View.layout(View.java:15143)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewGroup.layout(ViewGroup.java:4862)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2323)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2029)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1192)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6231)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:788)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.Choreographer.doCallbacks(Choreographer.java:591)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.Choreographer.doFrame(Choreographer.java:560)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:774)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.os.Handler.handleCallback(Handler.java:808)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.os.Handler.dispatchMessage(Handler.java:103)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.os.Looper.loop(Looper.java:193)
07-30 21:08:25.588: E/AndroidRuntime(26202): at android.app.ActivityThread.main(ActivityThread.java:5299)
07-30 21:08:25.588: E/AndroidRuntime(26202): at java.lang.reflect.Method.invokeNative(Native Method)
07-30 21:08:25.588: E/AndroidRuntime(26202): at java.lang.reflect.Method.invoke(Method.java:515)
07-30 21:08:25.588: E/AndroidRuntime(26202): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836)
07-30 21:08:25.588: E/AndroidRuntime(26202): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
07-30 21:08:25.588: E/AndroidRuntime(26202): at dalvik.system.NativeStart.main(Native Method)
Here is the array adapter, and the method I use to populate the listView
private void populateListView() {
adapter = new Due_TodayAdapter();
ListView list = (ListView)getView().findViewById(R.id.listView1);
list.setAdapter(adapter);
}
public class Due_TodayAdapter extends ArrayAdapter<Due_Today_List> {
public Due_TodayAdapter() {
super(getActivity(), R.layout.item_view, due_today_list);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
convertView = getActivity().getLayoutInflater().inflate(R.layout.item_view, parent, false);
holder = new ViewHolder();
holder.imageView = (ImageView)convertView.findViewById(R.id.item_iconclass);
holder.HomeworkDueText = (TextView) convertView.findViewById(R.id.item_texthomeworkdue);
holder.DescriptionText = (TextView) convertView.findViewById(R.id.item_textdescription);
holder.TeacherText = (TextView) convertView.findViewById(R.id.item_textteacher);
holder.TypeText = (TextView) convertView.findViewById(R.id.item_texttype);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
Due_Today_List currenthomeworkdue = due_today_list.get(position);
if(currenthomeworkdue.getType() != null && !currenthomeworkdue.getType().isEmpty()){
Teacher = currenthomeworkdue.getTeacher().substring(0,1).toUpperCase()+currenthomeworkdue.getTeacher().substring(1).toLowerCase();
//Description = currenthomeworkdue.getDescription().substring(5);
Description = currenthomeworkdue.getDescription().toString();
Description = StringUtils.trim(Description);
if(currenthomeworkdue.Band.substring(0, Math.min(currenthomeworkdue.Band.length(), 1)).equals("S")){
holder.imageView.setImageResource(R.drawable.science);
}
if(currenthomeworkdue.Band.substring(0, Math.min(currenthomeworkdue.Band.length(), 1)).equals("M")){
holder.imageView.setImageResource(R.drawable.mathematics);
}
if(currenthomeworkdue.Band.substring(0, Math.min(currenthomeworkdue.Band.length(), 1)).equals("H")){
holder.imageView.setImageResource(R.drawable.global_studies);
}
if(currenthomeworkdue.Band.substring(0, Math.min(currenthomeworkdue.Band.length(), 2)).equals("FS")){
holder.imageView.setImageResource(R.drawable.spanish);
}
if(currenthomeworkdue.Band.substring(0, Math.min(currenthomeworkdue.Band.length(), 1)).equals("E")){
holder.imageView.setImageResource(R.drawable.english);
}
holder.HomeworkDueText.setText(currenthomeworkdue.getTitle().trim());
holder.DescriptionText.setText(Description);
holder.DescriptionText.setEllipsize(TruncateAt.END);
holder.TeacherText.setText(Teacher.trim());
holder.TypeText.setText(currenthomeworkdue.getType().trim());
return convertView;
} else {
View empty = getActivity().getLayoutInflater().inflate(R.layout.empty_item, parent, false);
return empty;
}
}
Also here is the Asynctask used to update the ListView, the notifyDataSetChanged is at the end of the AsyncTask, in the Post Execute.
public class Update extends AsyncTask<String, Void, Void> {
private final HttpClient Client = new DefaultHttpClient();
@Override
protected Void doInBackground(String... urls) {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://www.beaconschool.org/~markovic/lincoln.php");
HttpResponse response = httpClient.execute(httpGet, localContext);
String result = "";
try {
Log.d("receiver", "animation stopped and downloaded file");
String duetoday_html = new Scanner(response.getEntity().getContent(), "UTF-8" ).useDelimiter("\\A").next();
String duetoday = Html.fromHtml(duetoday_html).toString();
SharedPreferences.Editor localEditor = getActivity().getSharedPreferences("due_today", Context.MODE_PRIVATE ).edit();
localEditor.putString("duetoday_content", duetoday);
localEditor.apply();
Log.d("receiver", "information given to shared preferences");
parse_due_today_string();
parse_due_today_content();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (ClientProtocolException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
}
return null;
}
@Override
protected void onPostExecute(Void result) {
swipeLayout.setRefreshing(false);
adapter.notifyDataSetChanged();
Toast.makeText(getActivity(),"Refresh Finished",4000).show();
}
}
And here's the full code for the fragment http://pastebin.com/4cVvJ6QG
You didn't post exactly which line crashes, but based on your implementation of getView, it's a good bet at some point in your code the else case that returns the generic view with no holder applied is being hit:
View empty = getActivity().getLayoutInflater().inflate(R.layout.empty_item, parent, false);
return empty;
In this block, there's no ViewHolder, so if this view gets recycled (it will at some point), the code above that pulls the holder out:
else {
holder = (ViewHolder) convertView.getTag();
}
will cause holder to be null.
Usually I try to solve getView by returning the same view for all views (if possible) and just showing and hiding subviews based on the data.
if(convertView==null){
convertView = getActivity().getLayoutInflater().inflate(R.layout.item_view, parent, false);
holder = new ViewHolder();
holder.imageView = (ImageView)convertView.findViewById(R.id.item_iconclass);
holder.HomeworkDueText = (TextView) convertView.findViewById(R.id.item_texthomeworkdue);
holder.DescriptionText = (TextView) convertView.findViewById(R.id.item_textdescription);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
And then
if (data == null) {
//hide your views here, or show some generic "empty" text
holder.DescriptionText.setVisibilty(View.GONE);
}