NPE 自定义 ListView 适配器

Posted

技术标签:

【中文标题】NPE 自定义 ListView 适配器【英文标题】:NPE Custom ListView adapter 【发布时间】:2014-01-01 10:04:23 【问题描述】:

我的 ListViewAdapter 类中出现 NPE 错误。我制作了一个自定义 ListViewAdapter 但它不起作用。为什么?

这是代码和日志错误文件:

12-13 15:57:53.859: E/androidRuntime(22065): FATAL EXCEPTION: main
12-13 15:57:53.859: E/AndroidRuntime(22065): java.lang.NullPointerException
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.LayoutInflater.from(LayoutInflater.java:211)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.View.inflate(View.java:16803)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at com.prjma.lovertech.adapter.ListViewAdapter.getView(ListViewAdapter.java:60)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.widget.AbsListView.obtainView(AbsListView.java:2177)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.widget.ListView.measureHeightOfChildren(ListView.java:1247)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.widget.ListView.onMeasure(ListView.java:1159)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.View.measure(View.java:15848)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1404)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.View.measure(View.java:15848)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.View.measure(View.java:15848)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:651)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.View.measure(View.java:15848)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.View.measure(View.java:15848)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at com.android.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:302)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.View.measure(View.java:15848)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5008)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2189)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.View.measure(View.java:15848)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1905)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1104)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1284)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.Choreographer.doCallbacks(Choreographer.java:562)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.Choreographer.doFrame(Choreographer.java:532)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.os.Handler.handleCallback(Handler.java:730)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.os.Handler.dispatchMessage(Handler.java:92)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.os.Looper.loop(Looper.java:137)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at android.app.ActivityThread.main(ActivityThread.java:5103)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at java.lang.reflect.Method.invokeNative(Native Method)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at java.lang.reflect.Method.invoke(Method.java:525)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-13 15:57:53.859: E/AndroidRuntime(22065):    at dalvik.system.NativeStart.main(Native Method)

ListViewAdaptr 类:

package com.prjma.lovertech.adapter;

import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.prjma.lovertech.R;
import com.prjma.lovertech.model.Item;

public class ListViewAdapter extends ArrayAdapter<String>  

    private static LayoutInflater inflater = null;

    public Context context; 
    public int layoutResourceId;
    public ArrayList<HashMap<String, String>> items;

    //public ImageLoader imageLoader;


    public ListViewAdapter(Context context, int layoutResourceId) 
        super(context, layoutResourceId);
        // TODO Auto-generated constructor stub
        Log.i("ListViewAdapter", "1");
    

    public ListViewAdapter(Context context, int listviewItemRow, ArrayList<HashMap<String, String>> items) 
        // TODO Auto-generated constructor stub
        super(context, listviewItemRow);
        this.items = items;
        Log.i("ListViewAdapter constructor Context ", "Context1");
    

    public int getCount() 
        return items.size();
    

    public Item getItem(Item position) 
        return position;
    

    public long getItemId(int position) 
        return position;
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        View row = convertView;
        Log.i("getView", "getView");

        if (row == null) 

            inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.listview_item_row, null);
        

        Log.i("1", Boolean.toString(items.isEmpty()));

        HashMap<String, String> p = items.get(position);

        if (p != null) 

            //ImageView listImage = (ImageView)row.findViewById(R.id.list_image);
            TextView scadenza = (TextView)row.findViewById(R.id.tvScadenza);
            TextView prezzo = (TextView)row.findViewById(R.id.tvPrezzo);
            TextView followers = (TextView)row.findViewById(R.id.tvFollowers);

            /*
            if (listImage != null) 
                listImage.animate();
            
            */
            if (scadenza != null) 
                scadenza.setText(p.get("scadenza"));
            
            if (prezzo != null) 
                prezzo.setText(p.get("prezzo"));
            
            if (followers != null) 
                followers.setText(p.get("followers"));
            
        
        return row;
    

片段类:

package com.prjma.lovertech.fragment;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Fragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import com.prjma.lovertech.R;
import com.prjma.lovertech.adapter.ListViewAdapter;
import com.prjma.lovertech.util.JSONParser;


