我是 Android Studio 的极端初学者并且使用 JavaScript ,所以仍然在学习并尝试掌握整个android studio的新概念。
我正在尝试创建一个数据库,用于添加,编辑和删除用户手动输入的记录。
当我到达 friends.xml 页面( friends.java )并填写字段以添加用户并按" ADD"当我点击" VIEW DATA" (链接到 view_data.xml ( listdata.java ))似乎没有显示条目。
如果答案尽可能简单,我仍然是初学者,那将是很棒的!任何帮助将不胜感激!谢谢!
friends.java
package com.example.chris.mobileappsassignment;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class friends extends AppCompatActivity {
EditText firstnameinput, lastnameinput, ageinput, addressinput;
Button addbutton, viewbutton;
DatabaseHelper dbhlpr;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_friends);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
firstnameinput = (EditText) findViewById(R.id.firstnameinput);
lastnameinput = (EditText) findViewById(R.id.lastnameinput);
ageinput = (EditText) findViewById(R.id.ageinput);
addressinput = (EditText) findViewById(R.id.addressinput);
addbutton = (Button) findViewById(R.id.addbutton);
viewbutton = (Button) findViewById(R.id.viewbutton);
dbhlpr = new DatabaseHelper(this);
addbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean addOK = true;
int age_as_int = -1;
String firstName = firstnameinput.getText().toString();
String lastName = lastnameinput.getText().toString();
String age = ageinput.getText().toString();
String address = addressinput.getText().toString();
if (firstName.length() < 1) {
toastMessage("You must enter something in this field!");
firstnameinput.requestFocus();
addOK = false;
}
if (lastName.length() < 1) {
toastMessage("You must enter something in this field!");
lastnameinput.requestFocus();
addOK = false;
}
if (age.length() < 1) {
toastMessage("You must enter something in this field!");
ageinput.requestFocus();
addOK = false;
}
if (address.length() < 1) {
toastMessage("You must enter something in this field!");
addressinput.requestFocus();
addOK = false;
}
try {
age_as_int = Integer.parseInt(age);
} catch (NumberFormatException e) {
toastMessage("You must enter a valid Number in this field!");
ageinput.requestFocus();
addOK = false;
}
if (addOK) {
dbhlpr.addData(firstName,lastName,"????",age_as_int,address);
toastMessage("Friend Added!");
}
}
});
viewbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context,listdata.class);
startActivity(intent);
}
});
} //END ON CREATE CLASS
//TOAST MSSG
private void toastMessage(String message) {
Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_friends, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
listdata.java
package com.example.chris.mobileappsassignment;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import static com.example.chris.mobileappsassignment.R.layout.view_data;
public class listdata extends AppCompatActivity {
private static final String TAG = "listdata";
DatabaseHelper mDatabaseHelper;
private ListView mListView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(view_data);
mListView = (ListView) findViewById(R.id.ListView);
mDatabaseHelper = new DatabaseHelper(this);
populateListView();
} //END ONCREATE
private void populateListView() {
Log.d(TAG, "populate ListView: Displaying Data in the ListView");
//get data and append to list
Cursor data = mDatabaseHelper.getData();
Log.d("CURSORCOUNT", "Number of rows in Cursor =");
Integer.toString(data.getCount());
ArrayList<String> listData = new ArrayList<>();
while(data.moveToNext()){
//GET VALUE FROM DB IN COL1
//then add to ArrayList
listData.add(data.getString(1));
listData.add(data.getString(2));
listData.add(data.getString(3));
listData.add(data.getString(4));
listData.add(data.getString(5)); // NUMBERS REFER TO COL'S. (coloumns)
}
//create LIST ADAPTER AND SET ADAPTER
ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, listData);
mListView.setAdapter(adapter);
//set on onclick listener to list view
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String name = adapterView.getItemAtPosition(position).toString(); // will grab object and convert to string
Log.d(TAG, "onItemClick: You clicked on " + name);
Cursor data = mDatabaseHelper.getItemID(name); // get ID associated with that name
int itemID = 1; // WHEN SEARCHING // RETURN SOMETHING THAT EXISTS
while (data.moveToNext()){
itemID = data.getInt(0); // if data is returned
}
if (itemID > -1) {
Log.d(TAG, "onItemClick: The ID is: " + itemID);
Intent editScreenIntent = new Intent(listdata.this, EditDataActivity.class ); // VID2, 2.49
editScreenIntent.putExtra("id", itemID);
editScreenIntent.putExtra("name", name);
startActivity(editScreenIntent);
}
else {
toastMessage("No ID is associated with that name");
}
}
});
}
/**
* customizable toast
*/
private void toastMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
} //END CLASS
按&#34; ADD&#34; logcat中的错误
--------- beginning of crash
09-12 02:40:00.329 26615-26615/com.example.chris.mobileappsassignment E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.chris.mobileappsassignment, PID: 26615
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ComponentName.<init>(ComponentName.java:128)
at android.content.Intent.<init>(Intent.java:4449)
at com.example.chris.mobileappsassignment.friends$2.onClick(friends.java:99)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
答案 0 :(得分:0)
此处的问题是,在名为 friends_table 的表格中找不到名为地址的列,具体如下: -
09-10 20:38:48.892 10003-10003/com.example.chris.mobileappsassignment E/SQLiteDatabase: Error inserting address=Mike lastname=Mike firstname=Mike age=Mike malefemale=Mike
android.database.sqlite.SQLiteException: table friends_table has no column named address (code 1): , while compiling: INSERT INTO friends_table(address,lastname,firstname,age,malefemale) VALUES (?,?,?,?,?)
用于创建表的定义可能需要更改,或者定义已更改但已实现,因为数据库的onCreate
方法尚未运行。
onCreate
方法仅在创建数据库本身时自动运行,即在数据库文件的生命周期内运行一次。有3种简单的方法可以让onCreate
运行,注意所有3将删除数据库中的任何现有数据。
onCreate
,则可以增加数据库的版本号。因此你需要
onCreate
按上述三种方法中的一种运行(对于那些想要保留现有数据的人来说,还有其他解决方法)。同样,从日志中,您可能会遇到如何在 addData
中准备数据的问题,因为您尝试将相同的数据插入到所有列中,例如Error inserting address=Mike lastname=Mike firstname=Mike age=Mike malefemale=Mike
会导致姓氏,名字,年龄,男性女性都具有值 Mike ( sheesh我不知道我很受欢迎:))
查看您使用的朋友课程(例如): -
if (firstnameinput.length() !=0) {
AddData(firstName);
firstnameinput.setText(""); .........
您正在将单个参数传递给AddData
方法,因此可能会将此一个参数用作填充所有列的数据。
因此,您可能希望将AddData
方法更改为接受5个参数(地址,姓氏,名字,年龄和男性女性),然后使用相应数据填充列。
此外,您随后会为每个数据项(男性女性除外)多次({1}}调用AddData
。这将导致每次单击添加按钮添加4行。我相信你真正想要的是添加一行,你应该只用{5}或4(也许你还没有到男性女性)数据项来调用AddData
一次。因此,您最终会得到一行包含所有相应的数据。
由于您遇到了很多问题,其中许多似乎来自预先存在的代码。因此,似乎大部分代码都未经过测试。我建议采用不同的方法。基本上集中精力让事情发挥作用,然后加入其中。
因为这里的工作代码(非常基本)可以工作,并且允许你a)添加朋友(因为你可能想要选择这个来调整性别)和b)通过视图按钮列出它们。
首先 AndroidManifest.xml (注意!仅在需要时将其用于比较)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="mjt.so46145559friendsdb">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".friends">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".listdata"></activity>
</application>
</manifest>
activity_friends.xml 朋友活动的布局(非常基本没有微调器): -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="mjt.so46145559friendsdb.friends">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
<EditText
android:id="@+id/firstnameinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="firstname"
android:inputType="text"/>
<EditText
android:id="@+id/lastnameinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="lastname"
android:inputType="text"/>
<EditText
android:id="@+id/ageinput"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="3"
android:inputType="number"/>
<EditText
android:id="@+id/addressinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="address"
android:inputType="text"/>
<Button
android:id="@+id/addbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ADD"/>
<Button
android:id="@+id/viewbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="VIEW"/>
</LinearLayout>
请注意!你可能现有的布局很有效。
activity_listdata.xml 单击VIEW按钮时调用 listdata 活动的布局(非常基本)。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/friendslist_heading"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ListView
android:id="@+id/friendlist"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
</LinearLayout>
listdataitem.xml ListView在 listdata 活动中显示的每个项目(行)使用的布局。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/firstnamedisplay"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent" />
<TextView
android:id="@+id/lastnamedisplay"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent" />
<TextView
android:id="@+id/agedisplay"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" />
<TextView
android:id="@+id/addressdisplay"
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="match_parent" />
</LinearLayout>
DatabaseHelper.java SQLiteOpenHelper子类,请注意已经进行了一些更改(可用于发现它们的布朗尼点):)
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DatabaseHelper";
public static final String TABLE_NAME = "friends_table";
public static final String IDCOL = "_id";
public static final String COL1 = "firstname";
public static final String COL2 = "lastname";
public static final String COL3 = "malefemale";
public static final String COL4 = "age";
public static final String COL5 = "address";
public DatabaseHelper (Context context) {
super(context, TABLE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (" + IDCOL+ " TEXT PRIMARY KEY, " +
COL1 + " TEXT, " +
COL2 + " TEXT, " +
COL3 + " TEXT, " +
COL4 + " INTEGER, " +
COL5 + " TEXT " +
")";
db.execSQL(createTable);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP IF TABLE EXISTS" + TABLE_NAME);
onCreate(db);
}
public boolean addData(String firstname, String lastname, String gender, int age, String address) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL1, firstname);
contentValues.put(COL2, lastname);
contentValues.put(COL3, gender);
contentValues.put(COL4, age);
contentValues.put(COL5, address);
long result = db.insert(TABLE_NAME, null, contentValues);
//if data as inserted inorrectly it will return -1
if (result == 1)
return false;
else {
return true;
}
}
/**
* Returns all data from DB
*/
public Cursor getData() {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME;
return db.query(TABLE_NAME,null,null,null,null,null,null);
}
/**
* Returns ID that matches the name
* searches the DB and returns the ID associated with that name
*/
public Cursor getItemID(String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT " + COL1 + " FROM " + TABLE_NAME + // SELECT ID FROM DB
" WHERE " + COL2 + " = '" + name + "'"; // WHERE THE LAST NAME = NAME SELECTED
Cursor data = db.rawQuery(query, null);
return data;
}
/**
* Alternative means of getting ID return it as a long rather in a cursor
*/
public long getID(String firstname) {
long rv = 0;
SQLiteDatabase db = this.getWritableDatabase();
Cursor csr = db.query(TABLE_NAME,null,COL2 + "=?",new String[]{firstname},null,null,null);
if (csr.moveToFirst()) {
rv = csr.getLong(csr.getColumnIndex(IDCOL));
}
csr.close();
return rv;
}
/**
* UPDATES THE NAME
*
* UPDATE TABLE > SET LASTNNAME(COL2) = newName = WHERE id = id in Question = AND LASTNAME(COL2) = oldName (was previously) >
*/
public void updateName (String newName, int id, String oldName) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "UPDATE " + TABLE_NAME + " SET " + COL2 +
" = '" + newName + "' WHERE " + COL1 + " = '" + id + "'" +
" AND " + COL2 + " = '" + oldName + "'";
//LOGS THE NEW NAME
Log.d(TAG, "updateName: query: " + query);
Log.d(TAG, "updateName: Setting name to " + newName); // NEW NAME CHANGING IT TO
db.execSQL(query); // EXECUTE QUERY
}
/**
* DELETE FROM DATABASE
* >>> DELETE FROM TABLE WHERE id = id passed AND name = name passed
*
*/
public void deleteName(int id, String name){
SQLiteDatabase db = this.getWritableDatabase();
String query = "DELETE FROM " + TABLE_NAME + " WHERE "
+ COL1 + " = '" + id + "'" +
" AND " + COL2 + " = '" + name + "'";
Log.d(TAG, "deleteName: query: " + query);
Log.d(TAG, "deleteName: Deleting " + name + " from database.");
db.execSQL(query); // EXECUTE QUERY
}
}
friends.java (裸骨但它有效,美化取决于你:))
public class friends extends AppCompatActivity {
EditText firstnameinput, lastnameinput, ageinput, addressinput;
Button addbutton, viewbutton;
DatabaseHelper dbhlpr;
Context context; //############### FIX_001
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_friends);
context = this; //########## FIX_001
firstnameinput = (EditText) findViewById(R.id.firstnameinput);
lastnameinput = (EditText) findViewById(R.id.lastnameinput);
ageinput = (EditText) findViewById(R.id.ageinput);
addressinput = (EditText) findViewById(R.id.addressinput);
addbutton = (Button) findViewById(R.id.addbutton);
viewbutton = (Button) findViewById(R.id.viewbutton);
dbhlpr = new DatabaseHelper(this);
addbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean addOK = true;
int age_as_int = -1;
String firstName = firstnameinput.getText().toString();
String lastName = lastnameinput.getText().toString();
String age = ageinput.getText().toString();
String address = addressinput.getText().toString();
if (firstName.length() < 1) {
toastMessage("You must enter something in this field!");
firstnameinput.requestFocus();
addOK = false;
}
if (lastName.length() < 1) {
toastMessage("You must enter something in this field!");
lastnameinput.requestFocus();
addOK = false;
}
if (age.length() < 1) {
toastMessage("You must enter something in this field!");
ageinput.requestFocus();
addOK = false;
}
if (address.length() < 1) {
toastMessage("You must enter something in this field!");
addressinput.requestFocus();
addOK = false;
}
try {
age_as_int = Integer.parseInt(age);
} catch (NumberFormatException e) {
toastMessage("You must enter a valid Number in this field!");
ageinput.requestFocus();
addOK = false;
}
if (addOK) {
dbhlpr.addData(firstName,lastName,"????",age_as_int,address);
toastMessage("Friend Added!");
}
}
});
viewbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context,listdata.class); //########## FIX_001
startActivity(intent);
}
});
}
private void toastMessage(String message) {
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
}
最后是一个便宜又开朗的 listdata.java
public class listdata extends AppCompatActivity {
ListView mListView;
TextView firstname, lastname, age, address;
DatabaseHelper dbhlpr;
Cursor friendlist;
SimpleCursorAdapter sca;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listdata);
mListView = (ListView) findViewById(R.id.friendlist);
firstname = (TextView) findViewById(R.id.firstnamedisplay);
lastname = (TextView) findViewById(R.id.lastnamedisplay);
age = (TextView) findViewById(R.id.agedisplay);
address = (TextView) findViewById(R.id.addressdisplay);
dbhlpr = new DatabaseHelper(this);
friendlist = dbhlpr.getData();
Log.d("CURSORCOUNT","Rows in Cursor is " + friendlist.getCount());
// make a list of the columns from which the data is to be extracted
String[] dbcolums = {
DatabaseHelper.COL1,
DatabaseHelper.COL2,
DatabaseHelper.COL4,
DatabaseHelper.COL5
};
// make a list of the view's id where the data is to be placed
//Note each column will have a respective view
int[] listviewids = {R.id.firstnamedisplay, R.id.lastnamedisplay, R.id.agedisplay, R.id.addressdisplay};
// Setup the Adapter
sca = new SimpleCursorAdapter(
this, // The context
R.layout.listdataitem, // the lasyout for an item
friendlist, // cursor with data
dbcolums, // the list of DB columns to get data from
listviewids, // the views in the layout where to place the data
0 // don't worry
);
// Finally tie the adapter to the ListView
mListView.setAdapter(sca);
}
}
拿这些,甚至可能开始一个新项目, AS THEY ARE ,让它工作,然后一次添加一小部分。遇到问题时创建新问题。请不要修改问题,删除你添加的东西基本上只添加到问题。 (非常混淆比特)。也总是非常清楚已添加的内容。
按照以下方式运作: -
a)刚开始时: -
b)添加数据: -
c)查看: -