Android, исключение нулевого указателя в тестовом коде ListView - PullRequest
1 голос
/ 10 августа 2011

Я создаю приложение, которое использует ListView и пользовательский адаптер, расширяющий BaseAdapter для обработки данных в ListView. Код выглядит следующим образом:

newlist.java компилируется / работает нормально

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 запускает NPE в строке 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;
    }

}

Строка 75:

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

Однако я отследил проблему до строки 62:

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

где из моих сообщений отладки видно, что holder.titleView null

Я попытался очистить / стереть папку bin и пересобрать проект безрезультатно. Я думаю, что проблема заключается в том, что View R.id.listTitle не найден. Но я понятия не имею, почему.

Я также включу мои два xml-файла для предварительного просмотра

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>

Ответы [ 4 ]

1 голос
/ 10 августа 2011

Вы никогда не назначаете ничего для titleView.

Вам нужно сделать следующее в onCreate () после super.onCreate ()

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

Убедитесь, что titleView объявлено как полев верхней части вашего класса, чтобы остальные члены вашего класса могли получить к нему доступ, если вам нужно.

Надеюсь, это поможет!

РЕДАКТИРОВАТЬ:

Важное замечание, которое я простозаметил:

android:name="@+id/myName" 

- это НЕ то же самое, что

android:id="@+id/myName"

Вам необходимо убедиться, что вы объявили идентификаторы, иначе вы не сможете получить доступ к элементам макета.

0 голосов
/ 10 августа 2011

вы передаете контекст Activity в конструктор MyListAdapter и присваиваете объекту Context.

измените Activity на Context в конструкторе, а затем попробуйте

0 голосов
/ 10 августа 2011

NullPointerException обычно возникает, когда у вас есть проблемы с вашими XML-файлами.Постарайтесь не заканчивать

<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>  

символами> и вместо> и

Я не уверен, что это источник вашей проблемы, но это может произойти.

Надеюсьпомогает.

0 голосов
/ 10 августа 2011

Я не совсем понимаю использование ViewHolder.

Вы должны сделать:

convertView = new YourViewClass();

в этом классе есть 2 поля для обоих текстовых представлений и onCreate, которые раздувают listRow.xml.и найдите оба представления по id.

, но конверсия и держатель представления не должны различаться, и вам не следует пытаться передавать одно представление из одного компонента в другой.

С уважением, Стефан

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...