public class VendiFragment extends Fragment 


    public ListView listView;
    public ListViewAdapter adapter;

    /**
     * Keep track of the login task to ensure we can cancel it if requested.
     */
    private DownloadTask mDownloadTask = null;

    public ArrayList<HashMap<String, String>> items;

    private static String URL = ".......";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 

        View rootView = inflater.inflate(R.layout.fragment_vendi, container, false); 

        // now you must initialize your list view
        listView = (ListView) rootView.findViewById(R.id.listViewVendi);

        items = new ArrayList<HashMap<String, String>>();

        mDownloadTask = new DownloadTask();
        mDownloadTask.execute((Void) null);     

        return rootView;
    


    /**
     * Represents an asynchronous login/registration task used to authenticate
     * the user.
     */
    public class DownloadTask extends AsyncTask<Void, Void, Boolean> 
        @Override
        protected Boolean doInBackground(Void... params) 
            // TODO: attempt authentication against a network service.

            //prendi tutti gli id dal webserver
            ArrayList<Long> ids = search();
            //per ogni id prendi l'elemento
            for(int i=0; i < ids.size() - 1; i++)
                getItem(ids.get(i));
            

            return true;
        

        @Override
        protected void onPostExecute(final Boolean success) 
            mDownloadTask = null;

            // dismiss the dialog after getting all products
            //showProgress(false);

            // updating UI from Background Thread
            getActivity().runOnUiThread(new Runnable() 
                public void run() 
                     //Updating parsed JSON data into ListView

                    Log.i("onPostExecute items size", Integer.toString(items.size()));
                    ListViewAdapter adapter = new ListViewAdapter(getActivity(),R.layout.listview_item_row, items);
                    // updating listview
                    //adapter.notifyDataSetChanged();
                    listView.setAdapter(adapter);
                
            );

        

        @Override
        protected void onCancelled() 
            mDownloadTask = null;
            //showProgress(false);
        

        public ArrayList<Long> search()
            // Building Parameters for search
            List<NameValuePair> parameters = new ArrayList<NameValuePair>();
            parameters.add(new BasicNameValuePair("secret", "......"));
            parameters.add(new BasicNameValuePair("category", ""));
            parameters.add(new BasicNameValuePair("latitude", ""));
            parameters.add(new BasicNameValuePair("longitude", ""));
            parameters.add(new BasicNameValuePair("radius", ""));
            parameters.add(new BasicNameValuePair("keywords", ""));
            parameters.add(new BasicNameValuePair("order", ""));
            parameters.add(new BasicNameValuePair("state", "2"));

            JSONObject obj = JSONParser.getJSONFromUrl(URL + "search", parameters);

            ArrayList<Long> ids = new ArrayList<Long>();

            // check for service response
            try 
                String firstItem = obj.getString("items");
                String[] values = firstItem.split("\\|");

                ArrayList<Long> longs = new ArrayList<Long>();

                for(int i=0; i < values.length; i++)
                    longs.add(Long.parseLong(values[i]));
                

                String status = obj.getString("status");
                Log.i("status", status);
                if (status.equals("0"))
                    for (int i = 0; i < longs.size() - 1; i++) 
                        if (i == 0) 
                            ids.add(longs.get(i));
                        
                        ids.add(longs.get(0) - longs.get(i + 1));
                    

                 else 
                     Log.e("error in search", "status = " + status);
                               
             catch (JSONException e) 
                e.printStackTrace();
            
            return ids;
        


        public void getItem(long ids)
            // Building Parameters for search
            Log.i("itemid", Long.toString(ids));
            List<NameValuePair> parameters = new ArrayList<NameValuePair>();
            parameters.add(new BasicNameValuePair("secret", "......"));
            parameters.add(new BasicNameValuePair("itemid", Long.toString(ids)));
            parameters.add(new BasicNameValuePair("details", "4"));

            JSONObject obj = JSONParser.getJSONFromUrl(URL + "getitem", parameters);

            // check for service response
            try 
                String status = obj.getString("status");
                Log.i("status", status);
                if (status.equals("0"))
                    String price = obj.getString("price");

                    // creating new HashMap
                    HashMap<String, String> map = new HashMap<String, String>();

                    // adding each child node to HashMap key => value
                    map.put("scadenza", obj.getString("sec2end"));
                    map.put("prezzo", obj.getString("price"));
                    map.put("followers", obj.getString("pop"));

                    // adding HashList to ArrayList
                    items.add(map);

                    Log.i("price", price);
                 else 
                    Log.e("error in getItem", "status = " + status);
                               
             catch (JSONException e) 
                e.printStackTrace();
            
        
    

【问题讨论】:

【参考方案1】:

您没有在构造函数中设置上下文。

将此添加到您的 ListViewAdapter 构造函数中。

this.context=context;

【讨论】:

【参考方案2】:

这似乎是其中之一:

    inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    row = inflater.inflate(R.layout.listview_item_row, null);

我没有看到 context var 的任何初始化?应该是这样的

【讨论】:

以上是关于NPE 自定义 ListView 适配器的主要内容,如果未能解决你的问题,请参考以下文章

使用自定义(对象)适配器过滤 ListView

ListView 的自定义适配器忽略设置值

具有包含 CheckBoxes 的自定义适配器的 Listview

滚动时 ListView 自定义适配器错误

Listview、自定义适配器和复选框

自定义 ListView 适配器中的 ImageButton