refresh listview when using hashmap

2019-08-10 07:55发布

问题:

I have a multiline listview , implemented using hashmaps . I get my data from a database .

I have another activity in which i am adding my items , which is being added to the database . Now when pressing the save button , the new added item should appear immediately in the listview which is implemented in a fragment . I can't figure out how to refresh the listview in this activity .

here's my fragment implementing the listview :

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {             
            myView = inflater.inflate(R.layout.fragment_layout, container, false);



            l = db.getAllEntries();

            list = (ListView) myView.findViewById(R.id.entrylist);
            mylist = new ArrayList<HashMap<String,String>>();


            HashMap<String,String> item;


            while(!l.isEmpty()){

                e = l.get(0);
                l.remove(0);

              item = new HashMap<String,String>();

              item.put( "line1", e._totime + " - " + e._totime);
              item.put( "line2", e._subject);
              item.put( "line3", e._place);
              mylist.add(n++,item);
            }

              sa = new SimpleAdapter(getActivity(), mylist,
                        R.layout.multi_line,
                        new String[] { "line1","line2", "line3" },
                        new int[] {R.id.line_a, R.id.line_b, R.id.line_c}); 

            list.setAdapter(sa);
return myView;
    }

and here in this activity i am adding items to the database , which should immediately appear in my listview above :

public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {
  case R.id.save:



      sub = subject.getText().toString();
      teach = teacher.getText().toString();
      pla = place.getText().toString();
      da = day.getSelectedItem().toString();
      fro = fromtime.getText().toString();
      to = totime.getText().toString();


      i = new Entries(sub,teach,pla,da,fro,to);
      db.addEntry(i);



      FragmentView1 f = (FragmentView1) this.getSupportFragmentManager().findFragmentByTag(FragmentView1.class.getName());


      l = db.getAllEntries();
      HashMap<String,String> map;


      while(!l.isEmpty()){

        e = l.get(0);
        l.remove(0);

        map = new HashMap<String,String>();

        map.put( "line1", e._fromtime + " - " + e._totime);
        map.put( "line2", e._subject);
        map.put( "line3", e._place);
        f.getArrayList().add(n++,map);    //nullpointerexception here
      }
      f.getMyListAdapter().notifyDataSetChanged();


        /*Toast.makeText(this, "You have chosen the " + getResources().getString(R.string.save) + " menu option",
                    Toast.LENGTH_SHORT).show();*/
        return true;


  default:
        return super.onOptionsItemSelected(item);
  }

}

回答1:

This is probably because findFragmentByTag() is not able to find the required fragment and so is returning null, resulting in NullPointerException when you try to access it. You can try a workaround by retrieving the tag for fragment and storing it in activity class variable for further access as follows:

In your activity class, declare a private String variable and getter/setter methods for it:

    public String fragmentView1Tag;

public String getfragmentView1Tag() {
    return fragmentView1Tag;
}

public void setfragmentView1Tag(String fragmentView1Tag) {
    this.fragmentView1Tag = fragmentView1Tag;
}

In FragmentView1 class, retrieve the tag of the fragment and set fragmentView1Tag variable:

    String tag = getTag();
    ((YourActivityName) getActivity()).setfragmentView1Tag(tag);

And now while retrieving the fragment in activity class, use the above getter method:

    FragmentView1 f = (FragmentView1) this.getSupportFragmentManager().findFragmentByTag(getfragmentView1Tag);


回答2:

Use a cursor to get all the rows from the database. Then use a cursor adapter to populate the list. After you add a new row to the database, just call notifyDataSetChanged(); on the cursor adapter.