Autore Topic: BaseExpandableListAdapter e Null Pointer Exception in getChildrenCount()  (Letto 519 volte)

Offline fabgio75

  • Nuovo arrivato
  • *
  • Post: 1
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Sistema operativo:
    Windows 7
Salve,
Sia la minSdkVersion sia la TargetSdkVersion del progetto per la gestione di un impianto domotico sono settate alla 19 (Android 4.4.2).
ricevo una Null Pointer Exception relativa al metodo getChildrenCount su    una classe che estende  BaseExpandableListAdapter. :-(
MI spigo meglio. Sto implementando un fragment contenente una lista di oggetti children (Command)  raggruppati in  oggetti  parents (Group).

CommandFragment.java:

Codice (Java): [Seleziona]
public class CommandFragment extends Fragment {
       
        private Command mCommand;
       
        @Override
        public void onCreate(Bundle savedInstanceState){
                super.onCreate(savedInstanceState);
                mCommand=new Command();
                UUID commandId=(UUID)getArguments().getSerializable(EXTRA_COMMAND_ID);
                mCommand=Dashboard.get(getActivity()).getCommand(commandId);
        }
               
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
                View v=inflater.inflate(R.layout.fragment_command, parent, false);
                mCommandTitleEditText=(EditText)v.findViewById(R.id.command_title_edit_text);
                mCommandTitleEditText.setText(mCommand.getTitle());
                mCommandTitleEditText.addTextChangedListener(new TextWatcher(){

                        ...omissis....
                        }
                       
                        @Override
                        public void afterTextChanged(Editable s) {}
                });
               
                mWhoSpinner=(Spinner)v.findViewById(R.id.command_who_spinner);
                ArrayAdapter<CharSequence>mWhoAdapter=ArrayAdapter
                                .createFromResource(getActivity(), R.array.who_array, android.R.layout.simple_spinner_item);
                mWhoAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                mWhoSpinner.setAdapter(mWhoAdapter);
                mSharedPreferences=getActivity().getSharedPreferences(PREFS_NAME, getActivity().MODE_PRIVATE);
                mWhoSpinner.setSelection(mSharedPreferences.getInt(WHO_SPINNER_USER_CHOICE,0));
                mWhoSpinner.setOnItemSelectedListener(new OnItemSelectedListener(){

                        @Override
                        public void onItemSelected(AdapterView<?> parent, View view,
                                        int position, long id) {
                                mSharedPreferences=getActivity().getSharedPreferences(PREFS_NAME,getActivity().MODE_PRIVATE);
                                SharedPreferences.Editor editor=mSharedPreferences.edit();
                                editor.putInt(WHO_SPINNER_USER_CHOICE, mWhoSpinner.getSelectedItemPosition());
                                editor.commit();
                                Intent data=new Intent();
                                data.putExtra(EXTRA_WHO_SELECTED_ITEM_POSITION, mWhoSpinner.getSelectedItemPosition());
                                getActivity().setResult(Activity.RESULT_OK,data);
                                sWhoSelected=mWhoSpinner.getItemAtPosition(position).toString();
                                switch(sWhoSelected){
                                // check mCommand settings!  Check OK
                                case "Scenarios":
                                        mCommand.setWho(Command.sWhoChoices[0]);
                                        break;
                                case "Lighting":
                                        mCommand.setWho(Command.sWhoChoices[1]);
                                        break;
                                ... omissis....
                                }
                               
                        }
                        @Override
                        public void onNothingSelected(AdapterView<?> parent) {}
                });
       
                mWhereSpinner=(Spinner)v.findViewById(R.id.command_where_spinner);
                [i]...omissis...[/i]
                mWhereSpinner.setOnItemSelectedListener(new OnItemSelectedListener(){
                       
                        ...omissis....
}
                        @Override
                        public void onNothingSelected(AdapterView<?> parent) {}
                });
                return v;
        }
       
        public static CommandFragment newInstace(UUID commandId){
                Bundle args=new Bundle();
                args.putSerializable(EXTRA_COMMAND_ID,commandId);
                CommandFragment fragment=new CommandFragment();
                fragment.setArguments(args);
                return fragment;
        }
}
Group.java:
Codice (Java): [Seleziona]
public class Group {
        private String mTitle;
        private ArrayList<Command>mCommands;
       
        public String getTitle() {
                return mTitle;
        }
        public void setTitle(String title) {
                mTitle = title;
        }
        public ArrayList<Command> getCommands() {
                return mCommands;
        }
        public void setCommands(ArrayList<Command> commands) {
                mCommands = commands;
        }
       
