2016-08-19 4 views
0

안드로이드 및 Java에 익숙하지 만 배우는 방법을 배우지 만 ListView에서 항목 클릭을 탐지 할 때 근본적인 것이 빠져있는 것처럼 보입니다.null 포인터 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. 타임 스탬프 왼쪽에,이 아이콘 언급 한 바와 같이 : 여기

@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); 


} 

그리고 난을 겪고있는 곳입니다 :

여기
<?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입니다 발행물. 아이콘의 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

당신이 어댑터에있는 ViewViewPassagesActivityView이 목록에 표시하지 레이아웃을 나타 내기 때문이다. ListView 항목에 ListView이 없으므로 findViewById은 null을 반환합니다. 당신이 당신의 ViewPassagesActivityonCreateOnItemClickListener 설정 부분을 이동하는 경우, 모든 어댑터에서

// ** 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에서 어댑터를 확장 해보십시오. 하지 어댑터에, 당신의 활동에에서 onCreate 함수에 있어야이 또한

public class PassagesViewAdapter extends BaseAdapter { 

당신의 setOnItemClickListener이

public class PassagesViewAdapter extends ArrayAdapter<Passage>{ 

.