0

This is My MainActivity where I have defined dataRefresh method that refreshes the adapter when data is inserted or deleted from the database

public class MainActivity extends AppCompatActivity {
EditText phone, name;
ListView list;
MyDatabase db;
CustomAdapter ad;
ArrayList<contact> cont;
Button add;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    list=findViewById(R.id.list_item);
    db=new MyDatabase(this);
    cont=new ArrayList<>();
    cont=db.showData();
    ad=new CustomAdapter(this,cont;
    list.setAdapter(ad);
}


 public  void  dataRefresh(){
    cont.clear();
    cont.addAll(db.showData());
    ad.notifyDataSetChanged();
}

above is a dataRefresh method

This is My adapter class where I call the deletion method to delete data from the database

    public class CustomAdapter extends ArrayAdapter {
    ArrayList<contact> phnecontact;
    MyDatabase db;
    LinearLayout horizon;
    Context context;

    public CustomAdapter(@NonNull Context context, ArrayList<contact> 
    phonecontact) {
    super(context,R.layout.customlayout,phonecontact);
    this.context = context;
    this.phnecontact = phonecontact;
    }

    public contact getItem(int position) {
    return phnecontact.get(position);
   }

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

  @NonNull
  @Override
  public View getView(int position, View i, ViewGroup parent) {
    View view = 
  LayoutInflater.from(context).inflate(R.layout.customlayout, parent, 
  false);
    contact s1 = phnecontact.get(position);
    db=new MyDatabase(context);
    TextView name=view.findViewById(R.id.cmname);
    horizont=view.findViewById(R.id.horizontal);
    TextView number=view.findViewById(R.id.cmphone);
    ImageView sms=view.findViewById(R.id.message);
    ImageView call=view.findViewById(R.id.phone);
    ImageView photo=view.findViewById(R.id.cmphoto);
    number.setText(String.valueOf(s1.getPhone()));
    name.setText(s1.getName());
    horizont.setOnLongClickListener(v -> {
       AlertDialog.Builder builder=new AlertDialog.Builder(context);
       builder.setTitle("Are you sure to delete");
       builder.setPositiveButton("yes", new 
       DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
               int i =db.Deletioncontact(s1.getPhone());

I want to call dataRefresh method of Mainactivity after if condition

               if(i==1)
               {

                   Toast.makeText(context, "contact is deleted", 
      Toast.LENGTH_SHORT).show();
               }
               else
               {
                   Toast.makeText(context, "contact not deleted", 
  Toast.LENGTH_SHORT).show();
               }
           }
       });

If I call this method using an object of Mainactivity then my application is crashing

Praveen
  • 3,186
  • 2
  • 8
  • 23
  • 2
    You should use a callback from the adapter; Refer link: [callback-from-dapter](https://stackoverflow.com/questions/32032933/callback-from-adapter) – Cuong Nguyen Oct 13 '21 at 08:37
  • Why using a callback if he could initialise the data directly in the adapter instead of his approach? I would load the data in the constructor of the adapter. Then you can implement onItemAdded, onItemRemoved,... with the correct notify methods. Then you call adapter.onItemAdded,... – John Doe Oct 13 '21 at 08:55
  • @JohnDoe That would make adapter class tightly coupled with activity, and that's not a good way to program. – Praveen Oct 13 '21 at 10:02
  • The callback is more architecture friendly but in your case, an easy solution could be use the context from the view holder view and casting by your activity, then you will can to call your activity method. – Manuel Mato Oct 13 '21 at 10:02

2 Answers2

0

Apart from calling a method in mainActivity there are a few things which you can improve.

You don't have to pass context in the adapter, to use inside getView() method, you can get context from parent viewGroup

@Override
  public View getView(int position, View i, ViewGroup parent) {
    View view = 
  LayoutInflater.from(parent.getContext()).inflate(R.layout.customlayout, parent, 
  false);

You can move all your clickListeners and longClickListeneners logic to your activity, and use interface to trigger those methods. This way it would keep your adapter class loosely coupled with your activity and you can use this adapter in another activity or fragment too.

Create clickInterface in your adapter class

public interface ClickListeners {
     public void onItemlongClickListener(int phone);
}

Now override this interface in your activity

public class MainActivity extends AppCompatActivity implements CustomAdapter.ClickListener{
    //

    @Override
    protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         //
         ad = new CustomAdapter(this, cont); // pass interface instance to the adapter
         //
    }

    @Override
    public void onItemlongClickListener(int phone) {
        // add your dialog confirmation 
        // and item deletion code here
    }

}

Change CustomAdaper constructor to take interface instance

public CustomAdapter(ClickListeners clickListeners, ArrayList<contact> 
    phonecontact) {
    super(context,R.layout.customlayout,phonecontact);
    this.clickListeners = clickListeners;
    this.phnecontact = phonecontact;
    }

Trigger onItemlongClickListener when the user long clicks on the item

horizon.setOnLongClickListener(v -> {
      clickListeners.onItemlongClickListener(s1.getPhone()); // call interface method
}
Praveen
  • 3,186
  • 2
  • 8
  • 23
0

**Try with this at your onclick method **

public void onClick(DialogInterface dialog, int which) {

int i =db.Deletioncontact(s1.getPhone());

Iterator<Integer> itr = numbers.iterator();
while(itr.hasNext()) { 
   Phone phone = itr.next(); 
   if (phone == s1.getPhone()) {  
      s1.remove(phone); 
   } 
}
notifyDataSetChange();
}
S.Iliev
  • 48
  • 1
  • 6