Reputation: 65
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
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
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
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
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