代码之家  ›  专栏  ›  技术社区  ›  Andrey Dobrikov

在listView中带有复选框的自定义布局:当我删除选中的行时(checkbox=true),下一行将得到选中

  •  0
  • Andrey Dobrikov  · 技术社区  · 12 年前

    当我删除一行时,如果它是 checked(checkBox = true )下一行得到支票。

    我有几行,第二行检查了第三行未检查。我删除了第二行,然后第三行(现在是第二行)被选中。。。我不想删除后再检查它。

    我在中的活动代码中删除 onContextItemSelected() .

    适配器代码:

    public class TodoAdapter2 extends ArrayAdapter<TodoTask>{
    
        Context context;
        int layoutResourceId;
        ArrayList<TodoTask> data = null;
    
        public TodoAdapter2(Context context, int layoutResourceId, ArrayList<TodoTask> data) {
            super(context, layoutResourceId, data);
            this.layoutResourceId = layoutResourceId;
            this.context = context;
            this.data = data;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View localView = convertView;
            todoHolder tempholder = new todoHolder();
    
            if(localView == null)
            {
                LayoutInflater inflater = ((Activity)context).getLayoutInflater();
                localView = inflater.inflate(layoutResourceId, parent, false);
                tempholder.task = (TextView) localView.findViewById(R.id.txtTodoTitle);
                tempholder.date = (TextView) localView.findViewById(R.id.txtTodoDueDate);
                tempholder.status = (CheckBox) localView.findViewById(R.id.toDoChecked);
                localView.setTag(tempholder);
            }
            else
            {
                tempholder = (todoHolder) localView.getTag();
            }
            final todoHolder holder = tempholder;
    
            final TodoTask currentTask = data.get(position);
            final CheckBox status = (CheckBox) holder.status;
            status.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                changeColorOnCheckBox(holder, status, currentTask);
              }
            });
            if(!holder.status.isChecked()){
              if(isOverdue(currentTask)){
                holder.task.setTextColor(Color.RED);
                holder.date.setTextColor(Color.RED);
            }
            else{
              holder.task.setTextColor(Color.BLACK);
              holder.date.setTextColor(Color.BLACK);
            }
          }
    
          holder.task.setText(currentTask.getTask());
          holder.date.setText(currentTask.toStringDate());
          return localView;
        }
    
        private static boolean isOverdue(TodoTask task){
          int currentDay = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
          int currentMonth = Calendar.getInstance().get(Calendar.MONTH)+1;
          int currentYear = Calendar.getInstance().get(Calendar.YEAR);
          if(task.getYear() < currentYear || task.getMonth() < currentMonth || task.getDay() < currentDay)
            return true;
          return false;
        }
    
        private static void changeColorOnCheckBox(todoHolder holder, CheckBox cb, TodoTask newTask){
          if (cb.isChecked()) {
            holder.task.setTextColor(Color.GREEN);
            holder.date.setTextColor(Color.GREEN);
          }
          else{
            if(isOverdue(newTask)){
              holder.task.setTextColor(Color.RED);
              holder.date.setTextColor(Color.RED);
            }
            else{
              holder.task.setTextColor(Color.BLACK);
              holder.date.setTextColor(Color.BLACK);
            }
          }
        }
    
        class todoHolder{
          CheckBox status;
          TextView task;
          TextView date;
        }
    }
    

    活动代码:

    public class TodoListManagerActivity extends Activity {
        private ArrayList<TodoTask> tasks;
        private ListView list;
        TodoAdapter2 ad;
        final int BROWSER_ACTIVATION_REQUEST = 2; // request code
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            tasks = new ArrayList<TodoTask>();
            setContentView(R.layout.activity_todo_list_manager);
            list = (ListView) findViewById(R.id.lstTodoItems);
            ad = new TodoAdapter2(this, R.layout.todoline_layout, tasks);
            list.setAdapter(ad);
            registerForContextMenu(list);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            //Inflate the menu. this adds items to the action bar if it is present.
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.todo_list_manager_menu, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            //What happens when we click the menu.
            super.onOptionsItemSelected(item);
            if(item.getItemId() == R.id.menuItemAdd){
                Intent intent = new Intent(this, AddNewTodoItemActivity.class); 
                startActivityForResult(intent, BROWSER_ACTIVATION_REQUEST);
            }
            if(item.getItemId() == R.id.menuAbout){
                Toast.makeText(getApplicationContext(), "Made by Andrey Dobrikov", Toast.LENGTH_SHORT).show();
            }
            if(item.getItemId() == R.id.exitMenu){
                finish();
            }
            return true;
        }
    
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v,
                ContextMenuInfo menuInfo) {
            super.onCreateContextMenu(menu, v, menuInfo);
            AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
            int pos = info.position;
            TodoTask curTask = tasks.get(pos);
            String title = curTask.getTask();
            menu.setHeaderTitle(title); //set title for delete menu.
    
            MenuInflater inflater = getMenuInflater();
            if(firstWordCall(title) != -1){
                inflater.inflate(R.menu.context_delete_call, menu);
                MenuItem mi =(MenuItem) menu.findItem(R.id.menuItemCall);
                mi.setTitle(title);
            }
            else{
                inflater.inflate(R.menu.context_delete, menu);
            }
        }
    
        private int firstWordCall(String title) {
            String[] split = title.split(" ",2);
            String firstWord = split[0].toLowerCase();
            if(firstWord.equals("call")){
                String rest = split[1];
                rest = rest.replaceAll("\\s","");
                if(rest.startsWith("-")) return -1;
                rest = rest.replaceAll("-", "");
                if(rest.matches("^[0-9]+")){
                    return Integer.parseInt(rest);
                }
            }
            return -1;
        }
    
        @Override
        public boolean onContextItemSelected(MenuItem item) {
            AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
            int id = info.position;
            if(item.getItemId() == R.id.menuItemDelete){
                String itemToDelete = tasks.get(id).getTask();
                tasks.remove(id);
                ad.notifyDataSetChanged();
                Toast.makeText(getApplicationContext(), "Item: [" + itemToDelete + "] was successfully deleted!", Toast.LENGTH_SHORT).show();
            }
            if(item.getItemId() == R.id.menuItemCall){
                Intent callIntent = new Intent(Intent.ACTION_CALL);
                callIntent.setData(Uri.parse("tel:" + tasks.get(id).getNumber()));
                startActivity(callIntent);
            }
            return super.onContextItemSelected(item);
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent input) {
            // if the results is coming from BROWSER_ACTIVATION_REQUEST 
            String newTask;
            int number = -1;
    
            if (requestCode == BROWSER_ACTIVATION_REQUEST) {
    
                // check the result code set by the activity
                if (resultCode == RESULT_OK) {
                    if(input.hasExtra("Task") && input.getExtras().getString("Task") != null){
                        newTask = input.getExtras().getString("Task");
                        int day = input.getExtras().getInt("Day");
                        int month = input.getExtras().getInt("Month");
                        int year = input.getExtras().getInt("Year");
                        if(newTask.toLowerCase().contains("call")){
                            number = firstWordCall(newTask);
                        }
                        TodoTask todoLine = new TodoTask(day, month, year, newTask, number);
                        newTask += day;
                        newTask += month;
                        newTask += year;
                        tasks.add(todoLine);
                        ad.notifyDataSetChanged();
                    }
                }
            }
        }
    
        @Override
        protected void onResume() {
            super.onResume();
        }
    }
    
    4 回复  |  直到 7 年前
        1
  •  1
  •   Hamid Shatu Hareshkumar Chhelana    12 年前

    首先,取消选中 CheckBox 然后执行行项目的删除。

        2
  •  1
  •   VonSchnauzer    12 年前

    更新:

    主要我认为这个问题只是一个常规的编程问题,而不是针对Android的。其目的是使用SharedPreferences并保存状态。或者将其保存在TodoTask中并从中获取状态。这取决于你。

    您需要的是识别每个复选框的方法。在您的场景中,我会从您的TodoTask中获取id。如果没有,请创建一个,将其附加到TodoTask对象。您可以在创建TodoTask列表时执行此操作。在getView中循环浏览TodoTask列表时

    String anIdForThisCheckbox = data.get(position).getId()
    

    因为每个TodoTask都有相应的复选框。

    在getView()中

    ...
    final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
    boolean isChecked = pref.getBoolean(anIdForThisCheckbox,  false);
    cb.setChecked(isChecked );
     ...
    

    在onClickListener中:

    cb.setOnClickListener(new View.OnClickListener() {
    
        @Override
        public void onClick(View v) {
            Editor editor = pref.edit();
    
            if (cb.isChecked()) {//Selected
                editor.putBoolean(anIdForThisCheckbox, true);//save state 
    
            } else {
                editor.putBoolean(anIdForThisCheckbox, false);
            }
        }
        editor.apply/commit
    });
    ...
    

    旧: 我认为@hamid shatu给出了一个很好的答案。另一种解决方案是,当用户选中/取消选中复选框时,立即保存复选框状态,并在您从持有者处获取该复选框时读取该复选框的状态。更多的工作要做,但如果你的支票箱状态应该能经受住方向改变,或者如果你想在应用程序被关闭后恢复状态,这是一条路。

        3
  •  0
  •   Hamid Shatu Hareshkumar Chhelana    12 年前

    1) 首先,您需要创建一个类来填充listView,该类的元素应该是您希望在列表项中显示的任何元素,并声明一个整数,然后为其生成getter和setter方法LIKE:

    public class Demo{
    
      int state;
    
      public int getState() {
    
        return state;
      }
    
      public void setState(int state) {
    
        this.state = state;
      }
    
    }
    

    2) 然后需要用类的数组列表填充列表视图 ArrayList<Demo> ,当您取消选中复选框时,只需保持单击,而不是通过调用setter方法将State值设置为0,当您选中复选框后,通过调用相同的setter方法并调用 notifyDatasetChanged() 方法, 最重要的是,你必须在适配器中执行所有代码。。。

    3) 因此,现在,当您想要从列表视图中删除任何列表项时,过程将是LIKE: 首先,当您单击列表项时,您将获得位置,然后您必须获得该位置的类表单arraylist并将其从arraylist中删除,然后再次调用Adapter中的notifyDatasetChanged()方法。

        4
  •  0
  •   Andrey Dobrikov    12 年前

    经过进一步调查,我发现了问题:

    在我的适配器代码中: 此代码需要更改:

    final TodoTask currentTask = data.get(position);
    final CheckBox status = (CheckBox) holder.status;
    status.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        changeColorOnCheckBox(holder, status, currentTask);
      }
    });
    

    到此代码:

    final TodoTask currentTask = data.get(position);
    final CheckBox status = (CheckBox) holder.status;
    
    status.setChecked(currentTask.isChecked());
    status.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
            changeColorOnCheckBox(holder, status, currentTask);
        if(status.isChecked()){
            Log.w("----------", "CheckboxT");
        currentTask.setChecked(true);
        }
        else{
            Log.w("----------", "CheckboxF");
        currentTask.setChecked(false);
        }
        }
    });
    

    这将更新正在按下的实际行的复选框。

    非常感谢所有试图帮助的人!非常感谢!