Question

I have an EditText and Checkbox inside the ListView of 20 rows. EditText is hidden for first 7 rows and then Visible for all other rows. CheckBox is Visible for first 7 rows and then Hidden for other rows. onItemClick I have given the toast to get text of the Edittext which works fine for starting 10 rows but not for the last rows which comes on the scrolling.The App gets crash giving the NullPointerException Error

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



    View vi=convertView;
    ViewHolder holder;

    if(convertView==null){ 

        /********** Inflate tabitem.xml file for each row ( Defined below ) ************/
        vi = inflater.inflate(R.layout.tabitem, null); 

        /******** View Holder Object to contain tabitem.xml file elements ************/
        holder=new ViewHolder();
        holder.text=(TextView)vi.findViewById(R.id.textView1);

        holder.check =(CheckBox)vi.findViewById(R.id.checkBox1);
         holder.text2=(EditText)vi.findViewById(R.id.editText1);

       /************  Set holder with LayoutInflater ************/
        vi.setTag(holder);


        j++;

        if(j<8){
       holder.text2.setVisibility(View.INVISIBLE);
       holder.check.setX(-150);
        }else
        {
             holder.check.setVisibility(View.INVISIBLE);
        }



    }
    else  
        holder=(ViewHolder)vi.getTag();

    holder.text2.getText();
       if(data.size()<=0)
    {
        holder.text.setText("No Data");

        holder.text2.getText();
 //        Log.v("BBBB",  holder.text2.getText().toString());

    }
    else
    {
        /***** Get each Model object from Arraylist ********/
        tempValues=null;
        tempValues = (ListModel) data.get(position);

        /************  Set Model values in Holder elements ***********/
         holder.text.setText(tempValues.getCompanyName());

         holder.text2.getText();
                         /******** Set Item Click Listner for LayoutInflater for each row ***********/
         vi.setOnClickListener(new OnItemClickListener(position));
    }

    Log.v("DDD",  holder.text2.getText().toString());
    return vi;
}

and

 @Override
public int getViewTypeCount() {
    return getCount();
}


 @Override
public int getItemViewType(int position) {
   return position; 
}

But the app crash onITemClick method...Even EditText text gets the cause of error..

  public void onItemClick(int mPosition)
{


     View vListSortOrder;
     vListSortOrder=list.getChildAt(mPosition);     
     Log.d("valueeeeeeee", Integer.toString(mPosition));

     EditText edit=(EditText)vListSortOrder.findViewById(R.id.editText1);
   String temp=edit.getText().toString();
}


public void onClick(View arg0) { 
CustomListViewAndroidExample sct = (CustomListViewAndroidExample)activity; sct.onItemClick(mPosition); }

The above onItemClick works fine for starting 10 rows .. but on 11th row it gets crash on EditText edit line with null pointer exception error

logcat

04-28 00:46:29.101: W/dalvikvm(2178): threadid=1: thread exiting with uncaught exception (group=0x41465700)
04-28 00:46:29.161: E/AndroidRuntime(2178): FATAL EXCEPTION: main
04-28 00:46:29.161: E/AndroidRuntime(2178): java.lang.NullPointerException
04-28 00:46:29.161: E/AndroidRuntime(2178):     at com.androidexample.customlistview.CustomListViewAndroidExample.onItemClick(CustomListViewAndroidExample.java:172)
04-28 00:46:29.161: E/AndroidRuntime(2178):     at com.androidexample.customlistview.CustomAdapter$OnItemClickListener.onClick(CustomAdapter.java:222)

complete adapter code

 @SuppressLint("NewApi") public class CustomAdapter extends BaseAdapter   implements OnClickListener {

/*********** Declare Used Variables *********/
 private Activity activity;
 private ArrayList data;
 private static LayoutInflater inflater=null;
 public Resources res;
 ListModel tempValues=null;
 int i=0;

int j=0;

public ArrayList<String> selectedStrings = new ArrayList<String>();


/*************  CustomAdapter Constructor *****************/
public CustomAdapter(Activity a, ArrayList d,Resources resLocal) {

    /********** Take passed values **********/
    activity = a;
    data=d;
    res = resLocal;

    /***********  Layout inflator to call external xml layout () **********************/
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

}

/******** What is the size of Passed Arraylist Size ************/
public int getCount() {

    if(data.size()<=0)
        return 1;
    return data.size();
}

public Object getItem(int position) {
    return data.get(position);
}

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

/********* Create a holder to contain inflated xml file elements ***********/
public static class ViewHolder{

    public TextView text;
    public TextView text1;
    public EditText text2;
    public TextView textWide;
    public ImageView image;
    public CheckBox check;

}

/*********** Depends upon data size called for each row , Create each ListView row ***********/
public View getView(int position, View convertView, ViewGroup parent) {



    View vi=convertView;
    final ViewHolder holder;

    if(convertView==null){ 

        /********** Inflate tabitem.xml file for each row ( Defined below ) ************/
        vi = inflater.inflate(R.layout.tabitem, null); 

        /******** View Holder Object to contain tabitem.xml file elements ************/
        holder=new ViewHolder();
        holder.text=(TextView)vi.findViewById(R.id.textView1);

        holder.check =(CheckBox)vi.findViewById(R.id.checkBox1);
                holder.text2=(EditText)vi.findViewById(R.id.editText1);



       holder.check.setOnClickListener(new OnClickListener(){

           @Override
             public void onClick(View v) 
             {
                 if (((CheckBox) v).isChecked()) 
                 {
                     holder.text2.setText("Checked");


                 }
                 else
                 {
                     holder.text2.setText("Not Checked");

                 }
             }
        });



       /************  Set holder with LayoutInflater ************/
        vi.setTag(holder);



        j++;

        if(j<8){
       holder.text2.setVisibility(View.INVISIBLE);
       holder.check.setX(-150);
       holder.check.setVisibility(View.VISIBLE);

        }else
        {
             holder.check.setVisibility(View.INVISIBLE);
             holder.text2.setVisibility(View.VISIBLE);

        }



    }
    else  
        holder=(ViewHolder)vi.getTag();

    holder.text2.getText();
      if(data.size()<=0)
    {
        holder.text.setText("No Data");

        holder.text2.getText();

    }
    else
    {
        /***** Get each Model object from Arraylist ********/
        tempValues=null;
        tempValues = (ListModel) data.get(position);

        /************  Set Model values in Holder elements ***********/
         holder.text.setText(tempValues.getCompanyName());

         /******** Set Item Click Listner for LayoutInflater for each row ***********/
         vi.setOnClickListener(new OnItemClickListener(position));
    }



    return vi;
}

@Override
public int getViewTypeCount() {
    return getCount();
}


@Override
public int getItemViewType(int position) {
   return position; 
}


@Override
public void onClick(View v) {
        Log.v("CustomAdapter", "=====Row button clicked");
}

/********* Called when Item click in ListView ************/
private class OnItemClickListener  implements OnClickListener{           
    private int mPosition;

    OnItemClickListener(int position){
         mPosition = position;
    }

    @Override
    public void onClick(View arg0) {
        CustomListViewAndroidExample sct = (CustomListViewAndroidExample)activity;
        sct.onItemClick(mPosition);
    }               
}   

}

