ShrimpCrackers
ShrimpCrackers

Reputation: 4532

Android Listview Position is 0 on item selection

I have a custom adapter for my list view (extends ArrayAdapter). The list loads fine. However, when I click on an item in my list, i.e. the 5th item in the list, the position in getView is always 0 instead of 5. It crashes because convertView is no longer null If it is 0, the headervariable should be initialized to the R.id.listHeaderTv TextView, but it can't find it and ends up being null.

How do I fix the position problem and convertView not being null anymore?

EDIT: After checking onItemClick method, the position is correct. The only problem then is that after the onItemClick method, getView is being called and crashes there because the view is not being inflated.

LOGCAT:

02-27 16:35:25.280: E/AndroidRuntime(6330): FATAL EXCEPTION: main
02-27 16:35:25.280: E/AndroidRuntime(6330): java.lang.NullPointerException
02-27 16:35:25.280: E/AndroidRuntime(6330):     at moflow.adapters.CatalogListAdapter.getView(CatalogListAdapter.java:66)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.widget.AbsListView.obtainView(AbsListView.java:1294)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.widget.ListView.makeAndAddView(ListView.java:1727)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.widget.ListView.fillSpecific(ListView.java:1272)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.widget.ListView.layoutChildren(ListView.java:1558)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.widget.AbsListView.onLayout(AbsListView.java:1147)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.view.View.layout(View.java:7035)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.widget.RelativeLayout.onLayout(RelativeLayout.java:909)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.view.View.layout(View.java:7035)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.view.View.layout(View.java:7035)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.widget.FrameLayout.onLayout(FrameLayout.java:333)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.view.View.layout(View.java:7035)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1045)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.os.Looper.loop(Looper.java:123)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at android.app.ActivityThread.main(ActivityThread.java:4627)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at java.lang.reflect.Method.invokeNative(Native Method)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at java.lang.reflect.Method.invoke(Method.java:521)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-27 16:35:25.280: E/AndroidRuntime(6330):     at dalvik.system.NativeStart.main(Native Method)

Adapter:

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

    @Override
            public View getView( int position, View convertView, ViewGroup parent ) {
                View v = convertView;
                CatalogItem item = getItem( position );

                if ( v == null ) {
                    LayoutInflater inflater = ( LayoutInflater ) mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE );

                    if ( item.header )
                        v = inflater.inflate( R.layout.sec_header, null );
                    else
                        v = inflater.inflate( R.layout.sec_item, null );
                }

                if ( item.header ) {
                    TextView header = ( TextView ) v.findViewById( R.id.listHeaderTV );
                    header.setText( item.name );
                    header.setEnabled( false );
                } else {
                    TextView sectionItem = ( TextView ) v.findViewById( R.id.listCreatureNameTV );
                    sectionItem.setText( item.name );
                }

                return v;
            }

Upvotes: 2

Views: 4712

Answers (2)

ShrimpCrackers
ShrimpCrackers

Reputation: 4532

Hm, don't know where Sam's answer went but he was correct about overriding those two methods getItemViewType() and getViewTypeCount(). I also got help from this page: http://androidtrainningcenter.blogspot.com/2012/03/android-listview-with-section-header.html

Here's the code that ended up working for me:

public View getView( int position, View convertView, ViewGroup parent ) {
        ViewHolder holder = null;
        int type = getItemViewType( position );

        if ( convertView == null ) {
            holder = new ViewHolder();
            switch( type ) {
                case TYPE_ITEM:
                    convertView = inflater.inflate( R.layout.sec_item, null );
                    holder.tv = ( TextView ) convertView.findViewById( R.id.listCreatureNameTV );
                    break;
                case TYPE_SEPARATOR:
                    convertView = inflater.inflate( R.layout.sec_header, null );
                    holder.tv = ( TextView ) convertView.findViewById( R.id.listHeaderTV );
                    break;
            }
            convertView.setTag( holder );
        } else {
            holder = ( ViewHolder ) convertView.getTag();
        }

        CatalogItem item = getItem( position );
        holder.tv.setText( item.name );

        return convertView;
    }

    public static class ViewHolder {
        public TextView tv;
    }

Upvotes: 1

323go
323go

Reputation: 14274

getView() is supposed to produce the view to be displayed. To get the click events, you'll want set on OnItemClickListener such as this:

new OnItemClickListener() {
    // @Override
     public void onItemClick(AdapterView<?> a, View v, int position, long id) {
         Toast.makeText(ListRecords.this,"Clicked item: " + position, Toast.LENGTH_LONG).show();
     }
     });

... and ignore convertView for the time being.

Upvotes: 2

Related Questions