Java 在自定义适配器notifyDataSetChanged上获取NullPointerException
我有一个自定义适配器,在调用Java 在自定义适配器notifyDataSetChanged上获取NullPointerException,java,android,nullpointerexception,android-adapter,baseadapter,Java,Android,Nullpointerexception,Android Adapter,Baseadapter,我有一个自定义适配器,在调用notifyDataSetChanged()获得nullPointerExeption后,我试图从中删除一个项 我想从数据库中删除数据,因此我将向适配器传递一个OnClickListener,以便稍后可以获取所需信息,以了解要删除的内容 这是我的密码: 带有列表视图的片段: adapter = new TransactionAdapter(getActivity(), values,currency); adapter.setButto
notifyDataSetChanged()
获得nullPointerExeption
后,我试图从中删除一个项
我想从数据库中删除数据,因此我将向适配器传递一个OnClickListener,以便稍后可以获取所需信息,以了解要删除的内容
这是我的密码:
带有列表视图的片段:
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);
<?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>
适配器:
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);
<?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>
公共类TransactionaAdapter扩展了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;
}
谢谢!您使用了错误类型的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);
}
现在在这里面,我们想知道哪一行按下了按钮
我是这样做的:
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!");
}
如果您的按钮“隐藏”得更深(例如,如果您的LinearLayout
内部有一个LinearLayout
,并且按钮位于该按钮的内部,则只需获取父级的父级:
LinearLayout parentOfParent = (LinearLayout) vwParentRow.getParent();
编辑2:
据我所知,您还可以通过编程方式添加侦听器,并让它执行与我在
methodName
中向您展示的相同的操作onClick
。我展示的方式确实有效-我在我的应用程序中使用了它。所以问题是,我是通过编程方式添加和ID的,它与其他ID冲突
在适配器上,我正在执行以下操作:
btnRemove = (Button) convertView.findViewById(R.id.btnRemove);
btnRemove.setOnClickListener(onClickListener);
btnRemove.setTag(entry);
btnRemove.setId(position);
我从教程中使用的代码,在我删除了setId
并在xml中使用了id之后,一切都正常了
谢谢大家u不能将onclick listener与适配器一起使用。您可以在此处检查按钮的id是否正确:
button btnRemove=(button)convertView.findViewById(R.id.btnRemove)
在R.layout.transaction\u item\u layout
中应该有一个按钮,id为btnRemove
@ShivamVerma是的,id是正确的。我已将布局添加到问题中。@raj即使侦听器是针对项目布局中的按钮,他们也在谈论第一个侦听器。适配器上的侦听器。在内部适配器,单击侦听器是可以的。即使侦听器是针对项目中包含的按钮的?请查看我的更新响应。我就是这样做的。如果它是正确的答案/它对您有帮助,请将其标记为已接受的答案。谢谢,让我尝试一下,您的EDIT2是我最初在问题中所做的。不是吗?这不起作用。因为我使用片段和点击方法将转到主活动,在那里我无法访问我需要的一半。但仍然可以帮助我找到正确的解决方案!它仍然可以帮助我,因为它抛出了一个android.content.res.Resources$NotFoundException:找不到资源ID#0x1
,在谷歌上搜索了一段时间后,我找到了解决方案