简体   繁体   中英

onItemClick of items in ListView after Scrolling throws NullPointerException

I have developed an activity that displays all the Contacts of Android phone and I am using a ListView to display the retrieved contacts. The problem is till the time I don't scroll my ListView, whenever I click on any list item - it is displaying that particular contact record details. But, when I scroll and click on any item in the list the application is crashing and throwing a NullPointerException. Can anyone guide me where am I going wrong and how to achieve my result. This may be a duplicate question, but I tried searching all over the net with no success. Below is the code snippet of my activity that displays contacts:

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.contact_manager);

    filterText = (EditText) findViewById(R.id.search_box);     
    filterText.addTextChangedListener(filterTextWatcher); 

    mContactList = (ListView) findViewById(R.id.contactList);
    populateContactList();      

}

private void populateContactList()
{
    // Another class used to retrieve contacts
              ContactAPI contactAPI = ContactAPI.getAPI();
    ContentResolver cr = getContentResolver();
    contactAPI.setCr(cr);

    ArrayList<Contact> a = new ArrayList<Contact>();
    a = contactAPI.newContactList(this).getContacts();

    contactsAL = new ArrayList<Contact>(a);     

    adapter = new CustomAdapter(this, R.layout.contact_entry, a);       

    mContactList.setAdapter(adapter);   

    mContactList.setOnItemClickListener(new OnItemClickListener(){
    public void onItemClick(AdapterView<?> parent, View view, int position, long id)
    {               

               ***// The below is the line where I am getting NullPointerException***
        LinearLayout l = (LinearLayout) parent.getChildAt(position);
        TextView tv = (TextView) l.getChildAt(1);

        Intent myIntent = new Intent(view.getContext(), ContactDetailsActivity.class);

        Bundle b = new Bundle();
        b.putString("ContactID", tv.getText().toString());
        myIntent.putExtras(b);

        startActivityForResult(myIntent, 0);
    }
    });



private TextWatcher filterTextWatcher = new TextWatcher() 
{      
    public void afterTextChanged(Editable s) 
    {     

    }      
    public void beforeTextChanged(CharSequence s, int start, int count, int after) 
    {     

    }      
    public void onTextChanged(CharSequence s, int start, int before, int count) 
    {         
        adapter.getFilter().filter(s);
    }  
};

protected void onDestroy() 
{     
    super.onDestroy();     
    filterText.removeTextChangedListener(filterTextWatcher); 
}   

And below is my custom Adapter class code snippet:

private ArrayList<Contact> original; 
private ArrayList<Contact> fitems;
private Filter filter;

private LayoutInflater mInflater;

public CustomAdapter(Context context, int layoutResourceId, ArrayList<Contact> data) 
{
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.original = new ArrayList<Contact>(data);         
    this.fitems = new ArrayList<Contact>(data);
}   

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) 
{       
    ViewHolder holder;

    if (convertView == null) 
    {
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);         
        convertView = mInflater.inflate(R.layout.contact_entry, null);
        holder = new ViewHolder();          
        holder.txtName = (TextView) convertView.findViewById(R.id.contactEntryText);
        holder.txtID = (TextView) convertView.findViewById(R.id.contactID);

        convertView.setTag(holder);         
    } 
    else 
    {           
        holder = (ViewHolder) convertView.getTag();         
    }

    if(fitems != null)
    {
        Contact ct = fitems.get(position);
        if(ct != null)
        {
            holder.txtName.setText((String)ct.getDisplayName());
            holder.txtID.setText((String)ct.getId());
        }
    }

    //this.notifyDataSetChanged();

    return convertView;
}

@Override
public Filter getFilter() {
    // TODO Auto-generated method stub
    // return super.getFilter();

    if (filter == null)         
        filter = new ContactFilter();      

    return filter;
}


private class ContactFilter extends Filter 
{ 
    @Override 
    protected FilterResults performFiltering(CharSequence constraint) 
    { 
        FilterResults results = new FilterResults(); 
        String prefix = constraint.toString().toLowerCase(); 

        if (prefix == null || prefix.length() == 0) 
        { 
            ArrayList<Contact> list = new ArrayList<Contact>(original); 
            results.values = list; 
            results.count = list.size(); 
        } 
        else 
        { 
            final ArrayList<Contact> list = new ArrayList<Contact>(original); 
            final ArrayList<Contact> nlist = new ArrayList<Contact>(); 
            int count = list.size(); 

            for (int i=0; i<count; i++) 
            { 
                final Contact cont = list.get(i); 
                final String value = cont.getDisplayName().toLowerCase(); 

                if (value.contains(prefix)) 
                { 
                    nlist.add(cont); 
                } 
            } 
            results.values = nlist; 
            results.count = nlist.size(); 
        } 
        return results; 
    } 

    @SuppressWarnings("unchecked") 
    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) 
    { 
        fitems = (ArrayList<Contact>)results.values; 

        clear(); 
        int count = fitems.size(); 
        for (int i=0; i<count; i++) 
        { 
            Contact cont = (Contact)fitems.get(i); 
            add(cont); 
        } 
    } 
}

static class ViewHolder {
    TextView txtName;
    TextView txtID;
}

Can anyone please suggest me where am I doing wrong?

int the onItemClick call CustomAdapter. getItem(int) to retrive the Contact object at position, a use contact to retrive the information you need to start the new activity.

remove setting onitemclicklistener in your main activity.

In CustomAdapter, inside getView method you just add clicklistener to textview

holder.txtName.setOnclickListener(new OnClickListener() {

   @Override
  public void onClick() {
  Intent myIntent = new Intent(view.getContext(), ContactDetailsActivity.class);

    Bundle b = new Bundle();
    b.putString("ContactID", holder.txtName.getText().toString());
    myIntent.putExtras(b);

    startActivityForResult(myIntent, 0);

   }
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM