Question

I'm working with a listview which on click opens a dialog box which contains an edittext and a button. On button click, the value entered in the editText is saved in a textView from listview item which had been pressed before. The problem is that the value wasn't saved anymore if I reopened the application. I tried to make it save using sharedPrefences but it's crashing and shows nullpointerexception and can't deal with it.

NoteAdapter.java:

 package com.cngcnasaud.orar;

    import java.util.Arrays;

    import android.app.Dialog;
    import android.content.Context;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ImageView;
    import android.widget.TextView;

    public class NoteAdapter extends BaseAdapter {

        String[] result;
        Context context;
        int[] imageId;
        private static LayoutInflater inflater = null;
        private Dialog dialog;
        String[] savedEntries;
        String[] saved = null;

        public NoteAdapter(Note note, String[] saved, String[] prgmNameList) {
            // TODO Auto-generated constructor stub
            result = prgmNameList;
            context = note;
            inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (saved == null) {
                savedEntries = new String[result.length];
                Arrays.fill(savedEntries, "");
            } else
                savedEntries = saved;

        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return result.length;
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return savedEntries[position];
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        public class Holder {
            TextView tv;
            ImageView img;
            public TextView text;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub

            final Holder holder = new Holder();
            View rowView;
            rowView = inflater.inflate(R.layout.note_items, null);
            holder.tv = (TextView) rowView.findViewById(R.id.textView1);
            holder.text = (TextView) rowView.findViewById(R.id.textView2);
            holder.text.setText(savedEntries[position]);
            holder.img = (ImageView) rowView.findViewById(R.id.imageView1);

            rowView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    dialog = new Dialog(context);
                    dialog.setContentView(R.layout.dialog);
                    dialog.setTitle("Materie:" + result[position]);

                    final EditText txtMode = (EditText) dialog
                            .findViewById(R.id.dialog);
                    Button btnSave = (Button) dialog.findViewById(R.id.bsave);

                    btnSave.setOnClickListener(new OnClickListener() {

                        @Override
                        public void onClick(View v) {

                            String data = txtMode.getText().toString();
                            holder.text.setText(data);

                            savedEntries[position] = data;

                            dialog.dismiss();
                            Log.d("data", data);
                        }
                    });
                    dialog.show();
                }

            });
            return rowView;
        }

    }

logcat:

04-19 04:14:32.130: E/AndroidRuntime(947): FATAL EXCEPTION: main
04-19 04:14:32.130: E/AndroidRuntime(947): Process: com.cngcnasaud.orar, PID: 947
04-19 04:14:32.130: E/AndroidRuntime(947): java.lang.NullPointerException
04-19 04:14:32.130: E/AndroidRuntime(947):  at com.cngcnasaud.orar.NoteAdapter.getView(NoteAdapter.java:76)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.AbsListView.obtainView(AbsListView.java:2263)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.ListView.makeAndAddView(ListView.java:1790)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.ListView.fillDown(ListView.java:691)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.ListView.fillFromTop(ListView.java:752)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.ListView.layoutChildren(ListView.java:1630)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.AbsListView.onLayout(AbsListView.java:2091)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:374)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.View.layout(View.java:14817)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewGroup.layout(ViewGroup.java:4631)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1987)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1744)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.Choreographer.doCallbacks(Choreographer.java:574)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.Choreographer.doFrame(Choreographer.java:544)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.os.Handler.handleCallback(Handler.java:733)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.os.Handler.dispatchMessage(Handler.java:95)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.os.Looper.loop(Looper.java:136)
04-19 04:14:32.130: E/AndroidRuntime(947):  at android.app.ActivityThread.main(ActivityThread.java:5017)
04-19 04:14:32.130: E/AndroidRuntime(947):  at java.lang.reflect.Method.invokeNative(Native Method)
04-19 04:14:32.130: E/AndroidRuntime(947):  at java.lang.reflect.Method.invoke(Method.java:515)
04-19 04:14:32.130: E/AndroidRuntime(947):  at com.android.internal.os.

Line 76 in NoteAdapter.java:

holder.text.setText(savedEntries[position]);

Adapter's constructor - Note.java:

package com.cngcnasaud.orar;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.Menu;

import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class Note extends Activity {

    public static final ListAdapter NoteAdapter = null;
    ListView lv;
    Context context;
    ArrayList<?> prgmName;
    TextView text;

    public static String[] prgmNameList = { "Romana   - ", "Matematica   - ",
            "Lb. Engleza   - ", "Lb. Germana/Franceza - ", "Istorie   - ",
            "Geografie   - ", "Biologie   - ", "Fizica   - ", "Ed. Fizica   - " };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.note_listview);

        text = (TextView) findViewById(R.id.textView2);

        context = this;

        lv = (ListView) findViewById(R.id.listView);
        lv.setAdapter(new NoteAdapter(this, prgmNameList, null));

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub

        NoteAdapter adapter = (NoteAdapter) lv.getAdapter();

        // Variable is public for clarity.
        String toSave = EncodeDecode.encode(adapter.savedEntries);
        SharedPreferences.Editor editor = getSharedPreferences("LV Data",
                MODE_PRIVATE).edit();
        editor.putString("TVEntries", toSave);
        editor.commit();
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub

        SharedPreferences prefs = getSharedPreferences("LV Data", MODE_PRIVATE);
        String encoded = prefs.getString("TVEntries", "");

        String[] entries;
        if (encoded.equals(""))
            entries = null;
        else
            entries = EncodeDecode.decode(encoded);

        NoteAdapter adapter = (NoteAdapter) lv.getAdapter();
        adapter.savedEntries = entries;
        lv.setAdapter(adapter);

        super.onResume();
    }

}

