質問

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

   }
})
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top