Question

I looked through a lot of information, but have not found the right solution.

My code:

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;
    }   

}

Problem is Delete book. After removal of the book from the database I want to update the screen ExpandableListView. This error occurs when you call the notifyDataSetChanged(). The element does not disappears from the screen.

I found a crutch to solve the problem:

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

But this is not entirely correct.

I ask your help.

Was it helpful?

Solution

You delete the item from the database, but it is still present in the lists that you have. You have to update the _listDataHeader list after you delete the item, and then notifyDataSetChanged. Also you should remove the child which corresponds to this item. Since you have many lists, update them also when an item is deleted.

.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();
    } })

To ensure that data is consistent, when you delete something.. delete other related items too.. for example:

if _paramDataChild and _paramDataHeader are related to the item being deleted, you may want to update them too.. so that they don't have values which relate to the deleted item. (this depends on your scenario, i am just giving an example)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top