notifyDataSetChanged() не обновляет расширяемый список

Я использую Expandable ListView, и данные в нем заполняются через базу данных Sqlite. Я дал возможность удалить группу из ExpandableListView, и она фактически удаляет соответствующую row в базе данных. Но действие не обновляется, и удаленное «дело» видно до тех пор, пока вы не вернетесь и не вернетесь снова к этому activity. Я создал class, который extends *BaseExpandableListAdapter*. Он содержит все overridden методы. Ниже приведен код:

public class ExpandableListAdapterForRunning extends BaseExpandableListAdapter {

private Context _context;
private List<String> _listDataHeader; // header titles
public  static List<String> _listDate;
public int index;
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;

public ExpandableListAdapterForRunning(Context context, List<String> listDataHeader,
        HashMap<String, List<String>> listChildData,int i,List<String> listDate) {
     this._context = context;
    this._listDataHeader = listDataHeader;
    this._listDataChild = listChildData;
    this.index=i;
    this._listDate=listDate;
}

@Override
public Object getChild(int groupPosition, int childPosititon) {
    return this._listDataChild.get(this._listDataHeader.get(groupPosition))
            .get(childPosititon);
}

//other overridden methods
}    

Теперь есть еще один class RunningCase.java который extends Activity. Этот class используется для заполнения данных в ExpandableListView. OnLongClick() (нажмите и удерживайте) любой группы в ExpandableListView, появится context menu. context menu содержит параметр Удалить, чтобы удалить это дело из базы данных и обновить файл RunningCase activity.

    public class RunningCase extends Activity

    {
    String[] day;
    LinearLayout layout_MainMenu;
    Case cases;
    ExpandableListAdapterForRunning listAdapter;
    ExpandableListView expListView;
    List<String> listDataHeader;
    List<String> listDate;
     HashMap<String, List<String>> listDataChild;    
    Case date;

protected void onCreate(Bundle savedInstanceState) {
    prepareListData();     
    expListView=(ExpandableListView) findViewById(R.id.lvExp);
    listAdapter= new  ExpandableListAdapterForRunning(this,listDataHeader,listDataChild,i,listDate);
    expListView.setAdapter(listAdapter);
    registerForContextMenu(expListView);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.add("Delete");
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    // TODO Auto-generated method stub
    super.onContextItemSelected(item);
    final DatabaseHandler dbs = new DatabaseHandler(this);
    Cursor c = null;
    ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) item
            .getMenuInfo();

    int type = ExpandableListView.getPackedPositionType(info.packedPosition);
    int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition);

    if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
          String cp=(String) listAdapter.getChild(groupPosition, 0);
        caseno=cp.substring(11, cp.length());       
        }

    if(item.getTitle()=="Delete")
    {       
        dbs.deletecase(caseno);
        expListView.post(new Runnable() {
            public void run() {
            listAdapter.notifyDataSetChanged();  //this is not working
            }
        });
        Toast.makeText(this, "The Case has been Deleted.", Toast.LENGTH_LONG).show();
    }
 return true;
}
//this is the method to populate the expandableListView
public void prepareListData() {
    listDataHeader = new ArrayList<String>();
    listDate =new ArrayList<String>();
    listDataChild = new HashMap<String, List<String>>();
    final DatabaseHandler db = new DatabaseHandler(this);
    List<Case> cases = db.getRunning();       
    int i=0;
    for (Case cn : cases) {
        String str = cn.getPetitioner()+" V/S " + cn.getDefendant();
        String caseNo=cn.getCaseNumber();
        String caseStage=cn.getCaseStage();
        String caseName=cn.getCourtName();
        listDataHeader.add(str);
        List<String> case2 = new ArrayList<String>();
        case2.add("Case No. : "+caseNo);
        case2.add("Court Name :"+caseName);
        case2.add("Case Stage :"+caseStage);

        listDataChild.put(listDataHeader.get(i++), case2);

    }
       List<Date> date = db.getRunning_child();       
       for (Date cn : date) {
           String str = cn.getNextDate();
           listDate.add(str);
    }
}

Методы db.getRunning(), db.getRunning_child() извлекают данные из базы данных. Кроме того, ниже приведен код для удаления случая из базы данных, который отлично работает:

void deletecase(String casenum){
    SQLiteDatabase db = this.getWritableDatabase();
    String whereClause = "Case_number = ?";
    String[] whereArgs = new String[] {
            casenum
        };

    db.delete(TABLE_CASEINFO,whereClause,whereArgs);        
    db.delete(TABLE_CLIENTINFO,whereClause,whereArgs);      
    db.delete(TABLE_DATEINFO,whereClause,whereArgs);        
        Log.d("case deleted","casenum: "+casenum); 

    db.close(); // Closing database connection      
}

Пожалуйста, помогите мне. activity должно обновляться при удалении дела, чтобы удаленное дело больше не появлялось. Заранее спасибо!!


person ankul09jain    schedule 14.03.2014    source источник
comment
вы удаляете запись из БД, но не удаляете ее из списка. вы должны изменить свою процедуру длинных кликов   -  person mangusta    schedule 14.03.2014
comment
Как мне удалить его из списка? Не могли бы вы помочь мне с кодом   -  person ankul09jain    schedule 14.03.2014


Ответы (1)


Перед вызовом notfifyDataSetChanged вы должны обновить свои данные, которые являются приватными HashMap> _listDataChild методом setData, который создан вами на вашем адаптере. Сначала установите данные, затем уведомите.

Пример:

public class MyAdapter extends BaseAdapter {

public MyAdapter(...) {
    super(...);
}

@Override
public View getView(int position, View view, ViewGroup parent) {
    .....
    return view;

}

private void setData() {
    ...
   notifyDataSetChanged();
}
}
person MSr    schedule 14.03.2014
comment
Это означает, что я должен вызвать метод prepareListData() перед вызовом notifyDataSetChanged()? - person ankul09jain; 14.03.2014
comment
@ ankul09jain Я так не думаю. Вы должны обновить данные в вашем адаптере. При первом создании экземпляра адаптера вы отправляете некоторые данные в адаптер с помощью конструктора. prepareListData() не может его обновить. - person MSr; 14.03.2014
comment
Спасибо @MSr. Я добавил следующие строки перед вызовом notifyDataSetChanged(), и это сработало: listDataHeader.remove(groupPosition); listDate.remove (groupPosition); for(int j=0;j‹listDataHeader.size();j++) listDataChild.remove(listDataHeader.get(j)); - person ankul09jain; 15.03.2014
comment
Добавление приведенных выше строк кода работает впервые. Но когда я постоянно удаляю другой случай, возникает NullPoiinterException в getChildPosition() в методе getChild() ExpandableListAdapterForRunning.java. Пожалуйста, скажите мне, где я ошибаюсь - person ankul09jain; 24.03.2014