listView中带有复选框的自定义布局:当我删除一行时,如果选中它(checkBox = true),则下一行将获得检查

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了listView中带有复选框的自定义布局:当我删除一行时,如果选中它(checkBox = true),则下一行将获得检查相关的知识,希望对你有一定的参考价值。

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

我有几行,第二行检查第三未检查。我删除第二行,然后第三行(现在是第二行)被检查...我不希望删除后检查它。

我在onContextItemSelected()的Activity代码中删除了。

适配器代码:

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

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

另一答案

更新:

主要是我认为这个问题只是一个常规的编程问题,不是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给出了一个很好的答案。另一种解决方案是在用户检查/取消选中时立即保存复选框状态,并在从持有者处获取该复选框时读取该复选框的状态。更多的工作,但如果您的chekbox状态应该在方向更改后存活,或者如果您想要在应用程序被杀死后恢复状态,这是可行的方法。

另一答案

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方法将setState值设置为0,并且当你选中复选框然后setState值通过调用相同的setter方法并在适配器中调用notifyDatasetChanged()方法来实现1,并且您必须在适配器中执行所有代码...

3)所以,现在当你想要从list-view中删除任何列表项时,程序将是LIKE:首先,当你点击list-item时你将获得位置,而不是你需要获得该位置的类形式arraylist从ArrayList中删除它,并再次调用Adapter中的notifyDatasetChanged()方法。

另一答案

经过一番调查后我发现了问题:

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

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

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

非常感谢所有想要帮助的人!非常感激!

以上是关于listView中带有复选框的自定义布局:当我删除一行时,如果选中它(checkBox = true),则下一行将获得检查的主要内容,如果未能解决你的问题,请参考以下文章

ListView 中的自定义复选框

每个项目中带有 Switch 和 TextView 的自定义 ListView

android中每行中带有添加和删除按钮的ListView

Android中项目的自定义ListView点击问题

自定义ListView的RelativeLayout中的Android布局居中

带有复选框的自定义 ListView 检查未选中的项目