我对android很新,并试图制作一个简单的字典。因此,当用户单击单词(列表项)时,将使用DetailActivity打开详细信息(单词+定义)。问题是,当单击Next
按钮时,我无法使用下一个单词刷新DetailActivity。
MainActivity:
public class MainActivity extends AppCompatActivity {
EditText mEditTextWord;
EditText mEditTextDefinition;
DictionaryDatabase mDB;
ListView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDB = new DictionaryDatabase(this);
mEditTextWord = (EditText)findViewById(R.id.editTextWord);
mEditTextDefinition = (EditText)findViewById(R.id.editTextDefinition);
Button buttonAddUpdate = (Button)findViewById(R.id.buttonAddUpdate);
buttonAddUpdate.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
saveRecord();
}
});
mListView = (ListView)findViewById(R.id.listView);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View
view, int position, long id) {
String nextId = String.valueOf(id+1);
Intent intent = new Intent(view.getContext(),DetailActivity.class);
intent.putExtra("key" ,mDB.getWord(id)+"");
intent.putExtra("value",mDB.getDefinition(id)+"");
intent.putExtra("nextId",nextId+"");
startActivity(intent);
}
});
mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this,
"Records deleted = " + mDB.deleteRecord(id),
Toast.LENGTH_SHORT).show();
updateWordList();
return true;
}
});
updateWordList();
}
...
和DetailActivity
public class DetailActivity extends AppCompatActivity {
Button shareBtn ;
Button nextBtn ;
DictionaryDatabase mDB;
TextView title, body; //Globally Declaration
String nextId;
int id;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
try{
String key = getIntent().getStringExtra("key");
String value = getIntent().getStringExtra("value");
String idString = getIntent().getStringExtra("nextId");
id = Integer.parseInt(idString) + 1; //to be used to render the next item
title = (TextView) findViewById(R.id.title);
title.setText(key);
body = (TextView) findViewById(R.id.body);
body.setText(value);
}
catch(Exception e){
e.printStackTrace();
}
//render the next item. There is no error without this part
mDB = new DictionaryDatabase(this);
nextBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String key = mDB.getWord(id);
String value = mDB.getDefinition(id);
title = (TextView) findViewById(R.id.title);
title.setText(key);
body = (TextView) findViewById(R.id.body);
body.setText(value);
}
});
}
}
运行时错误:
com.example.dict1 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dict1, PID: 22547
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.dict1/com.example.dict1.DetailActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
我已经持续了好几个小时,所以感谢您提示解决它。
更新:详细信息页面的布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.dictshop.dict1.DetailActivity"
tools:showIn="@layout/activity_detail">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Title"
android:id="@+id/title"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="txtBody"
android:id="@+id/body"
android:layout_below="@+id/title"
android:layout_marginTop="55dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Share"
android:id="@+id/shareBtn"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="76dp"
android:onClick="shareThis"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="next"
android:id="@+id/nextBtn"
android:layout_alignTop="@+id/shareBtn"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:onClick="nextWord"
/>
</RelativeLayout>
主页面布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.dictshop.dict1.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
和DictionaryDatabse.java
package com.dict1shop.dict1;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/**
* Created by me on 19/05/16.
*/
public class DictionaryDatabase extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "dict1.db";
private static final String TABLE_DICTIONARY = "dictionary";
private static final String FIELD_WORD = "word";
private static final String FIELD_DEFINITION = "definition";
private static final int DATABASE_VERSION = 1;
DictionaryDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_DICTIONARY +
"(_id integer PRIMARY KEY," +
FIELD_WORD + " TEXT, " +
FIELD_DEFINITION + " TEXT);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//Handle database upgrade as needed
}
public void saveRecord(String word, String definition) {
long id = findWordID(word);
if (id>0) {
updateRecord(id, word,definition);
} else {
addRecord(word,definition);
}
}
public long addRecord(String word, String definition) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(FIELD_WORD, word);
values.put(FIELD_DEFINITION, definition);
return db.insert(TABLE_DICTIONARY, null, values);
}
public int updateRecord(long id, String word, String definition) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("_id", id);
values.put(FIELD_WORD, word);
values.put(FIELD_DEFINITION, definition);
return db.update(TABLE_DICTIONARY, values, "_id = ?",
new String[]{String.valueOf(id)});
}
public int deleteRecord(long id) {
SQLiteDatabase db = getWritableDatabase();
return db.delete(TABLE_DICTIONARY, "_id = ?", new
String[]{String.valueOf(id)});
}
public long findWordID(String word) {
long returnVal = -1;
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery(
"SELECT _id FROM " + TABLE_DICTIONARY +
" WHERE " + FIELD_WORD + " = ?", new String[]{word});
Log.i("findWordID","getCount()="+cursor.getCount());
if (cursor.getCount() == 1) {
cursor.moveToFirst();
returnVal = cursor.getInt(0);
}
return returnVal;
}
public String getWord(long id) {
String returnVal = "";
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery(
"SELECT word FROM " + TABLE_DICTIONARY +
" WHERE _id = ?", new String[]{String.valueOf(id)});
if (cursor.getCount() == 1) {
cursor.moveToFirst();
returnVal = cursor.getString(0);
}
return returnVal;
}
public String getDefinition(long id) {
String returnVal = "";
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery(
"SELECT definition FROM " + TABLE_DICTIONARY +
" WHERE _id = ?", new String[]{String.valueOf(id)});
if (cursor.getCount() == 1) {
cursor.moveToFirst();
returnVal = cursor.getString(0);
}
return returnVal;
}
public Cursor getWordList() {
SQLiteDatabase db = getReadableDatabase();
String query = "SELECT _id, " + FIELD_WORD +
" FROM " + TABLE_DICTIONARY + " ORDER BY " + FIELD_WORD +
" ASC";
return db.rawQuery(query, null);
}
}
答案 0 :(得分:1)
我认为您的错误是将onClickListener()
方法分配给尚未初始化的按钮nextBtn
在protected void onCreate(Bundle savedInstanceState)
尝试做这样的事情
nextBtn= (Buttom) findViewById(R.id.nextBtn);
或您在xml填充中调用的任何内容
我希望得到这个帮助
答案 1 :(得分:1)
您获得null
的原因是您从未初始化onClickListener()
。你声明了它,但你没有初始化它所以对象引用现在是nextBtn = (Button) findViewById(R.id.id_of_next_Btn);
。在<?php
if( empty($_POST || !isset($_POST)) ) {
$last_ajax = null;
} else {
$last_ajax = time();
}
clearstatcache();
$last_change = filemtime('cache.txt');
if ($last_ajax == null || $last_change > $last_ajax) {
// Load the ajax
$R = json_decode(file_get_contents('php://input'), true);
// Load into memory the file
$F = json_decode(file_get_contents('cache.txt'), true);
// If not empty the file append
if(!empty($F)) {
$S = array_merge_recursive($F, $R);
file_put_contents('cache.txt', json_encode($S), true);
// Else just write into the file the post
} else {
file_put_contents('cache.txt', json_encode($R), true);
}
echo json_encode(file_get_contents('cache.txt'), true);
break;
}
?>
尝试以下操作之前:
var enrol = angular.module("enrol",[]);
enrol.controller("enrolController", function($scope, $http){
$scope.submit = function() {
console.log("Submitting");
$http({
method : "POST",
url : "dependencies/cache.php",
data : {
'action': 'enrol',
'data': {
'Login': $scope.apliclogin,
'Password': $scope.aplicpass,
'rol': {
'admin': $scope.admin,
'sala': $scope.sala,
'barra': $scope.barra,
'cocina': $scope.cocina,
'caja': $scope.caja
}
}
},
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function(data){
console.log(data);
});
};
});
如果您还有其他问题,请在评论中告诉我。
答案 2 :(得分:1)
我想在你的DetailActivity.class
中nextBtn == null
你必须做那样的事情:
Button nextBtn = (Button) findViewById(R.id.YOUR_BUTTON_ID_HERE);
之前
nextBtn.setOnClickListener(...);
答案 3 :(得分:0)
为此你应该将你的单词列表传递给DetailActivity.java
类,这样点击下一个按钮,你就会知道你需要意思的下一个单词。
在这里点击你只发送那个词的含义。您应该传递arraylist
和position
项目。这样您就可以从该特定位置的列表中获取数据。