简体   繁体   中英

How to delete listview item in fragment?

I'm trying to delete an item from a listview, but there is a problem..i'm using a fragment and I don't know how to get the "delete image button" to add a onClickListener... That's my xml of the delete button which is in payment_list_view.xml :

<ImageButton
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/trash_icon"
            android:padding="10dp"
            android:id="@+id/delete_payment_btn"
            android:background="@android:color/white" />

Then, I have my PaymentFragment which contains my listview:

 package com.nicola.baccillieri.splitpayment;




public class PaymentFragment extends Fragment {

private String descString;
private int price;
private String payedBy;
private ArrayList<String> descPayArray;
private ArrayList<Integer> priceArray;
private ArrayList<String> payedByArray;
int trash;
PaymentAdapter customAdapter;
private final static String SHARED_PREFS = "sharedPrefs";
FirebaseFirestore db;



@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    db = FirebaseFirestore.getInstance();
    trash = (R.drawable.trash_icon);
    descPayArray = new ArrayList<>();
    priceArray = new ArrayList<>();
    payedByArray = new ArrayList<>();


}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {


    final View rootView=inflater.inflate(R.layout.payments_fragment,container,false);

    ProgressBar detailsPb = rootView.findViewById(R.id.details_pb);
    detailsPb.getIndeterminateDrawable().setColorFilter(0XFF3F51B5,
            PorterDuff.Mode.MULTIPLY);
    detailsPb.setVisibility(View.VISIBLE);

    final ListView listView = rootView.findViewById(R.id.paymentLv);
    String email = getEmail();
    String groupName = getActivity().getIntent().getStringExtra("title");

    DocumentReference docRef = db.collection("users").document(email).collection("Group").document(groupName);

    docRef.collection("Payments")
            .get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                    for (QueryDocumentSnapshot document : queryDocumentSnapshots) {

                        //Extracting payment description from each document

                        descString = document.getId();
                        descPayArray.add(descString);

                        //Extracting cost and who payed from each document

                        price = document.getLong("cost").intValue();
                        priceArray.add(price);

                        payedBy = document.getString("payed by");
                        payedByArray.add(payedBy);
                        trash = R.drawable.trash_icon;
                        customAdapter = new PaymentAdapter(getActivity(), descPayArray, payedByArray, priceArray, trash);
                        listView.setAdapter(customAdapter);
                        ProgressBar detailsPb =  rootView.findViewById(R.id.details_pb);
                        detailsPb.setVisibility(View.GONE);
  // That's the line that cause the error
                        ImageButton deleteBtn = rootView.findViewById(R.id.delete_payment_btn);
                        deleteBtn.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                String groupName = getActivity().getIntent().getStringExtra("title");
                                int positionToRemove = (int) v.getTag();
                                String email = getEmail();
                                String paymentToRemove = descPayArray.get(positionToRemove);
                                DocumentReference docRef = db.collection("users").document(email).collection("Group").document(groupName).collection("Payments").document(paymentToRemove);
                                docRef.delete();

                                descPayArray.remove(positionToRemove);
                                customAdapter.notifyDataSetChanged();
                            }
                        });

                    }
                    // If there isn't any payment display a blank activity
                    ProgressBar detailsPb =  rootView.findViewById(R.id.details_pb);
                    detailsPb.setVisibility(View.GONE);


                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    ProgressBar detailsPb =  rootView.findViewById(R.id.details_pb);
                    detailsPb.setVisibility(View.GONE);
                    Toast.makeText(getContext(), "Failed to load payments", Toast.LENGTH_LONG).show();
                }
            });



    return rootView;

}


public String getEmail() {

    SharedPreferences sharedPreferences = this.getActivity().getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
    String email = (sharedPreferences.getString("email", ""));
    return email;
}}

and finally the file group_detail_activity.xml contains my 2 fragment with a tab layout. Now, the app crash when It has to show the PaymentFragment, because ImageButton deleteBtn = rootView.findViewById(R.id.delete_payment_btn); says

`java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference".

That's because my rootView contains payment_fragment.xml, and not the payment_list_view.xml. So It doesn't find the button. I've tryed to add final View rootListView=inflater.inflate(R.layout.payment_list_view,container,false); and then it shows the list view, but when I click on the delete button, it doesn't do anything. What should I do?

那就是列表视图的片段:

That's my PaymentAdapter:

package com.nicola.baccillieri.splitpayment;


public class PaymentAdapter extends BaseAdapter {

private Context context;
private ArrayList<String> payDesc;
private ArrayList<String> payedBy;
private ArrayList<Integer> price;
private int trash;
LayoutInflater inflater;


public PaymentAdapter(Context context, ArrayList<String> payDesc, ArrayList<String> payedBy, ArrayList<Integer> price, int trash) {
    this.context = context;
    this.payDesc = payDesc;
    this.payedBy = payedBy;
    this.price = price;
    this.trash = trash;
    inflater = (LayoutInflater.from(context));
}

@Override
public int getCount() {
    return payDesc.size();
}

@Override
public Object getItem(int position) {
    return payDesc.get(position);
}

@Override
public long getItemId(int position) {
    return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    convertView = inflater.inflate(R.layout.payment_list_view, null);

    TextView paymentDesc = convertView.findViewById(R.id.payedDescTv);
    TextView payedByTv = convertView.findViewById(R.id.payedByTv);
    TextView priceTv = convertView.findViewById(R.id.priceTv);
    ImageButton trashIcon = convertView.findViewById(R.id.delete_payment_btn);

    paymentDesc.setText(payDesc.get(position));
    payedByTv.setText("Payed by " + payedBy.get(position));
    priceTv.setText(String.valueOf(price.get(position)) + "€");
    trashIcon.setImageResource(trash);
    trashIcon.setTag(position);

    return convertView;
}}

The problem is that I need to delete the item both from the listview and from firebase...so I need the getEmail() method e the getExtra which is in PaymentFragment..If i put the listener on the adapter, how can I delete o Firebase?

Try this way. On list clicked you can delete item

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            payedByArray.remove(position);
            adapter.notifyItemRemoved(position);

        }
    });

Other way is to put the Delete Button in your payment_list_view and then in Adapter you can get position on that button click and delete it

From Custom_adapater's viewholder get the view id , and you can easily delete the item by using

payedByArray.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, payedByArray.size());

How to delete list item ,a SO's question already answered.. Have a look... that might solve your problem.

You can set a listener to link the delete image button action to your fragment. Then can the button is click you trigger the listener and do what your want in your fragment. Yo can send the position to remove the good element

Your adapter don't know that list is being modified. you need to provide latest list to adapter after deletion of item.

Make your payedByArray list public in adapter code.

This activity code.

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        payedByArray.remove(position);
        //payedByArray is activity list;
        adapter.payedByArray = payedByArray;
        adapter.notifyItemRemoved(position);
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM