Android:列表视图和选项卡视图
我一直遇到此错误:
E/AndroidRuntime(8107): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.KAHTextApp/com.example.KAHTextApp.Main}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.KAHTextApp/com.example.KAHTextApp.Inbox}: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
我需要一些帮助,当点击发送按钮时,消息将保存在数据库中,并且列表视图将显示详细信息。我使用 Notepad 3 教程 作为数据库。
这是 KAHTextApp java:
public class KAHTextApp extends Activity implements AdapterView.OnItemSelectedListener {
Button btnRecipient;
Button btnSend;
EditText editTextRecipient;
EditText editTextNewMessage;
Spinner spinnerTimeDelay;
private static final int CONTACT_PICKER_RESULT = 1001;
private int count=0;
private ProgressDialog dialog;
public boolean FirstLoad = true;
private MessagesDBAdapter mDbHelper;//
private Long mRowId;//
String[] items={"No Delay", "15 seconds", "30 seconds", "60 seconds"};
Handler handler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.compose_message);
btnRecipient = (Button) findViewById(R.id.button_recipient_picker);
btnSend = (Button) findViewById(R.id.button_send);
editTextRecipient = (EditText) findViewById(R.id.editText_recipient);
editTextNewMessage = (EditText) findViewById(R.id.editText_new_message);
spinnerTimeDelay = (Spinner) findViewById(R.id.spinner_delay);
spinnerTimeDelay.setOnItemSelectedListener(this);
ArrayAdapter<String> aa=new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,items);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerTimeDelay.setAdapter(aa);
mRowId = (savedInstanceState == null) ? null://
(Long) savedInstanceState.getSerializable(MessagesDBAdapter.KEY_ROWID);
if (mRowId==null) {
Bundle extras=getIntent().getExtras();
mRowId=extras!=null ? extras.getLong(MessagesDBAdapter.KEY_ROWID):null;
}
populateFields();//
// calls the contact picker
btnRecipient.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, CONTACT_PICKER_RESULT);
}
});
}
// Spinner
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
count=pos;
if(FirstLoad){
FirstLoad = false;
return;
}
Toast.makeText(parent.getContext(), "You chose " +
parent.getItemAtPosition(pos).toString()+ " to delay", Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView<?> parent) {
return;
}
public void showProgress () {
dialog = new ProgressDialog(this);
dialog.setCancelable(true);
dialog.setMessage("Sending Message .. ");
dialog.show();
}
// Contact Picker
@Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (CONTACT_PICKER_RESULT):
if (resultCode == Activity.RESULT_OK) {
StringBuilder sb = new StringBuilder();
Uri contactData = data.getData();
Cursor contactsCursor = managedQuery(contactData,
null, null, null, null);
if (contactsCursor.moveToFirst()) {
String id = contactsCursor.getString(contactsCursor
.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
String name = contactsCursor.getString(contactsCursor
.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
String hasPhoneNumber = contactsCursor.getString(contactsCursor
.getColumnIndexOrThrow(ContactsContract.Contacts.HAS_PHONE_NUMBER));
sb.append(name);
if (Integer.parseInt(hasPhoneNumber) > 0) {
Uri myPhoneUri = Uri.withAppendedPath(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, id);
Cursor phoneCursor = managedQuery(
myPhoneUri, null, null, null, null);
for (phoneCursor.moveToFirst(); !phoneCursor.isAfterLast(); phoneCursor.moveToNext()) {
String phoneNumber = phoneCursor.getString(phoneCursor
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
sb.append(phoneNumber);
}
} else {
sb.append("This contact doesn't have a phone number");
}
editTextRecipient.setText(sb.toString());
}
}
break;
}
btnSend.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String phoneNo = editTextRecipient.getText().toString();
String message = editTextNewMessage.getText().toString();
Log.d(phoneNo, message);
saveState();
boolean split = false;
final Toast toast = Toast.makeText(getBaseContext(),
"Your message " + "\"" + message + "\"" + " is sent to " +"\""+ phoneNo+"\"",
Toast.LENGTH_SHORT);
Runnable showToastRunnable = new Runnable() {
public void run() {
dialog.cancel();
toast.show();
}
};
if (phoneNo.length()>0 && message.length()>0) {
showProgress();
if (count == 0) {
handler.postDelayed(showToastRunnable, 0);
}
else if (count == 1) {
handler.postDelayed(showToastRunnable, 15000);
}
else if (count == 2) {
handler.postDelayed(showToastRunnable, 30000);
}
else if (count == 3) {
handler.postDelayed(showToastRunnable, 60000);
}
}
// sendSMS(phoneNo, message, split); */
else
Toast.makeText(getBaseContext(),
"Please enter both phone number and message.",
Toast.LENGTH_SHORT).show();
}
});
}
private void populateFields() {
if (mRowId!=null) {
Cursor note=mDbHelper.fetchNote(mRowId);
startManagingCursor(note);
editTextRecipient.setText(note.getString(note.getColumnIndexOrThrow(MessagesDBAdapter.KEY_RECIPIENT)));
editTextNewMessage.setText(note.getString(note.getColumnIndexOrThrow(MessagesDBAdapter.KEY_MESSAGE)));
}
}
protected void onSavedInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putSerializable(MessagesDBAdapter.KEY_ROWID, mRowId);
}
@Override
protected void onPause() {
super.onPause();
saveState();
}
@Override
protected void onResume() {
super.onResume();
populateFields();
}
private void saveState() {
String phoneNo = editTextRecipient.getText().toString();
String message = editTextNewMessage.getText().toString();
if (mRowId==null) {
long id=mDbHelper.createNote(phoneNo, message);
}
}
这是收件箱,列表视图数据库在其中:
public class Inbox extends ListActivity {
ListView ListViewMessageInbox;
private static final int ACTIVITY_CREATE=0;
private static final int ACTIVITY_EDIT=1;
private static final int INSERT_ID = Menu.FIRST;
private static final int DELETE_ID = Menu.FIRST + 1;
private MessagesDBAdapter mDbHelper;
private Cursor mNotesCursor;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.inbox);
mDbHelper = new MessagesDBAdapter(this);
mDbHelper.open();
fillData();
registerForContextMenu(getListView());
ListViewMessageInbox= (ListView) findViewById(R.id.ListViewMessageInbox);
}
private void fillData() {
String[] from = new String[]{MessagesDBAdapter.KEY_RECIPIENT};
int[] to = new int[]{R.id.text1};
SimpleCursorAdapter messages =
new SimpleCursorAdapter(this, R.layout.message_row, mNotesCursor, from, to);
setListAdapter(messages);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, INSERT_ID, 0, R.string.menu_insert);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case INSERT_ID:
createNote();
return true;
}
return super.onMenuItemSelected(featureId, item);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
mDbHelper.deleteNote(info.id);
fillData();
return true;
}
return super.onContextItemSelected(item);
}
private void createNote() {
Intent i = new Intent(this, KAHTextApp.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, KAHTextApp.class);
i.putExtra(MessagesDBAdapter.KEY_ROWID, id);
startActivityForResult(i, ACTIVITY_EDIT);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
fillData();
}
}
这是保存选项卡视图的主要部分:
public class Main extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = (TabHost)findViewById(android.R.id.tabhost);
TabSpec firstTabSpec = tabHost.newTabSpec("tid1");
TabSpec secondTabSpec = tabHost.newTabSpec("tid1");
firstTabSpec.setIndicator("Inbox").setContent(new Intent(this,Inbox.class));
secondTabSpec.setIndicator("New Message").setContent(new Intent(this,KAHTextApp.class));
tabHost.addTab(firstTabSpec);
tabHost.addTab(secondTabSpec);
}
}
我在这里错过了什么?请帮忙。
I keep having this error:
E/AndroidRuntime(8107): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.KAHTextApp/com.example.KAHTextApp.Main}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.KAHTextApp/com.example.KAHTextApp.Inbox}: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
I need some help, when the send button is tapped the message will be saved in the database and the list view will display the details. I used the Notepad 3 Tutorial for the database.
Here's the KAHTextApp java:
public class KAHTextApp extends Activity implements AdapterView.OnItemSelectedListener {
Button btnRecipient;
Button btnSend;
EditText editTextRecipient;
EditText editTextNewMessage;
Spinner spinnerTimeDelay;
private static final int CONTACT_PICKER_RESULT = 1001;
private int count=0;
private ProgressDialog dialog;
public boolean FirstLoad = true;
private MessagesDBAdapter mDbHelper;//
private Long mRowId;//
String[] items={"No Delay", "15 seconds", "30 seconds", "60 seconds"};
Handler handler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.compose_message);
btnRecipient = (Button) findViewById(R.id.button_recipient_picker);
btnSend = (Button) findViewById(R.id.button_send);
editTextRecipient = (EditText) findViewById(R.id.editText_recipient);
editTextNewMessage = (EditText) findViewById(R.id.editText_new_message);
spinnerTimeDelay = (Spinner) findViewById(R.id.spinner_delay);
spinnerTimeDelay.setOnItemSelectedListener(this);
ArrayAdapter<String> aa=new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,items);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerTimeDelay.setAdapter(aa);
mRowId = (savedInstanceState == null) ? null://
(Long) savedInstanceState.getSerializable(MessagesDBAdapter.KEY_ROWID);
if (mRowId==null) {
Bundle extras=getIntent().getExtras();
mRowId=extras!=null ? extras.getLong(MessagesDBAdapter.KEY_ROWID):null;
}
populateFields();//
// calls the contact picker
btnRecipient.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, CONTACT_PICKER_RESULT);
}
});
}
// Spinner
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
count=pos;
if(FirstLoad){
FirstLoad = false;
return;
}
Toast.makeText(parent.getContext(), "You chose " +
parent.getItemAtPosition(pos).toString()+ " to delay", Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView<?> parent) {
return;
}
public void showProgress () {
dialog = new ProgressDialog(this);
dialog.setCancelable(true);
dialog.setMessage("Sending Message .. ");
dialog.show();
}
// Contact Picker
@Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (CONTACT_PICKER_RESULT):
if (resultCode == Activity.RESULT_OK) {
StringBuilder sb = new StringBuilder();
Uri contactData = data.getData();
Cursor contactsCursor = managedQuery(contactData,
null, null, null, null);
if (contactsCursor.moveToFirst()) {
String id = contactsCursor.getString(contactsCursor
.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
String name = contactsCursor.getString(contactsCursor
.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
String hasPhoneNumber = contactsCursor.getString(contactsCursor
.getColumnIndexOrThrow(ContactsContract.Contacts.HAS_PHONE_NUMBER));
sb.append(name);
if (Integer.parseInt(hasPhoneNumber) > 0) {
Uri myPhoneUri = Uri.withAppendedPath(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, id);
Cursor phoneCursor = managedQuery(
myPhoneUri, null, null, null, null);
for (phoneCursor.moveToFirst(); !phoneCursor.isAfterLast(); phoneCursor.moveToNext()) {
String phoneNumber = phoneCursor.getString(phoneCursor
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
sb.append(phoneNumber);
}
} else {
sb.append("This contact doesn't have a phone number");
}
editTextRecipient.setText(sb.toString());
}
}
break;
}
btnSend.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String phoneNo = editTextRecipient.getText().toString();
String message = editTextNewMessage.getText().toString();
Log.d(phoneNo, message);
saveState();
boolean split = false;
final Toast toast = Toast.makeText(getBaseContext(),
"Your message " + "\"" + message + "\"" + " is sent to " +"\""+ phoneNo+"\"",
Toast.LENGTH_SHORT);
Runnable showToastRunnable = new Runnable() {
public void run() {
dialog.cancel();
toast.show();
}
};
if (phoneNo.length()>0 && message.length()>0) {
showProgress();
if (count == 0) {
handler.postDelayed(showToastRunnable, 0);
}
else if (count == 1) {
handler.postDelayed(showToastRunnable, 15000);
}
else if (count == 2) {
handler.postDelayed(showToastRunnable, 30000);
}
else if (count == 3) {
handler.postDelayed(showToastRunnable, 60000);
}
}
// sendSMS(phoneNo, message, split); */
else
Toast.makeText(getBaseContext(),
"Please enter both phone number and message.",
Toast.LENGTH_SHORT).show();
}
});
}
private void populateFields() {
if (mRowId!=null) {
Cursor note=mDbHelper.fetchNote(mRowId);
startManagingCursor(note);
editTextRecipient.setText(note.getString(note.getColumnIndexOrThrow(MessagesDBAdapter.KEY_RECIPIENT)));
editTextNewMessage.setText(note.getString(note.getColumnIndexOrThrow(MessagesDBAdapter.KEY_MESSAGE)));
}
}
protected void onSavedInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putSerializable(MessagesDBAdapter.KEY_ROWID, mRowId);
}
@Override
protected void onPause() {
super.onPause();
saveState();
}
@Override
protected void onResume() {
super.onResume();
populateFields();
}
private void saveState() {
String phoneNo = editTextRecipient.getText().toString();
String message = editTextNewMessage.getText().toString();
if (mRowId==null) {
long id=mDbHelper.createNote(phoneNo, message);
}
}
Here's the inbox, where the list view database is:
public class Inbox extends ListActivity {
ListView ListViewMessageInbox;
private static final int ACTIVITY_CREATE=0;
private static final int ACTIVITY_EDIT=1;
private static final int INSERT_ID = Menu.FIRST;
private static final int DELETE_ID = Menu.FIRST + 1;
private MessagesDBAdapter mDbHelper;
private Cursor mNotesCursor;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.inbox);
mDbHelper = new MessagesDBAdapter(this);
mDbHelper.open();
fillData();
registerForContextMenu(getListView());
ListViewMessageInbox= (ListView) findViewById(R.id.ListViewMessageInbox);
}
private void fillData() {
String[] from = new String[]{MessagesDBAdapter.KEY_RECIPIENT};
int[] to = new int[]{R.id.text1};
SimpleCursorAdapter messages =
new SimpleCursorAdapter(this, R.layout.message_row, mNotesCursor, from, to);
setListAdapter(messages);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, INSERT_ID, 0, R.string.menu_insert);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case INSERT_ID:
createNote();
return true;
}
return super.onMenuItemSelected(featureId, item);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
mDbHelper.deleteNote(info.id);
fillData();
return true;
}
return super.onContextItemSelected(item);
}
private void createNote() {
Intent i = new Intent(this, KAHTextApp.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, KAHTextApp.class);
i.putExtra(MessagesDBAdapter.KEY_ROWID, id);
startActivityForResult(i, ACTIVITY_EDIT);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
fillData();
}
}
and here's the main where it holds the tab view:
public class Main extends TabActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = (TabHost)findViewById(android.R.id.tabhost);
TabSpec firstTabSpec = tabHost.newTabSpec("tid1");
TabSpec secondTabSpec = tabHost.newTabSpec("tid1");
firstTabSpec.setIndicator("Inbox").setContent(new Intent(this,Inbox.class));
secondTabSpec.setIndicator("New Message").setContent(new Intent(this,KAHTextApp.class));
tabHost.addTab(firstTabSpec);
tabHost.addTab(secondTabSpec);
}
}
What do I miss here? Help please.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在您的
inbox.xml
布局文件中,当您想要使用ListActivity
时,您的 ListView 需要有这一行In your
inbox.xml
layout file, your ListView needs to have this line when you want to use aListActivity
当您扩展 listActivity
getListView()
时,它将搜索带有 id 的 Listview@android:list
。在inbox.xml中设置
when you extend listActivity
getListView()
it will search for Listview with id@android:list
.set it in inbox.xml
在您的 R.layout.inbox 表示 inbox.xml 文件中,
使用
android:id="@android:id/list"
声明一个 ListViewIn your R.layout.inbox means inbox.xml file,
declare a ListView with
android:id="@android:id/list"