BaseExpandableListAdapter notifyDataSetChanged()错误

时间:2013-11-07 02:09:30

标签: android notifydatasetchanged

我查看了大量信息,但未找到正确的解决方案。

我的代码:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.safety.Whitelist;
import org.jsoup.select.Elements;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.TextView;
import android.widget.Toast;

public class ExpandableListAdapter extends BaseExpandableListAdapter {

    MyPointsDB db;

    ArrayList<String> arr_book_title = new ArrayList<String>();
    ArrayList<String> arr_book_href = new ArrayList<String>();
    String selGroupParam;
    String selItemParam;
    public static String PACKAGE_NAME;
    File directory;
    String directory_string;    

    private Context _context;
    private List<String> _listDataHeader; // header titles
    private List<String> _paramDataHeader;
    // child data in format of header title, child title
    private HashMap<String, List<String>> _listDataChild;
    private List<String> _paramDataChild;

    AlertDialog dialog; 


    public ExpandableListAdapter(Context context, List<String> listDataHeader, List<String> paramDataHeader, HashMap<String, List<String>> listChildData, List<String> paramChildData) {
        this._context = context;
        this._listDataHeader = listDataHeader;
        this._paramDataHeader = paramDataHeader;
        this._listDataChild = listChildData;
        this._paramDataChild = paramChildData;
        //PACKAGE_NAME = _context.getPackageName();
        this.db = new MyPointsDB(_context);
    }


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

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    public String getChildParam(int groupPosition, int childPosition) {
        return _paramDataChild.get(childPosition).toString();
    }    