        @Override
        public String toString(){
                return mTitle;
        }
}


Ecco la classe singleton che gestisce "il database" dei Command(s) e dei Group(s) (questi ultimi non ancora serializzati).

Dashboard.java:
Codice (Java): [Seleziona]
public class Dashboard {
        private static final String TAG = "Dashboard";
        private static final String mSerializeFileName = "commands.ser";
        private static Dashboard sDashboard;
        private Context mAppContext;
        Serializer mSerializer;
        ArrayList<Command> mCommands;
        ArrayList<Group>mGroups;
        int groupindex;
       
        private Dashboard(Context appContext) {
                mAppContext = appContext;
                mSerializer=new Serializer(mAppContext,mSerializeFileName);
                try{
                mCommands=mSerializer.loadCommands();
                Log.i(TAG, "commands loaded  ");
                }catch (Exception e){
                        mCommands=new ArrayList<>();
                        Log.i(TAG, "commands not  loaded  ");
                }
                mGroups=new ArrayList<>();
        }

        public static Dashboard get(Context c) {
                if (sDashboard == null)
                        sDashboard = new Dashboard(c.getApplicationContext());
                return sDashboard;
        }

        public ArrayList<Command> getCommands() {
                return mCommands;
        }
       
        public ArrayList<Group> getGroups() {
                return mGroups;
        }
       
        public Command getCommand(UUID id) {
                for (Command c : mCommands) {
                        if (c.getId().equals(id))
                                return c;
                }
                return null;
        }

        public void addCommand(Command c) {
                mCommands.add(c);
        }
        public void addGroup(Group g){
                if(!mGroups.contains(g))
                mGroups.add(g);
                groupindex=mGroups.indexOf(g);
        }

        public void saveCommands() {
                mSerializer.saveCommands(mCommands);
                Log.i(TAG, "Commands saved");
        }

di seguito il fragment per la gestione della lista che "poggia" su Dashboard.java.
CommandListFragment:

Codice (Java): [Seleziona]
public class CommandListFragment extends Fragment {
        private static final String TAG = "CommandListFragment";
        private ArrayList<Group> mGroups;
        private ArrayList<Command> mCommands;
        private ExpandableListAdapter mExpandableListAdapter;
        private ExpandableListView mExpandableListView;
        private int mWhoSelected;
        public static final int REQUEST_WHO_SELECTED_ITEM=0;
       
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setHasOptionsMenu(true);
                getActivity().setTitle(R.string.command_list_label);
                mGroups = Dashboard.get(getActivity()).getGroups();
                mCommands = Dashboard.get(getActivity()).getCommands();
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup parent,
                        Bundle savedIstanceState) {
                View v = inflater.inflate(R.layout.activity_fragment_expandable,
                                parent, false);
                mExpandableListView = (ExpandableListView) v.findViewById(R.id.ExpList);
                mExpandableListAdapter = new ExpandableListAdapter(getActivity(),
                                mGroups, mCommands);
                mExpandableListView.setAdapter(mExpandableListAdapter);
                Button mEmptyButton = (Button) v.findViewById(android.R.id.empty);
                mExpandableListView.setEmptyView(mEmptyButton);
                mEmptyButton.setOnClickListener(new View.OnClickListener() {

                        @Override
                        public void onClick(View v) {
                                newCommandSelected();
                        }
                });
                mExpandableListView.setOnChildClickListener(new OnChildClickListener() {

                        @Override
                        public boolean onChildClick(ExpandableListView parent, View v,
                                        int groupPosition, int childPosition, long id) {
                                Intent i = new Intent(getActivity(), CommandActivity.class);
                                i.putExtra(CommandFragment.EXTRA_COMMAND_ID,
                                                mExpandableListAdapter.c.getId());
                                startActivityForResult(i,REQUEST_WHO_SELECTED_ITEM);
                                return true;
                        }
                });
                return v;
        }

        @Override
        public void onResume() {
                super.onResume();
                mExpandableListAdapter.notifyDataSetChanged();
        }
       
        public void newCommandSelected() {
                Command command = new Command();
                Dashboard.get(getActivity()).addCommand(command);
                Intent i = new Intent(getActivity(), CommandActivity.class);
                i.putExtra(CommandFragment.EXTRA_COMMAND_ID, command.getId());
                startActivityForResult(i,REQUEST_WHO_SELECTED_ITEM);
        }
        public void newGroup(int whoselected){
                Group group = new Group();
                Dashboard.get(getActivity()).addGroup(group);
                String whoArray[]=getActivity().getResources().getStringArray(R.array.who_array);
                group.setTitle(whoArray[whoselected]);
                int index = mGroups.indexOf(group);
                mGroups.get(index).setCommands(group.getCommands());   
        }
       
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data){
                if (data==null) return;
                switch(requestCode){
                case REQUEST_WHO_SELECTED_ITEM:        
                        mWhoSelected=data.getIntExtra(CommandFragment.EXTRA_WHO_SELECTED_ITEM_POSITION,0);
                        newGroup(mWhoSelected);
                break;
        }
}
}
come si vede  group.setTitle()  assume il valore indicizzato di who_array.

