snoopaki
snoopaki

Reputation: 65

Android, Null Pointer Exception on ListView test code

I am building an app that uses ListView and a custom adapter extending BaseAdapter to handle the data to the ListView. The code is as follows:

newlist.java compiles/runs fine

public class newslist extends Activity {

    public static final String tag = "newslist";
    ListView listNews;
    MyListAdapter listAdapter;


    /** Set or Grab the URL */        
    public static final String parseURL = "http://www.example.com.gr/article.php";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.newslist);

        /** Array Lists */
        ArrayList<String> titles = new ArrayList<String>();
        ArrayList<String> links = new ArrayList<String>();
        ArrayList<String> dates = new ArrayList<String>();

        Log.d(newslist.tag, "****** parseURL = " + parseURL);

        listNews = (ListView) findViewById(R.id.listNews);

        try {                  
            /** Open URL with Jsoup */
            Document doc = Jsoup.connect(parseURL).get();

            /** Grab classes we want */                   
            Elements pcontent = doc.getElementsByClass("content_title");
            Elements pdates = doc.getElementsByClass("content_datecreated_left");

            /** Loop for grabbing TITLES within parent element */
            for (Element ptitles : pcontent) {

                /** Grab Anchors */
                Elements ptitle = ptitles.getElementsByTag("a");
                for (Element title : ptitle) {
                  titles.add(title.text());
                }
            }

            /** Loop for grabbing LINKS within parent element */
            for (Element plinks : pcontent) {
                /** Grab anchors */
                Elements plink = plinks.getElementsByTag("a");
                for (Element link : plink) {                    
                  links.add(link.attr("abs:href")); /** parse absolute address */    
                }
            }

            /** Loop for grabbing DATES within parent element */
            for (Element pdate : pdates) {
                dates.add(pdate.text()) ;
            }

            //TODO: Regex on Date

            //String content: Main Activity Content

            int i=0;
            int num = titles.size();
            String[] printDates = new String[num];
            for (i=0; i < num; i++)
            {
                //substring(25) leaves a space after the date, eg "26/6/2011 "
                //content[i] = titles.get(i) + "\n Date: " + dates.get(i).substring(25);
                printDates[i] = dates.get(i).substring(25);
            }

            /** Create an ArrayAdapter, that will actually make the Strings above 
             * appear in the ListView */ 
            listAdapter = new MyListAdapter(this, titles, dates);
            listNews.setAdapter(listAdapter);

        } catch (Exception e) {
            Log.e(newslist.tag, "****** Failed to Parse URL:" + e.getMessage());
            e.printStackTrace();
        } 

    } /*- OnCreate End -*/

} /*- Class End -*/

MyListAdapter.java runs a NPE at line 75:

public class MyListAdapter extends BaseAdapter {

    public final static String tag = "MyListAdapter";
    public Context context;
    public ArrayList<String> title;
    public ArrayList<String> date;
    public LayoutInflater inflater;

    public MyListAdapter(Activity context, ArrayList<String> title, ArrayList<String> date) {
        super();
        this.context = context;
        this.title = title;
        this.date = date;

        this.inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public int getCount() {
        // Auto-generated method stub
        return this.title.size();
    }

    public Object getItem(int position) {
        //Auto-generated method stub
        return this.title.get(position);
    }

    public long getItemId(int position) {
        // Auto-generated method stub
        return position;
    }

    private static class ViewHolder {
        TextView titleView;
        TextView dateView;
    }

    public View getView(int position, View convertView, ViewGroup parent)
    {
        // Auto-generated method stub
        ViewHolder holder;

        Log.d(tag, "****** convertView: " + convertView);

        if (convertView == null)
        {
            convertView = inflater.inflate(R.layout.listrow, null);
            holder = new ViewHolder();
            holder.titleView = (TextView) convertView.findViewById(R.id.listTitle);
            holder.dateView = (TextView) convertView.findViewById(R.id.listDate);
            convertView.setTag(holder);
        }
        else
        {
            holder = (ViewHolder) convertView.getTag();
        }
        Log.d(tag, "****** Title: " + title.get(position));
        Log.d(tag, "****** findViewById: " + convertView.findViewById(R.id.listTitle));
        Log.d(tag, "****** holder.titleView: " + holder.titleView);


        holder.titleView.setText(title.get(position));
        holder.dateView.setText(date.get(position));

        //notifyDataSetChanged();

        return convertView;
    }

}

Line 75 is:

holder.titleView.setText(title.get(position));

However I have tracked the problem to line 62:

holder.titleView = (TextView) convertView.findViewById(R.id.listTitle);

where it seems from my debugging messages that holder.titleView is null

I have tried cleaning/erasing bin folder and rebuilding the project to no avail. I think the problem lies in the View R.id.listTitle not being found. But i have no idea why.

I will also include my two xml files for previewing

newslist.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
<TextView  
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/title"
    android:gravity="center|top"
    android:textSize="20dip"
    android:textStyle="bold"
    android:text="@string/titleNewslist"
    />
<ListView  
    android:id="@+id/listNews"
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    >
</ListView>
</LinearLayout>

listrow.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:name="@+id/listTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="top|left"
        android:textSize="18dip"
        android:textStyle="bold"
        android:text="TextView">
    </TextView>  
    <TextView
        android:name="@+id/listDate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="bottom|right"
        android:textSize="12dip"
        android:textStyle="bold"
        android:textColor="@android:color/white"
        android:text="TextView">
    </TextView>
</LinearLayout>

Upvotes: 1

Views: 1598

Answers (4)

Pratik
Pratik

Reputation: 30855

you are passing the Activity context into the MyListAdapter constructor and assign to the Context object.

change the Activity to Context in constructor and then try it

Upvotes: 0

Zwiebel
Zwiebel

Reputation: 1615

NullPointerException usually comes, when you have some problems with your XML files. Try to not end your

<TextView
    android:name="@+id/listTitle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="top|left"
    android:textSize="18dip"
    android:textStyle="bold"
    android:text="TextView">
</TextView>  

with > and instead of > and

I'm not sure that it's the source of your problem, but it can happen.

Hope it helps.

Upvotes: 0

Snicolas
Snicolas

Reputation: 38168

I don't really understand the use of ViewHolder.

You should do :

convertView = new YourViewClass();

in this class have 2 fields for both textviews and a onCreate that inflate listRow.xml and find both views by id.

but converview and view holder should not be different and you should not try to pass one view from one component to the other.

Regards, Stéphane

Upvotes: 0

Codeman
Codeman

Reputation: 12375

You never assign anything to titleView.

You need to do the following in your onCreate() after super.onCreate()

titleView = (TextView) this.getViewById(R.id.listTitle);

Make sure to declare titleView as a field at the top of your class so the rest of your class can access it, if you need to.

Hope this helps!

EDIT:

An important note I just noticed:

android:name="@+id/myName" 

is NOT the same as

android:id="@+id/myName"

You need to make sure you declare the ids, or you will not be able to access the layout elements.

Upvotes: 1

Related Questions