    @Override
    public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final String childText = (String) getChild(groupPosition, childPosition);

        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.list_item, null);
        }

        TextView txtListChild = (TextView) convertView.findViewById(R.id.lblListItem);
        txtListChild.setTag(_paramDataChild.get(childPosition).toString());
        txtListChild.setText(childText);

        Button btnItem = (Button) convertView.findViewById(R.id.iconShowParamItem);
        btnItem.setTag(_paramDataChild.get(childPosition).toString());
        btnItem.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                selItemParam = view.getTag().toString().trim();
                final CharSequence[] items = {_context.getString(R.string.operation_del_book)};

                AlertDialog.Builder builder = new AlertDialog.Builder(_context);
                builder.setItems(items, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int item) {

                        String[] separated = selItemParam.split(";");
                        String url_base = separated[1];

                        // Delete book
                        if (items[item] == _context.getString(R.string.operation_del_book)) {
                            new AlertDialog.Builder(_context)
                            .setTitle(R.string.alert_del_book_caption)
                            .setMessage(R.string.alert_del_book_message)
                            .setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    String[] separated = selItemParam.split(";");
                                    String _id = separated[0];                                  
                                    db.deleteBOOKid(_id);
                                    //Toast.makeText(_context, selItemParam, Toast.LENGTH_LONG).show();
                                    //refreshList();
                                    //Toast.makeText(_context, _context.getString(R.string.operation_del_book), Toast.LENGTH_SHORT).show();
                                }
                            })
                            .setNegativeButton(R.string.button_cancel,
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                        }
                                    }).show();                          
                        }                       
                    }
                });
                AlertDialog alert = builder.create();
                alert.show();               
            }
        }); 

        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition)).size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return this._listDataHeader.get(groupPosition);
    }

    @Override
    public int getGroupCount() {
        return this._listDataHeader.size();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        String headerTitle = (String) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.list_group, null);
        }

        TextView lblListHeader = (TextView) convertView.findViewById(R.id.lblListHeader);
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle);

        Button btnGroup = (Button) convertView.findViewById(R.id.iconShowParamGroup);
        btnGroup.setTag(_paramDataHeader.get(groupPosition).toString());
        btnGroup.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                //Toast.makeText(_context, "btnGroup", Toast.LENGTH_SHORT).show();
                selGroupParam = view.getTag().toString().trim();
                final CharSequence[] items = {_context.getString(R.string.operation_add_book), _context.getString(R.string.operation_del_autor)};

                AlertDialog.Builder builder = new AlertDialog.Builder(_context);
                builder.setItems(items, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int item) {
                        //Toast.makeText(_context, items[item], Toast.LENGTH_SHORT).show();
                        String[] separated = selGroupParam.split(";");
                        String url_base = separated[1];

                        // Add book
                        if (items[item] == _context.getString(R.string.operation_add_book)) {
                            new selectBookInAutor().execute(url_base);
                        }

                        // Delete book
                        if (items[item] == _context.getString(R.string.operation_del_autor)) {
                            new AlertDialog.Builder(_context)
                            .setTitle(R.string.alert_del_autor_caption)
                            .setMessage(R.string.alert_del_autor_message)
                            .setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    String[] separated = selGroupParam.split(";");
                                    String _id = separated[0];                                  
                                    db.deleteAUTORid(_id);
                                    notifyDataSetChanged();
                                }
                            })
                            .setNegativeButton(R.string.button_cancel,
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                        }
                                    }).show();                          
                        }                       
                    }
                });
                AlertDialog alert = builder.create();
                alert.show();               
            }
        });        

        return convertView;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }



    private class selectBookInAutor extends AsyncTask<String, Void, String> {
        ProgressDialog mProgressDialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            arr_book_title.clear();
            arr_book_href.clear();
            mProgressDialog = new ProgressDialog(_context);
            mProgressDialog.setMessage("Loading...");
            mProgressDialog.setIndeterminate(false);
            mProgressDialog.show();
        }       

        @Override
        protected String doInBackground(String... params) {
            Document doc = null;
            StringBuilder sb = new StringBuilder();
            try {
                doc = Jsoup.connect(params[0]).userAgent("Mozilla").get();
                //Elements links = doc.select("dl>dl>dt>li>a");
                Elements links = doc.select("li>a");
                for (Element link : links) {
                    sb.append(link.text());
                    arr_book_title.add(link.text());
                    arr_book_href.add(Jsoup.clean(link.attr("abs:href"), Whitelist.basic()));
                }

            } catch (IOException e) {
                e.printStackTrace();
            }

            return sb.toString();           
        } 
        @Override
        protected void onPostExecute(String result) {   
            if(!result.equals("")){
                //Toast.makeText(_context, result, Toast.LENGTH_LONG).show();
                final CharSequence[] items = arr_book_title.toArray(new CharSequence[arr_book_title.size()]);

                final ArrayList seletedItems = new ArrayList();
                AlertDialog.Builder builder = new AlertDialog.Builder(_context);
                builder.setTitle("Select The Difficulty Level");
                builder.setMultiChoiceItems(items, null, new DialogInterface.OnMultiChoiceClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) {
                        if (isChecked) {
                            seletedItems.add(indexSelected);
                        }else if(seletedItems.contains(indexSelected)){
                            seletedItems.remove(Integer.valueOf(indexSelected));
                        }
                    }
                }).setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        //Toast.makeText(_context, seletedItems.toString(), Toast.LENGTH_SHORT).show();
                        for (Object s : seletedItems){
                            String[] separated = selGroupParam.split(";");
                            String _idautor = separated[0].toString();                          
                            long id_book = db.insertBOOK(_idautor, arr_book_href.get(Integer.valueOf(s.toString())).toString(), "", arr_book_title.get(Integer.valueOf(s.toString())).toString());
                            new saveBookInAutor().execute(arr_book_href.get(Integer.valueOf(s.toString())).toString(), _idautor, String.valueOf(id_book));
                        }
                        //refreshList();
                    }
                }).setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                    }
                }).create().show();             
            }else{
                Toast.makeText(_context, "Error get book autor", Toast.LENGTH_SHORT).show();
            }
            mProgressDialog.dismiss();
        }
    }    

    private class saveBookInAutor extends AsyncTask<String, Void, String> {
        ProgressDialog mProgressDialog2;
        String _idautor = "", _idbook = "";

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mProgressDialog2 = new ProgressDialog(_context);
            mProgressDialog2.setMessage("Save page...");
            mProgressDialog2.setIndeterminate(false);
            mProgressDialog2.show();
        }       

        @Override
        protected String doInBackground(String... params) {
            Document doc = null;
            String _html = "";
            _idautor = params[1];
            _idbook = params[2];
            try {
                doc = Jsoup.connect(params[0]).userAgent("Mozilla").get();
                _html = doc.select("dd").outerHtml();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return Jsoup.clean(_html, Whitelist.basic());           
        } 
        @Override
        protected void onPostExecute(String result) {   
            if(!result.equals("")){
                Toast.makeText(_context, "Save file", Toast.LENGTH_SHORT).show();
                String html = "<html lang='ru'><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/></head><body>"+result+"</body></html>";
                //String html = result;
                savePageToFile(_idautor + "_" + String.valueOf(_idbook), html);
            }else{
                Toast.makeText(_context, "Error save page", Toast.LENGTH_SHORT).show();
            }
            mProgressDialog2.dismiss();
        }
    }        

    public void refreshList() {
        Intent intent = new Intent(_context, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        _context.startActivity(intent);     
    }

    public void savePageToFile(String filename, String html) {
        try {
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(_context.openFileOutput(filename, Context.MODE_PRIVATE));
            outputStreamWriter.write(html);
            outputStreamWriter.close();
        }
        catch (IOException e) {
            //Log.e("Exception", "File write failed: " + e.toString());
        } 
    }   

    public String readPageFile(String filename) {
        String ret = "";
        try {
            InputStream inputStream = _context.openFileInput(filename);
            if ( inputStream != null ) {
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                String receiveString = "";
                StringBuilder stringBuilder = new StringBuilder();
                while ( (receiveString = bufferedReader.readLine()) != null ) {
                    stringBuilder.append(receiveString);
                }
                inputStream.close();
                ret = stringBuilder.toString();
            }
        }
        catch (FileNotFoundException e) {
            //Log.e("login activity", "File not found: " + e.toString());
        } catch (IOException e) {
            //Log.e("login activity", "Can not read file: " + e.toString());
        }

        return ret;
    }   

}

问题是删除书籍。从数据库中删除书后,我想更新屏幕ExpandableListView。调用notifyDataSetChanged()时会发生此错误。元素不会从屏幕上消失。

我找到了一个解决问题的拐杖:

Intent intent = new Intent(_context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
_context.startActivity(intent);  

但这并不完全正确。

我请求你的帮助。

1 个答案:

答案 0 :(得分:0)

您从数据库中删除该项目,但它仍然存在于您拥有的列表中。删除项目后,您必须更新_listDataHeader列表,然后notifyDataSetChanged。您还应该删除与此项目对应的子项。由于您有许多列表,因此在删除项目时也会更新它们。

.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        String[] separated = selItemParam.split(";");
        String _id = separated[0];
        db.deleteBOOKid(_id);

        //update lists here, and remove the header, child items and anything related..
        // _listDataHeader.remove(groupPosition) // groupPosition should be final
        // etc. etc.

        notifyDataSetChanged();
    } })

为确保数据一致,当您删除某些内容时...也删除其他相关项目..例如:

如果_paramDataChild_paramDataHeader与要删除的项目相关,您可能也想要更新它们......以便它们没有与已删除项目相关的值。 (这取决于你的情况,我只是举个例子)