我有一个自定义适配器,在我致电notifyDataSetChanged()
后我试图从中删除一个项目我得到nullPointerExeption
。
我想从数据库中删除数据,因此我将OnClickListener传递给适配器,以便稍后获取知道删除内容所需的信息。
这是我的代码:
使用ListView进行分段:
adapter = new TransactionAdapter(getActivity(), values,currency);
adapter.setButtonOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RelativeLayout l = (RelativeLayout) v.getParent();
String id_string = ((TextView) l.findViewById(R.id.transaction_id)).getText() +"";
int id = Integer.parseInt(id_string);
//Remove from DB
if(adapter.remove(id)){
adapter.notifyDataSetChanged();
}
Toast.makeText(getActivity(), "deleted entry - "+ id, Toast.LENGTH_SHORT).show();
}
});
// Assign adapter to ListView
listView.setAdapter(adapter);
适配器:
公共类TransactionAdapter扩展BaseAdapter { 私有上下文上下文;
private OnClickListener onClickListener;
private List<Transaction> listTransaction;
private String currency;
public TransactionAdapter(Context context, List<Transaction> listTransaction, String currency) {
this.context = context;
this.listTransaction = listTransaction;
this.currency = currency;
}
public void setButtonOnClickListener(OnClickListener c){
onClickListener = c;
}
public View getView(int position, View convertView, ViewGroup viewGroup) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.transaction_item_layout, null);
}
convertView.setClickable(false);
Transaction entry = listTransaction.get(position);
TextView tvDescription = (TextView) convertView.findViewById(R.id.description);
String description = entry.getDescription();
if(description == null){
description = "Description Filler";
}
tvDescription.setText(description);
TextView tvAmount = (TextView) convertView.findViewById(R.id.amount);
Boolean expense = entry.getExpense();
if(expense) {
tvAmount.setText("- " + entry.getAmount().toString() + currency);
tvAmount.setTextColor(context.getResources().getColor(R.color.buttons_color_delete));
}else{
tvAmount.setText("+ " + entry.getAmount().toString() + currency);
tvAmount.setTextColor(context.getResources().getColor(R.color.second_elements_color));
}
TextView tvID = (TextView) convertView.findViewById(R.id.transaction_id);
tvID.setText(entry.getId()+"");
// Set the onClick Listener on this button
Button btnRemove = (Button) convertView.findViewById(R.id.btnRemove);
btnRemove.setOnClickListener(onClickListener);
btnRemove.setTag(entry);
btnRemove.setId(position);
return convertView;
}
public boolean remove(int id){
for (int i = 0; i < listTransaction.size(); i++) {
Transaction t = listTransaction.get(i);
if(id == t.getId()){
listTransaction.remove(i);
return true;
}
}
return false;
}
Item_layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/transaction_item"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_marginTop="1dp"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:orientation="horizontal"
android:background="@drawable/edittext_create_budget">
<TextView
android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/create_budget_edit_text"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:gravity="center_vertical"
android:text="@string/start_date" />
<TextView
android:id="@+id/transaction_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="id"
android:visibility="gone"/>
<TextView
android:id="@+id/amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_toLeftOf="@+id/btnRemove"
android:layout_toStartOf="@+id/btnRemove"
android:gravity="center_vertical"
android:textColor="@color/create_budget_edit_text"
android:textSize="20sp"
android:text="23.05€" />
<Button
android:id="@+id/btnRemove"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginRight="15dp"
android:layout_marginEnd="15dp"
android:background="@drawable/round_button"
android:text="R" />
</RelativeLayout>
这是 StackTrace :
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at TransactionAdapter.getView(TransactionAdapter.java:75)
at android.widget.AbsListView.obtainView(AbsListView.java:2344)
at android.widget.ListView.makeAndAddView(ListView.java:1864)
at android.widget.ListView.fillSpecific(ListView.java:1344)
at android.widget.ListView.layoutChildren(ListView.java:1651)
at android.widget.AbsListView.onLayout(AbsListView.java:2148)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:887)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:494)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2072)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1829)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
谢谢!
答案 0 :(得分:1)
您正在使用错误类型的OnClickListener!
以下是我的代码:
receiverList = dbTools.getAllReceivers();
dbTools.close();
listView = getListView();
if(receiverList.size() != 0) {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int index, long id) {
TextView textView = (TextView) view.findViewById(R.id.receiverId);
setReceiverSelection(Integer.valueOf(textView.getText().toString()));
((SimpleAdapter) getListAdapter()).notifyDataSetChanged();
}
});
SimpleAdapter adapter = getNewAdapter();
setListAdapter(adapter);
}
您需要使用AdapterView.OnItemClickListener()
。在onItemClick()
方法中,您将获得所点击行的view
和index
。
希望这会有所帮助。祝你好运:)
编辑:
如果您希望在行中的按钮上有一个监听器,这是最简单的方法。
在添加行的XML中,将android:onClick="methodName"
添加到Button的XML中。
然后,在您拥有ListView
的活动中,添加底部,添加一个名为methodName
的方法,该方法将View
作为参数。它看起来像这样。
public void methodName(View view) {
}
现在,我们要弄清楚哪一行按了它的按钮。
我是这样做的:
public void methodName(View view) {
LinearLayout vwParentRow = (LinearLayout)view.getParent();
TextView recId = (TextView) vwParentRow.findViewById(R.id.receiverId);
System.out.println(recId.getText().toString() + " had its button pressed!");
}
如果你的按钮被埋没了#39;更深层(如果你的LinearLayout
内有一个LinearLayout
并且按钮位于其中,只需获取父级的父级:
LinearLayout parentOfParent = (LinearLayout) vwParentRow.getParent();
EDIT2:
你也可以按照我所知的方式以编程方式添加一个监听器,让它像我在onClick
中向你展示的那样methodName
。我展示的方式肯定有效 - 我在我的应用程序中使用它。
答案 1 :(得分:0)
所以问题是我正在添加和ID以及其他ID
在我正在做的适配器上:
btnRemove = (Button) convertView.findViewById(R.id.btnRemove);
btnRemove.setOnClickListener(onClickListener);
btnRemove.setTag(entry);
btnRemove.setId(position);
我从教程中使用的代码,在我删除了setId
之后,只是在xml中使用了ID,一切正常。
谢谢大家