EncodeDecode.java:

package com.cngcnasaud.orar;

import java.util.ArrayList;
import java.util.Arrays;
import java.lang.StringBuffer;

public class EncodeDecode
{

  public static void main(String[] args)
  {
    //Test functionality.
    String[] toEncode = {"a?b","c,d,", "asdas,dasd?,,,,,", "asdsad*\t      "};
    String encodedString = encode(toEncode);
    String[] decodedArray = decode(encodedString);
    System.out.println("Original Array: " + Arrays.toString(toEncode));
    System.out.println("Encoded String: " + encodedString);
    System.out.println("Decoded Array: " + Arrays.toString(decodedArray));
    System.out.println();
    System.out.println("Testing equality of the arrays.....");
    if(encode(toEncode).equals(encode(decodedArray)))
      System.out.println("Passed!");
    else
       System.out.println("Failed :(!");
  }

  /**  
   *  Function: encode
   *  --------------------
   *  Encode a String array into a single String.
   *  
   *  toEncode: the String array to be encoded.
   *
   *  returns: the encoded string.
   */
  public static String encode(String[] toEncode)
  {
    StringBuffer strBuf = new StringBuffer();
    for(int i = 0; i < toEncode.length; i++)
    {
      /*Retrieve a representation of the current string element that is
      easier to modify.*/
      StringBuffer curString = new StringBuffer(toEncode[i]);
      for(int j = 0; j < curString.length(); j++)
        //If we see a "break" character, prepend another "break" character to it.
        if(curString.charAt(j) == '?')
        {
          curString.insert(j, '?');
          j++;
        }
        //If we see a delimiter character, prepend "break" character to it.
        else if(curString.charAt(j) == ',')
        {
          curString.insert(j, '?');
          j++;
        }

      //Add the delimiter to the encoded string.
      strBuf.append(curString + ",");

    }
    return strBuf.toString();
  }

  /**  
   *   Function: decode
   *  --------------------
   *  Decode an encoded string into its original array..
   *  
   *  toDecode: the String to be decoded.
   *
   *  returns: the decoded String array.
   */
  public static String[] decode(String toDecode)
  {
    /*We utilize an ArrayList, since the exact number of 
    string elements is inderterminate*/
    ArrayList<String> decoded = new ArrayList<String>();

    /*Retrieve a representation of the current string element that is
    easier to modify.*/
    StringBuffer encodedStr = new StringBuffer(toDecode);

    //The starting point of the current isolated string to add/append.
    int currIndex = 0;

    for(int i = 0; i < encodedStr.length(); i++)
    {
      /*If we see the "break character" remove it, and skip
      the following character*/
      if(encodedStr.charAt(i) == '?')
        encodedStr.deleteCharAt(i);

      /*If we see a delimiter, add what we have amassed
      so far to the list.*/
      else if(encodedStr.charAt(i) == ',')
      {
        decoded.add(encodedStr.substring(currIndex, i));

        //Update the starting point.
        currIndex = i + 1;
      }
    }

    String[] toReturn = new String[decoded.size()];
    return decoded.toArray(toReturn);
  }
}

Line 39 in EncodeDecode:java:

for(int i = 0; i < toEncode.length; i++)
Was it helpful?

Solution

According to your debugging savedEntries == null. That is the reason for the NullPointerException here: savedEntries[position]

Since you said that those array-values will be provided by the users later you can for example just add a null check to avoid this problem, something like this:

if (savedEntries != null) {
    holder.text.setText(savedEntries[position]);
} else {
    holder.text.setText(""); 
}

Update:

Looks like you try to look up the textview with the id textView2 in 2 different layout xmls! One is in note_items layout, the other in note_listview.

See in Note Activity:

    setContentView(R.layout.note_listview);

    text = (TextView) findViewById(R.id.textView2);

See in NoteAdapter:

    rowView = inflater.inflate(R.layout.note_items, null);
    holder.tv = (TextView) rowView.findViewById(R.id.textView1);
    holder.text = (TextView) rowView.findViewById(R.id.textView2);

==> Without even looking at the xml layout (which you didn't include in question) I can tell that this is not good. The reason is you have either textviews id textView2 in different layouts, which is bad since ids must be unique or textView2 is simply missing in note_items layout.

OTHER TIPS

lv.setAdapter(new NoteAdapter(this, prgmNameList, null)) is the problem. NoteAdapter's constructor expects the third argument to be the program list.

In addition, I would recommend creating an empty array in Note and passing that in as NoteAdapter's second argument. Then, in your onStop, you could simply say String toSave = EncodeDecode.encode(the_array_you_created); instead of String toSave = EncodeDecode.encode(adapter.savedEntries);

EDIT

public class Note extends Activity {

...
private String[] savedArray;
...

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    savedArray = new String[prgmNameList.length];
    lv.setAdapter(new NoteAdapter(this, savedArray, prgmNameList));

}

...

@Override
protected void onStop() {
    String toSave = EncodeDecode.encode(savedArray);
    SharedPreferences.Editor editor = getSharedPreferences("LV Data",
            MODE_PRIVATE).edit();
    editor.putString("TVEntries", toSave);
    editor.commit();
}
....

}

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