ExpandableListAdapter.java:
Codice (Java): [Seleziona]
public class ExpandableListAdapter extends BaseExpandableListAdapter {
        private Context mContext;
        private ArrayList<Group>mGroups;
        private ArrayList <Command>mCommands;
        Command c;
        TextView ItemTitleTextView;

        ExpandableListAdapter(Context context, ArrayList<Group>groups, ArrayList<Command>commands){
                mContext=context;
                mGroups=groups;
                mCommands=commands;    
        }

        @Override
        public int getGroupCount() {
                return mGroups.size();
        }
        @Override
        public void onGroupCollapsed(int groupPosition){
                super.onGroupCollapsed(groupPosition);
        }
        @Override
        public void onGroupExpanded(int groupPosition){
                super.onGroupExpanded(groupPosition);
        }

        @Override
        public int getChildrenCount(int groupPosition) {
                return mGroups.get(groupPosition).getCommands().size(); //I have got a null pointer exception here
        }

        @Override
        public Object getGroup(int groupPosition) {
                return mGroups.get(groupPosition);
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
                return mGroups.get(groupPosition).getCommands().get(childPosition);
        }
        @Override
        public long getGroupId(int groupPosition) {
                return groupPosition;
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
                return childPosition;
        }

        @Override
        public boolean hasStableIds() {
                return false;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded,
                        View convertView, ViewGroup parent) {
                        Group g=(Group)getGroup(groupPosition);
                        LayoutInflater inflater=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                        convertView=inflater.inflate(R.layout.list_item_group,parent,false);
                TextView tv=(TextView)convertView.findViewById(R.id.groupTextView);
                tv.setText(g.getTitle());
                return convertView;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition,
                        boolean isLastChild, View convertView, ViewGroup parent) {
                        LayoutInflater childinflater=(LayoutInflater)mContext.
                                        getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                        convertView=childinflater.inflate(R.layout.list_item_command,parent,false);
                        TextView ItemTitleTextView=(TextView)convertView.
                                        findViewById(R.id.command_list_item_titleTextView);
                        c=(Command)getChild(groupPosition,childPosition);
                        ItemTitleTextView.setText(c.getTitle());
                        //Switch ItemWhatSwich=(Switch)convertView.findViewById(R.id.command_list_item_whatSwitch); //to be implemented
                        return convertView;
                }      

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
                return true;
        }
}

Logcat:
Codice (XML): [Seleziona]
09-13 08:34:03.120: E/AndroidRuntime(1614): FATAL EXCEPTION: main
09-13 08:34:03.120: E/AndroidRuntime(1614): Process: com.homeautomation.smarthome, PID: 1614
09-13 08:34:03.120: E/AndroidRuntime(1614): java.lang.NullPointerException
09-13 08:34:03.120: E/AndroidRuntime(1614):     at com.homeautomation.smarthome.ExpandableListAdapter.getChildrenCount(ExpandableListAdapter.java:40)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at android.widget.ExpandableListConnector.refreshExpGroupMetadataList(ExpandableListConnector.java:563)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at android.widget.ExpandableListConnector.expandGroup(ExpandableListConnector.java:688)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at android.widget.ExpandableListView.handleItemClick(ExpandableListView.java:691)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at android.widget.ExpandableListView.performItemClick(ExpandableListView.java:651)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at android.widget.AbsListView$3.run(AbsListView.java:3638)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at android.os.Handler.handleCallback(Handler.java:733)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at android.os.Handler.dispatchMessage(Handler.java:95)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at android.os.Looper.loop(Looper.java:136)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at android.app.ActivityThread.main(ActivityThread.java:5017)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at java.lang.reflect.Method.invokeNative(Native Method)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at java.lang.reflect.Method.invoke(Method.java:515)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
09-13 08:34:03.120: E/AndroidRuntime(1614):     at dalvik.system.NativeStart.main(Native Method)

Da circa una settimana non riesco  a risolvere il problema quindi ogni suggerimento è benvenuto! Grazie mille
« Ultima modifica: 13 Settembre 2014, 21:34:17 CEST da fabgio75 »