Android 如何使用自定义ArrayAdapter跟踪自定义ListView中的项目检查?

Android 如何使用自定义ArrayAdapter跟踪自定义ListView中的项目检查?,android,checkbox,android-listview,android-arrayadapter,Android,Checkbox,Android Listview,Android Arrayadapter,我的堆栈真的溢出了,我的意思是,目前我的大脑无法想出解决以下问题的方法(尽管我已经经历了很多天的反复试验)。我只想做一个删除的sreen,比如() 我有如下列表视图项的布局(log_view.xml): 这是我的自定义适配器: class LogViewAdapter extends ArrayAdapter<Log> { public ArrayList<Boolean> checkList; private int layoutResour

我的堆栈真的溢出了,我的意思是,目前我的大脑无法想出解决以下问题的方法(尽管我已经经历了很多天的反复试验)。我只想做一个删除的sreen,比如()

我有如下列表视图项的布局(log_view.xml):


这是我的自定义适配器:

class LogViewAdapter extends ArrayAdapter<Log>  {   
    public ArrayList<Boolean> checkList;
    private int layoutResourceId;
    private List<Log> logList;

    Context context;

    public LogViewAdapter(Context context, int layoutResourceId, List<Log> data) {
        super(context, R.layout.log_view, data);

        this.layoutResourceId = layoutResourceId;
        this.logList = data;
        this.context = context;

        checkList = new ArrayList<Boolean>();
        for (int i = 0; i < logList.size(); i ++)   {
            checkList.add(false);
        }
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        LogHolder logholder = null;

        // Unidentified view            
        if(convertView == null) {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            convertView = inflater.inflate(layoutResourceId, parent, false);

            // Create a new holder
            logholder = new LogHolder();

            logholder.del_box = (CheckBox)convertView.findViewById(R.id.del_box);
            logholder.del_box.setChecked(false);

            final int iFinal = position;
            logholder.del_box.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    checkList.set(iFinal, buttonView.isChecked());
                }
            });

            logholder.date_view = (TextView)convertView.findViewById(R.id.date_view);
            logholder.value_view = (TextView)convertView.findViewById(R.id.value_view);

            convertView.setTag(logholder);
        }

        // Identified view
        else    {
            logholder = (LogHolder) convertView.getTag();
        }

        if (null != logList)    {
            if (null == checkList.get(position))    {
                android.util.Log.e("getView", "Checklist null at " + position);
            }

            //logholder.del_box.setChecked((boolean)checkList.get(position));
            logholder.date_view.setText(logList.get(position).date);
            logholder.value_view.setText(logList.get(position).value);
        }

        android.util.Log.e("getView", " at " + position + ", value = " + logholder.value_view.getText().toString());
        return convertView;
    }

    static class LogHolder  {
        TextView date_view;
        TextView value_view;
        CheckBox del_box;
    }
}
class LogViewAdapter扩展了ArrayAdapter{
公共阵列列表检查表;
私人内部布局资源;
私有列表日志列表;
语境;
公共LogViewAdapter(上下文上下文、内部布局资源ID、列表数据){
super(上下文、R.layout.log_视图、数据);
this.layoutResourceId=layoutResourceId;
this.logList=数据;
this.context=上下文;
检查表=新的ArrayList();
对于(int i=0;i
以下是我的活动:

public class LoggingActivity extends Activity   {

    //private EditText edt_name;
    //private EditText edt_value;
    private List<Log> logList;
    private LogViewAdapter lw_adapter;
    private ListView listView;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.log_list);
        //setContentView(android.R.layout.simple_list_item_multiple_choice);

        logList = loadLog();
        listView = (ListView)findViewById(R.id.log_list);

        lw_adapter = new LogViewAdapter(this, R.layout.log_view, logList);
        //lw_adapter = new LogViewAdapter(this, android.R.layout.simple_list_item_multiple_choice, logList);

        listView.setAdapter(lw_adapter);
    }

    /** implements for the MENU soft-key. Android 2.3.x */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.layout.log_menu, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // IMPORTANT: listView.getChildAt(index) will only return the
        // VISIBLE views in our current screen
        if (null == listView)   {
            android.util.Log.e("onOptionsItemSelected", "list view null");
            return true;
        }

        for (int i = 0; i < listView.getChildCount(); i++) {
            if (null == listView.getChildAt(i)) continue;

            CheckBox cb = (CheckBox) listView.getChildAt(i).findViewById(R.id.del_box);
            if (null == cb) {
                android.util.Log.e("CB", "CheckBox at i = " + i + " null");
                return true;
            }

            final int iFinal = i + listView.getFirstVisiblePosition();
            cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    listView.setItemChecked(iFinal, buttonView.isChecked());
                    lw_adapter.checkList.set(iFinal, buttonView.isChecked());
                }
            });

            SparseBooleanArray selectedItems = listView.getCheckedItemPositions();

            for (int j = 0; j < selectedItems.size(); j++) {
                if (selectedItems.get(j)) {
                    android.util.Log.e("CHECKED", "Row "+ j + ", value = " + logList.get(j).value);
                }

                else    {
                    android.util.Log.e("CHECKED", "Row "+ j + " not checked");
                }
            }

            cb.setVisibility(View.VISIBLE);
            cb.setEnabled(true);
        }

        File folder = new File(Environment.getExternalStorageDirectory(), "50802566/logs");

        // Handle item selection
        switch (item.getItemId()) {
            case R.id.log_sort:
                Collections.sort(logList, Log.COMPARE_BY_VALUE);
                lw_adapter.notifyDataSetChanged();

                return true;
            case R.id.log_del:
                for (int i = 0; i < logList.size(); i++) {
                    if (null == lw_adapter.checkList.get(i))    {
                        android.util.Log.e("DEL", "checklist["+ i + "] = null");
                        continue;
                    }

                    if (true == lw_adapter.checkList.get(i)) {
                        // Delete correlative xml file
                        Date date = null;
                        try {
                            date = new SimpleDateFormat("dd/MM/yyyy - HH:mm:ss").parse(logList.get(i).date);
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }

                        String filename = new SimpleDateFormat("dd_MM_yyyy - HH_mm_ss").format(date) + ".xml";
                        File toDelete = new File(folder, filename);
                        if (!toDelete.delete()) {
                            android.util.Log.e("DEL", "File " + filename + ": not deleted or not existed");
                        }

                        // Update the UI
                        //lw_adapter.remove(logList.get(i));
                        //lw_adapter.checkList.remove(i);

                        logList.set(i, null);
                        lw_adapter.checkList.set(i, null);
                        android.util.Log.e("DEL", "Deleted " + i + ", size now = " + logList.size());
                    }  
                }

                for (int i = 0; i < logList.size(); i ++)   {
                    if (null == logList.get(i)) {
                        logList.remove(i);
                        lw_adapter.checkList.remove(i);
                    }
                }

                lw_adapter.notifyDataSetChanged();

                // Refresh the checklist
                for (int i = 0; i < lw_adapter.checkList.size(); i ++)  {
                    lw_adapter.checkList.set(i, false);
                }

                for (int i = 0; i < listView.getChildCount(); i++) {
                    if (null == listView.getChildAt(i)) continue;
                    CheckBox cb = (CheckBox) listView.getChildAt(i).findViewById(R.id.del_box);
                    cb.setChecked(false);
                }

                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private ArrayList<Log> loadLog()    {
        /** Access folder "my_logs" in external memory */
        File baseDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
                                File.separator +
                                "50802566/logs");
        if (!baseDir.exists())  {   baseDir.mkdirs();   }
        File[] list_file = baseDir.listFiles();

        /** For internal memory */
        //File[] list_file = this.getFilesDir().listFiles();

        for (int i = 0; i < list_file.length; i ++) {
            //android.util.Log.e("PRINTLN", list_file[i].getPath());
        }

        int l = list_file.length;

        ArrayList<Log> list = new ArrayList<Log>();

        while (l-- > 0) {
            File file = list_file[l];

            FileInputStream fin = null;
            LogReader logr = new LogReader();

            try {
                fin = new FileInputStream(file);
                list.add(list_file.length - l - 1, logr.read(fin));
                fin.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (XmlPullParserException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return list;
    }
}
公共类日志活动扩展了活动{
//私有编辑文本edt_名称;
//私有编辑文本edt_值;
私有列表日志列表;
专用LogViewAdapter lw_适配器;
私有列表视图列表视图;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.log_列表);
//setContentView(android.R.layout.simple\u list\u item\u多选);
logList=loadLog();
listView=(listView)findViewById(R.id.log\u列表);
lw_adapter=新的LogViewAdapter(这个,R.layout.log_视图,logList);
//lw_adapter=新的LogViewAdapter(这个,android.R.layout.simple_list_item_多选,logList);
setAdapter(lw_适配器);
}
/**实现菜单软键。Android 2.3.x*/
@凌驾
公共布尔onCreateOptions菜单(菜单){
MenuInflater充气机=getMenuInflater();
充气机。充气(R.layout.log_菜单,菜单);
返回true;
}
@凌驾
公共布尔值onOptionsItemSelected(菜单项项){
//重要提示:listView.getChildAt(索引)将只返回
//当前屏幕中的可见视图
if(null==listView){
android.util.Log.e(“onOptionsItemSelected”,“列表视图null”);
返回true;
}
对于(int i=0;ipublic class LoggingActivity extends Activity   {

    //private EditText edt_name;
    //private EditText edt_value;
    private List<Log> logList;
    private LogViewAdapter lw_adapter;
    private ListView listView;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.log_list);
        //setContentView(android.R.layout.simple_list_item_multiple_choice);

        logList = loadLog();
        listView = (ListView)findViewById(R.id.log_list);

        lw_adapter = new LogViewAdapter(this, R.layout.log_view, logList);
        //lw_adapter = new LogViewAdapter(this, android.R.layout.simple_list_item_multiple_choice, logList);

        listView.setAdapter(lw_adapter);
    }

    /** implements for the MENU soft-key. Android 2.3.x */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.layout.log_menu, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // IMPORTANT: listView.getChildAt(index) will only return the
        // VISIBLE views in our current screen
        if (null == listView)   {
            android.util.Log.e("onOptionsItemSelected", "list view null");
            return true;
        }

        for (int i = 0; i < listView.getChildCount(); i++) {
            if (null == listView.getChildAt(i)) continue;

            CheckBox cb = (CheckBox) listView.getChildAt(i).findViewById(R.id.del_box);
            if (null == cb) {
                android.util.Log.e("CB", "CheckBox at i = " + i + " null");
                return true;
            }

            final int iFinal = i + listView.getFirstVisiblePosition();
            cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    listView.setItemChecked(iFinal, buttonView.isChecked());
                    lw_adapter.checkList.set(iFinal, buttonView.isChecked());
                }
            });

            SparseBooleanArray selectedItems = listView.getCheckedItemPositions();

            for (int j = 0; j < selectedItems.size(); j++) {
                if (selectedItems.get(j)) {
                    android.util.Log.e("CHECKED", "Row "+ j + ", value = " + logList.get(j).value);
                }

                else    {
                    android.util.Log.e("CHECKED", "Row "+ j + " not checked");
                }
            }

            cb.setVisibility(View.VISIBLE);
            cb.setEnabled(true);
        }

        File folder = new File(Environment.getExternalStorageDirectory(), "50802566/logs");

        // Handle item selection
        switch (item.getItemId()) {
            case R.id.log_sort:
                Collections.sort(logList, Log.COMPARE_BY_VALUE);
                lw_adapter.notifyDataSetChanged();

                return true;
            case R.id.log_del:
                for (int i = 0; i < logList.size(); i++) {
                    if (null == lw_adapter.checkList.get(i))    {
                        android.util.Log.e("DEL", "checklist["+ i + "] = null");
                        continue;
                    }

                    if (true == lw_adapter.checkList.get(i)) {
                        // Delete correlative xml file
                        Date date = null;
                        try {
                            date = new SimpleDateFormat("dd/MM/yyyy - HH:mm:ss").parse(logList.get(i).date);
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }

                        String filename = new SimpleDateFormat("dd_MM_yyyy - HH_mm_ss").format(date) + ".xml";
                        File toDelete = new File(folder, filename);
                        if (!toDelete.delete()) {
                            android.util.Log.e("DEL", "File " + filename + ": not deleted or not existed");
                        }

                        // Update the UI
                        //lw_adapter.remove(logList.get(i));
                        //lw_adapter.checkList.remove(i);

                        logList.set(i, null);
                        lw_adapter.checkList.set(i, null);
                        android.util.Log.e("DEL", "Deleted " + i + ", size now = " + logList.size());
                    }  
                }

                for (int i = 0; i < logList.size(); i ++)   {
                    if (null == logList.get(i)) {
                        logList.remove(i);
                        lw_adapter.checkList.remove(i);
                    }
                }

                lw_adapter.notifyDataSetChanged();

                // Refresh the checklist
                for (int i = 0; i < lw_adapter.checkList.size(); i ++)  {
                    lw_adapter.checkList.set(i, false);
                }

                for (int i = 0; i < listView.getChildCount(); i++) {
                    if (null == listView.getChildAt(i)) continue;
                    CheckBox cb = (CheckBox) listView.getChildAt(i).findViewById(R.id.del_box);
                    cb.setChecked(false);
                }

                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private ArrayList<Log> loadLog()    {
        /** Access folder "my_logs" in external memory */
        File baseDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
                                File.separator +
                                "50802566/logs");
        if (!baseDir.exists())  {   baseDir.mkdirs();   }
        File[] list_file = baseDir.listFiles();

        /** For internal memory */
        //File[] list_file = this.getFilesDir().listFiles();

        for (int i = 0; i < list_file.length; i ++) {
            //android.util.Log.e("PRINTLN", list_file[i].getPath());
        }

        int l = list_file.length;

        ArrayList<Log> list = new ArrayList<Log>();

        while (l-- > 0) {
            File file = list_file[l];

            FileInputStream fin = null;
            LogReader logr = new LogReader();

            try {
                fin = new FileInputStream(file);
                list.add(list_file.length - l - 1, logr.read(fin));
                fin.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (XmlPullParserException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return list;
    }
}
@Override
    public void onCheckedChanged(CompoundButton cb, boolean isChecked) {
        int graphicalPos = -1;

        // This is top view on the screen for sure
        if (((View)cb.getParent()).getTop() < 0)    {
            graphicalPos = 0;
        }

        else if (((View)cb.getParent()).getTop() == 0)  {
            graphicalPos = (int) (((View)cb.getParent()).getTop() / ((View)cb.getParent()).getHeight());
        }

        else if (((View)cb.getParent()).getTop() > 0)   {
            graphicalPos = (int) (((View)cb.getParent()).getTop() / ((View)cb.getParent()).getHeight());
            if (listView.getChildAt(0).getTop() < 0)    {
                graphicalPos = graphicalPos + 1;
            }

            else    {
                android.util.Log.e("NOT PLUS", "First Top = " + listView.getChildAt(0).getTop());
            }
        }

        int dataPos = graphicalPos + listView.getFirstVisiblePosition();

        lw_adapter.checkList.set(dataPos, isChecked);
        android.util.Log.e("onCheckedChanged", "Checked row " + dataPos + ", graphicalPos = " + graphicalPos + ", top = " + ((View)cb.getParent()).getTop() + ", firstVisible = " + listView.getFirstVisiblePosition());
    }