04-28 03:33:23.542: E/AndroidRuntime(4917): FATAL EXCEPTION: main
04-28 03:33:23.542: E/AndroidRuntime(4917): java.lang.NullPointerException
04-28 03:33:23.542: E/AndroidRuntime(4917):     at com.androidexample.customlistview.CustomListViewAndroidExample$1.onClick(CustomListViewAndroidExample.java:89)
04-28 03:33:23.542: E/AndroidRuntime(4917):     at android.view.View.performClick(View.java:4240)
04-28 03:33:23.542: E/AndroidRuntime(4917):     at android.view.View$PerformClick.run(View.java:17721)
04-28 03:33:23.542: E/AndroidRuntime(4917):     at android.os.Handler.handleCallback(Handler.java:730)
Was it helpful?

Solution

you have write confusing code.

you insert tag to text2 on:

holder.text2.setTag(1);

then next line of that use:

int position12 = (Integer)holder.text2.getTag();

so every time position12 is equal to 1.

next thing is using of jinstead of position.

you need change back your visibility too like following code because ListView's recycling

if(j<8){

     holder.text2.setVisibility(View.INVISIBLE);
     holder.check.setVisibility(View.VISIBLE);
     holder.check.setX(-150);

 }else{
     holder.text2.setVisibility(View.VISIBLE);
     holder.check.setVisibility(View.INVISIBLE);
  }

and as you have one layout why you Override getViewTypeCount and getItemViewType?

please remove following line from getView method,

 holder.text2.getText();

and

 Log.v("DDD",  holder.text2.getText().toString());

Your Problem

your problem is on:

private class OnItemClickListener  implements OnClickListener{           
    private int mPosition;

    OnItemClickListener(int position){
         mPosition = position;
    }

    @Override
    public void onClick(View arg0) {
        CustomListViewAndroidExample sct = (CustomListViewAndroidExample)activity;
        sct.onItemClick(mPosition);  <--- problem is here
    }               
}   

I don't know what you want exactly but you can do this.

1- change:

 vi.setOnClickListener(new OnItemClickListener(position));

to

 vi.setOnClickListener(this);

2- add following line to getView method:

  holder.text.setTag(position);

3- add following code to onClick method:

@Override
public void onClick(View v) {
       TextView tv = (TextView)v.findViewById(R.id.textView1);
       int pos = (Integer)tv.getTag();
       Log.d("position of clicked item is", ""+pos);
}

4- change

if(j<8)

to

if( position <8)

OTHER TIPS

1. Always remember to override these three methods when extending BaseAdapter:

@Override
public int getCount() {
    return your_objects_list.size();
}

@Override
public YourObjectType getItem(int position) {

    return your_objects_list.get(position);
}

@Override
public long getItemId(int position) {
// you could return any id related to your context, i just return 0 because I don't need it

    return 0;
}

2. Get rid of these methods:

You definitely do not need these:


 @Override
public int getViewTypeCount() {
    return getCount();
}


 @Override
public int getItemViewType(int position) {
   return position; 
}

Look, let me explain when you should be using these methods:

getViewTypeCount:

This method should return the number of different XML layout files you are using. For example if you are using row_layout_1.xml and row_layout_2.xml files for your rows, your getViewTypeCount() should always return 2.

So if you are using a single .XML file for all the rows, you really shouldn't override this method.

getItemViewType:

This method, when called on a single list item, should return the type. In the example I mentioned before, it should return 1 or 2, based on the position of the item.

Since you are using a single XML row type, you shouldn't override this method either.

Let me know your results.

3. Don't use j at all, use position instead.

move this code and place it one line before return vi;

    if(position <8){
   holder.text2.setVisibility(View.INVISIBLE);
   holder.check.setX(-150);
   holder.check.setVisibility(View.VISIBLE);

    }else
    {
         holder.check.setVisibility(View.INVISIBLE);
         holder.text2.setVisibility(View.VISIBLE);

    }

Let me know your results.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top