Neu für Android und Java und Learning by Doing, aber ich vermisse etwas grundlegend beim Detektieren von Element Klicks in einem ListView.Null Pointer Ausnahme beim Aufruf von SetOnItemClickListener
Ich habe eine Aktivität, die ein paar Tasten mit einem ListView unter ihnen ist. Jedes ListView-Element verfügt über ein Symbol, auf das geklickt werden kann, das schließlich zu einer anderen Aktivität wechselt, und einen Zeitstempel (der gerade angibt, dass der Klick über Toast funktioniert hat). Klick-Erkennung auf dem Symbol funktioniert, aber ich versuche, die Auswahl der Elemente in der ListView zu implementieren, und das ist, wo ich Probleme habe.
ich zahlreiche Beispiele wie this prüft haben, und ich denke, dass ich es wie vorgeschrieben tue, aber ich bin offensichtlich etwas fehlt, wie ich eine Laufzeitausnahme erhalte „java.lang.NullPointerException: Der Versuch, virtuelle Methode aufzurufen‚Leere android.widget.ListView.setOnItemClickListener (android.widget.AdapterView $ OnItemClickListener)‘auf einer null-Objekt-Referenz:“
Hier ist das Layout für die Ansicht:
<?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>
Hier ist das Layout für ein Element in der ListView. Wie bereits erwähnt, ist es mit einem Zeitstempel ein Symbol auf der linken Seite:
<?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>
Hier ist er() aus meiner Tätigkeit onCreate, die mein Adapter setzt:
@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);
}
Und hier ist, wo ich die habe Problem. Der OnClickListener für das Symbol funktioniert. Meine Absicht ist, die Auswahl eines ListView-Elements zu erkennen, damit es gelöscht werden kann. Wenn ich jedoch den Aufruf von SetOnItemClickListener() hinzufüge, erhalte ich eine Laufzeitausnahme.
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;
}
}
Aha. Ich verstehe es. Danke für die schnelle Antwort. Der Wechsel zu OnCreate() hat funktioniert. – sje