我正在使用listview,点击后会打开一个包含edittext和按钮的对话框。单击按钮时,editText中输入的值将保存在listView项目的textView中,该项目之前已按过该项目。问题是,如果我重新打开应用程序,则不再保存该值。我尝试使用sharedPrefences进行保存,但它崩溃并显示nullpointerexception并且无法处理它。
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.
NoteAdapter.java中的第76行:
holder.text.setText(savedEntries[position]);
适配器的构造函数 - 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);
}
}
EncodeDecode中的第39行:java:
for(int i = 0; i < toEncode.length; i++)
答案 0 :(得分:1)
lv.setAdapter(new NoteAdapter(this, prgmNameList, null))
是问题所在。 NoteAdapter
的构造函数希望第三个参数成为程序列表。
此外,我建议在Note
中创建一个空数组,并将其作为NoteAdapter
的第二个参数传递。然后,在onStop
中,您可以简单地说String toSave = EncodeDecode.encode(the_array_you_created);
而不是String toSave = EncodeDecode.encode(adapter.savedEntries);
修改强>
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();
}
....
}
答案 1 :(得分:1)
根据您的调试savedEntries == null
。这就是NullPointerException的原因:savedEntries[position]
由于您之后说过这些数组值将由用户提供,您可以例如添加一个空检查以避免此问题,如下所示:
if (savedEntries != null) {
holder.text.setText(savedEntries[position]);
} else {
holder.text.setText("");
}
<强>更新强>
看起来您尝试在2个不同的布局xmls中使用ID textView2
查找textview!一个是note_items
布局,另一个是note_listview
。
参见注意活动:
setContentView(R.layout.note_listview);
text = (TextView) findViewById(R.id.textView2);
参见 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);
==&GT;甚至没有看到xml布局(你没有提到问题),我可以说这不好。原因是您在不同的布局中有文字视图ID textView2
,这很糟糕,因为ID必须是唯一的,否则在note_items布局中只会丢失textView2
。