2016-08-19 101 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功能在您的活動,而不是在適配器。