无法在DetailActivity中呈现ListView的下一项

时间:2016-05-21 00:03:04

标签: android listview onclicklistener

我对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);
    }
}

4 个答案:

答案 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类,这样点击下一个按钮,你就会知道你需要意思的下一个单词。

在这里点击你只发送那个词的含义。您应该传递arraylistposition项目。这样您就可以从该特定位置的列表中获取数据。