调用setOnItemClickListener时出现空指针异常

时间:2016-08-19 13:53:22

标签: java android listview

Android和Java新手以及边做边学,但我似乎缺少一些在ListView中检测项目点击的基本信息。

我有一个活动是一些按钮,下面有一个ListView。每个ListView项目都有一个可以单击的图标,最终将转到另一个活动,以及一个时间戳(当前只是指示通过Toast工作的点击)。图标上的点击检测工作正常,但我正在尝试在ListView中实现项目的选择,这就是我遇到麻烦的地方。

我已经回顾了许多例子,例如this,我认为我按照规定这样做但我显然遗漏了一些东西,因为我收到了运行时异常" java.lang.NullPointerException :尝试调用虚方法' void android.widget.ListView.setOnItemClickListener(android.widget.AdapterView $ OnItemClickListener)'在空对象引用上:"

以下是视图的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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"
    tools:context="com.example.foo.magma.ViewPassagesActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/linearLayout">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Update"
            android:onClick="update"
            android:id="@+id/updateButton"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_weight="1"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Delete"
            android:onClick="delete"
            android:id="@+id/deleteButton"
            android:layout_alignParentTop="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_weight="1"/>
    </LinearLayout>

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/passagesListView"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/linearLayout" />
    </RelativeLayout>

以下是ListView中项目的布局。如上所述,它左侧是一个带有时间戳的图标:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <ImageView
        android:id="@+id/icon"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="4dp"
        android:src="@drawable/curve" >
    </ImageView>

    <TextView
        android:id="@+id/label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Timestamp: "
        android:textStyle="bold"
        android:textSize="20dp"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@+id/icon"
        android:layout_toEndOf="@+id/icon">
        android:layout_toRightOf="@+id/icon"
    </TextView>

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="layouttesttime"
        android:textSize="20dp"
        android:layout_below="@+id/date"
        android:layout_alignRight="@+id/date"
        android:layout_alignEnd="@+id/date"
        android:layout_alignLeft="@+id/date"
        android:layout_alignStart="@+id/date">
    </TextView>

    <TextView
        android:id="@+id/date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="layouttestdate"
        android:textSize="20dp"
        android:layout_alignTop="@+id/icon"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_toRightOf="@+id/label"
        android:layout_toEndOf="@+id/label">
    </TextView>
    </RelativeLayout>

这是他来自我的活动的onCreate(),它设置了我的适配器:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_view_passages);

    ListView passagesListView = (ListView) findViewById(R.id.passagesListView);
    assert passagesListView != null;

    buildPassageList();

    PassagesViewAdapter adapter = new PassagesViewAdapter(this, R.layout.passages_row_layout, passages);
    passagesListView.setAdapter(adapter);


}

这就是我遇到问题的地方。图标的OnClickListener有效。我的目的是检测ListView项的选择,以便可以删除它。但是,当我添加setOnItemClickListener()的调用时,我收到一个运行时异常。

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;


public class PassagesViewAdapter extends ArrayAdapter<Passage>{

    private int resource;
    private List<Passage> passages;

    public  PassagesViewAdapter(Context context, int resource, List<Passage> passages) {
        super(context, resource, passages);
        this.resource = resource;
        this.passages = passages;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view = convertView;

        if (view == null) {
            LayoutInflater li = LayoutInflater.from(getContext());
            view = li.inflate(resource, null);
        }

        Passage passage = this.passages.get(position);

        TextView time = (TextView) view.findViewById(R.id.time);
        TextView date = (TextView) view.findViewById(R.id.date);
        ImageView icon = (ImageView) view.findViewById(R.id.icon);
        icon.setTag(new Integer(position));
        final String positionStr = icon.getTag().toString();

        // This works great!
        icon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(), "You clicked on " + positionStr, Toast.LENGTH_SHORT).show();
            }
        });

       ListView passagesListView = (ListView) view.findViewById(R.id.passagesListView);
       assert passagesListView != null;

       // ** This call results in a runtime error for null pointer reference.
       passagesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapter, View view, int position,long arg3) {
                Toast.makeText(getContext(), "Foo", Toast.LENGTH_SHORT).show();
            }
        });

        time.setText(passage.getPassageTime());
        date.setText(passage.getPassageDate());

        return view;
    }

}

2 个答案:

答案 0 :(得分:1)

这是因为您的适配器中的View代表您在列表中看到的View,而不是ViewPassagesActivity的布局。您的ListView项目中没有ListView,因此无法找到,findViewById返回null。如果您将设置OnItemClickListener的部分移动到onCreate的{​​{1}},那么一切都应该正常工作

从适配器中删除此部分

ViewPassagesActivity

并将其添加到您的Activity的onCreate中,如此

// ** This call results in a runtime error for null pointer reference.
passagesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapter, View view, int position,long arg3) {
        Toast.makeText(getContext(), "Foo", Toast.LENGTH_SHORT).show();
    }
});

答案 1 :(得分:0)

尝试从BaseAdapter扩展适配器。

public class PassagesViewAdapter extends ArrayAdapter<Passage>{

到这个

public class PassagesViewAdapter extends BaseAdapter {

您的 setOnItemClickListener 也需要位于活动中的onCreate函数中,而不是适配器中。