2016-08-19 54 views
0

刚刚接触Android和Java并且在干中学习,但我似乎在检测ListView中的项目点击时漏掉了一些基本的东西。当调用setOnItemClickListener时出现空指针异常

我有一个活动,它是一个ListView下面的几个按钮。每个ListView项目都有一个可以点击的图标,最终会转到另一个活动,并且有一个时间戳(当前仅表示点击通过Toast工作)。单击检测图标正在工作,但我试图在ListView中实现项目的选择,这是我遇到麻烦的地方。

我已审查的例子不胜枚举,如this,我认为我这样做的规定,但显然我失去了一些东西,因为我收到一个运行时异常“显示java.lang.NullPointerException:试图调用虚拟方法无效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; 
    } 

} 

回答

1

那是因为你在你的适配器有View代表View您在列表中看到的,不是你的ViewPassagesActivity的布局。您的ListView项目中没有ListView项,因此无法找到并且findViewById返回null。如果你移动你设置OnItemClickListenerViewPassagesActivityonCreate的一部分,一切都应该工作正常

从适配器删除这部分

// ** 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(); 
    } 
}); 

,并把它添加到您的活动的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); 

    // ** 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(); 
     } 
    }); 
} 
+0

啊哈。我知道了。感谢您的及时回复。移动到OnCreate()工作。 – sje

0

尝试从BaseAdapter扩展适配器。

public class PassagesViewAdapter extends ArrayAdapter<Passage>{ 

这个

public class PassagesViewAdapter extends BaseAdapter { 

而且你setOnItemClickListener必须在OnCreate功能在您的活动,而不是在适配器。

相关问题