Android Open Source - CheckListView Check List View






From Project

Back to project page CheckListView.

License

The source code is released under:

Apache License

If you think the Android project CheckListView listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package it.feio.android.checklistview.models;
/*  www  .j a  v a2  s.  c  o  m*/
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.text.Html;
import android.util.Log;
import android.view.DragEvent;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;

import it.feio.android.checklistview.App;
import it.feio.android.checklistview.Settings;
import it.feio.android.checklistview.dragging.ChecklistViewItemOnDragListener;
import it.feio.android.checklistview.dragging.ChecklistViewOnTouchListener;
import it.feio.android.checklistview.interfaces.CheckListChangedListener;
import it.feio.android.checklistview.interfaces.CheckListEventListener;
import it.feio.android.checklistview.interfaces.Constants;
import it.feio.android.pixlui.links.TextLinkClickListener;

@SuppressLint("NewApi")
public class CheckListView extends LinearLayout implements Constants, CheckListEventListener {

  private boolean showDeleteIcon = Constants.SHOW_DELETE_ICON;
  private boolean showHintItem = Constants.SHOW_HINT_ITEM;
  private String newEntryHint = "";
  private int moveCheckedOnBottom = Settings.CHECKED_HOLD;

  private Context mContext;
  private CheckListChangedListener mCheckListChangedListener;
  private TextLinkClickListener mTextLinkClickListener;
  private ChecklistViewItemOnDragListener mChecklistViewItemOnDragListener;


  public CheckListView(Context activity) {
    super(activity);
    this.mContext = activity;
    setTag(Constants.TAG_LIST);
    setOrientation(VERTICAL);
    setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
    if (Build.VERSION.SDK_INT >= 11) {
      mChecklistViewItemOnDragListener = new ChecklistViewItemOnDragListener();
      this.setOnDragListener(mChecklistViewItemOnDragListener);
    }
  }


  /**
   * Declare if a checked item must be moved on bottom of the list or not
   */
  public void setMoveCheckedOnBottom(int moveCheckedOnBottom) {
    this.moveCheckedOnBottom = moveCheckedOnBottom;
  }


  /**
   * Set if show or not a delete icon at the end of the line. Default true.
   */
  public void setShowDeleteIcon(boolean showDeleteIcon) {
    this.showDeleteIcon = showDeleteIcon;
  }


  /**
   * Set if an empty line on bottom of the checklist must be shown or not
   */
  public void setShowHintItem(boolean showHintItem) {
    this.showHintItem = showHintItem;
  }


  /**
   * Text to be used as hint for the last empty line (hint item)
   */
  public void setNewEntryHint(String hint) {
    setShowHintItem(true);
    this.newEntryHint = hint;
  }


  @SuppressLint("NewApi")
  @SuppressWarnings("deprecation")
  public void cloneStyles(EditText v) {
    for (int i = 0; i < getChildCount(); i++) {
      getChildAt(i).cloneStyles(v);
    }
  }


  public CheckListViewItem getChildAt(int i) {
    return (CheckListViewItem) super.getChildAt(i);
  }


  public EditText getEditText() {
    EditText res = null;
    CheckListViewItem child = getChildAt(0);
    if (child != null) {
            res = child.getEditText();
        }
    return res;
  }


  @Override
  public void onItemChecked(CheckListViewItem checked, boolean isChecked) {
        if (isChecked) {
            doOnCheck(checked);
        } else {
            doOnUncheck(checked);
        }
  }


    /**
     * If is not selected to HOLD checked items on position then the checked
     * item will be moved on bottom of the list
     */
    private void doOnCheck(CheckListViewItem checked) {
        if (moveCheckedOnBottom != Settings.CHECKED_HOLD) {
            for (int i = 0; i < getChildCount(); i++) {
                if (moveOnChecked(checked, i)) return;
            }
        }
        // Notify something is changed
        if (mCheckListChangedListener != null) {
            mCheckListChangedListener.onCheckListChanged();
        }
    }


    private boolean moveOnChecked(CheckListViewItem checked, int i) {
        if (checked.equals(getChildAt(i))) {

            // If it's on last position yet nothing will be done
            int lastIndex = getChildCount() - 1;
            if (i == lastIndex) {
                Log.v(Constants.TAG, "Not moving item it's the last one");
                return true;
            }

            // Otherwise all items at bottom than the actual will be
            // cycled until a good position is find.
            Log.v(Constants.TAG, "Moving item at position " + i);

            // The newly checked item will be positioned at last position.
            if (moveCheckedOnBottom == Settings.CHECKED_ON_BOTTOM) {
                removeView(checked);
                addView(checked, lastIndex);
                return true;
            }

            // Or at the top of checked ones
            if (moveCheckedOnBottom == Settings.CHECKED_ON_TOP_OF_CHECKED) {
                for (int j = lastIndex; j > i; j--) {
                    if (!getChildAt(j).isChecked()) {
                        removeView(checked);
                        addView(checked, j);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
    * Item has been unchecked and have to be (eventually) moved up
     */
    private void doOnUncheck(CheckListViewItem checked) {
        if (moveCheckedOnBottom != Settings.CHECKED_HOLD) {
            CheckListViewItem line;
            int position = 0;
            for (int i = 0; i < getChildCount(); i++) {
                line = getChildAt(i);
                position = i;
                if (line.isChecked() || line.isHintItem()) {
                    break;
                }
            }
            removeView(checked);
            addView(checked, position);
        }
    }


    @Override
  public void onNewLineItemEdited(CheckListViewItem checkableLine) {
    checkableLine.getCheckBox().setEnabled(true);
    enableDragAndDrop(checkableLine);
    addHintItem();
  }


  @Override
  public void onEditorActionPerformed(CheckListViewItem mCheckListViewItem, int actionId, KeyEvent event) {

    if (actionId != EditorInfo.IME_ACTION_NEXT) {
            return;
        }

    EditTextMultiLineNoEnter v = mCheckListViewItem.getEditText();

    // Text length, start and end selection points, and other derived flags are retrieved
    int textLength = mCheckListViewItem.getText().length();
    int start = v.getSelectionStart();
    int end = v.getSelectionEnd();
    boolean isTextSelected = end != start;
    boolean isTruncating = !isTextSelected && start > 0 && start < textLength;
    int index = indexOfChild(mCheckListViewItem);
    int lastIndex = getChildCount() - 1;
    boolean isLastItem = index == lastIndex;

    // If the "next" ime key is pressed being into the hint item of the list the
    // softkeyboard will be hidden and focus assigned out of the checklist items.
    if (mCheckListViewItem.isHintItem() || isLastItem) {
      InputMethodManager inputManager = (InputMethodManager) mContext
          .getSystemService(Context.INPUT_METHOD_SERVICE);
      inputManager.hideSoftInputFromWindow(mCheckListViewItem.getWindowToken(),
          InputMethodManager.HIDE_NOT_ALWAYS);
      return;
    }

        CheckListViewItem nextItem = getChildAt(index + 1);

    if (newItemIsNeeded(textLength, start, isTextSelected, isTruncating, nextItem)) {
      nextItem.requestFocus();
      nextItem.getEditText().setSelection(0);
      return;
    }

    // The actual and the new one view contents are generated depending
    // on cursor position
    String text = v.getText().toString();
    String oldViewText = isTextSelected ? text.substring(0, start) + text.substring(end, text.length()) : text
        .substring(0, start);
    String newViewText = isTextSelected ? text.substring(start, end) : text.substring(end, text.length());

    // Actual view content is replaced
    v.setText(oldViewText);

    // A new checkable item is eventually created (optionally with text content)
    addItem(newViewText, mCheckListViewItem.isChecked(), index + 1);

    // The new view is focused
    getChildAt(index + 1).requestFocus();
  }


    /*
    * If line is empty a newline will not be created but the focus will be moved on bottom.
  * This must happen also if an empty line is already present under the actual one.
    */
    private boolean newItemIsNeeded(int textLength, int start, boolean isTextSelected, boolean isTruncating, CheckListViewItem nextItem) {
        boolean transposeSomeText = isTextSelected || isTruncating;
        return textLength == 0    // Empty line
                || (nextItem.getText().length() == 0 && !transposeSomeText)
                || (!transposeSomeText && start == 0);
    }


    /**
   * Add a new item into the checklist
   * 
   * @param text
   *            String to be inserted as item text
   */
  public void addItem(String text) {
    addItem(text, false);
  }


  /**
   * Add a new item into the checklist
   * 
   * @param text
   *            String to be inserted as item text
   */
  public void addItem(String text, boolean isChecked) {
    addItem(text, isChecked, null);
  }


  /**
   * Add a new item into the checklist at specific index
   * 
   * @param text
   *            String to be inserted as item text
   */
  public void addItem(String text, boolean isChecked, Integer index) {
    CheckListViewItem mCheckListViewItem = new CheckListViewItem(mContext, isChecked, showDeleteIcon);
    mCheckListViewItem.cloneStyles(getEditText());
    mCheckListViewItem.setText(text);
    mCheckListViewItem.getEditText().setImeOptions(EditorInfo.IME_ACTION_NEXT);
    mCheckListViewItem.setItemCheckedListener(this);
    // Links recognition
    if (mTextLinkClickListener != null) {
      mCheckListViewItem.getEditText().gatherLinksForText();
      mCheckListViewItem.getEditText().setOnTextLinkClickListener(mTextLinkClickListener);
    }
    // Set text changed listener if is asked to do this
    if (mCheckListChangedListener != null) {
      mCheckListViewItem.setCheckListChangedListener(this.mCheckListChangedListener);
    }
    if (index != null) {
      addView(mCheckListViewItem, index);
    } else {
      addView(mCheckListViewItem);
    }

    // Drag & drop
    enableDragAndDrop(mCheckListViewItem);
  }


  private void enableDragAndDrop(CheckListViewItem mCheckListViewItem) {
    if (Build.VERSION.SDK_INT >= 11 && App.getSettings().getDragEnabled()) {
      mCheckListViewItem.getDragHandler().setOnTouchListener(new ChecklistViewOnTouchListener());
      mCheckListViewItem.setOnDragListener(mChecklistViewItemOnDragListener);
    }
  }


  /**
   * Add a new item to the checklist
   */
  public void addHintItem() {
    CheckListViewItem mCheckListViewItem = new CheckListViewItem(mContext, false, false);
    mCheckListViewItem.cloneStyles(getEditText());
    mCheckListViewItem.setHint(Html.fromHtml("<i>" + newEntryHint + "</i>"));
    mCheckListViewItem.getEditText().setImeOptions(EditorInfo.IME_ACTION_NEXT);
    // Set the checkbox initially disabled
    CheckBox c = mCheckListViewItem.getCheckBox();
    c.setEnabled(false);
    mCheckListViewItem.setCheckBox(c);
    // Attach listener
    mCheckListViewItem.setItemCheckedListener(this);
    // Set text changed listener if is asked to do this
    if (mCheckListChangedListener != null) {
      mCheckListViewItem.setCheckListChangedListener(this.mCheckListChangedListener);
    }

    // Defining position (default last, but if checked items behavior is not HOLD if changes)
    int hintItemPosition = getChildCount();
    if (moveCheckedOnBottom != Settings.CHECKED_HOLD) {
      for (int i = 0; i < getChildCount(); i++) {
        if (getChildAt(i).isChecked()) {
          hintItemPosition = i;
          break;
        }
      }
    }

    // To avoid dropping here the dragged checklist items
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
      mCheckListViewItem.setOnDragListener(new OnDragListener() {
        @Override
        public boolean onDrag(View v, DragEvent event) {
          if (event.getAction() == DragEvent.ACTION_DROP) {
            mChecklistViewItemOnDragListener.onDrag(v, event);
          }
          return true;
        }
      });
    }

    // Add view
    addView(mCheckListViewItem, hintItemPosition);
  }


  private void focusView(View v, int focusDirection) {
    EditTextMultiLineNoEnter focusableEditText = (EditTextMultiLineNoEnter) v.focusSearch(focusDirection);
    if (focusableEditText != null) {
      focusableEditText.requestFocus();
      focusableEditText.setSelection(focusableEditText.getText().length());
    }
  }


  public void setCheckListChangedListener(CheckListChangedListener mCheckListChangedListener) {
    this.mCheckListChangedListener = mCheckListChangedListener;
  }


  @Override
  public void onLineDeleted(CheckListViewItem checkableLine) {
    // Eventually notify something is changed
    mCheckListChangedListener.onCheckListChanged();
  }


  public void setOnTextLinkClickListener(TextLinkClickListener textlinkclicklistener) {
    mTextLinkClickListener = textlinkclicklistener;
  }


  
  @Override
  public boolean dispatchDragEvent(DragEvent ev) {
    boolean r = super.dispatchDragEvent(ev);
    if (r && (ev.getAction() == DragEvent.ACTION_DRAG_STARTED || ev.getAction() == DragEvent.ACTION_DRAG_ENDED)) {
      // If we got a start or end and the return value is true, our
      // onDragEvent wasn't called by ViewGroup.dispatchDragEvent
      // So we do it here.
      onDragEvent(ev);
    }
    return r;
  }

}




Java Source Code List

it.feio.android.checklistview.App.java
it.feio.android.checklistview.ChecklistManager.java
it.feio.android.checklistview.Settings.java
it.feio.android.checklistview.demo.MainActivity.java
it.feio.android.checklistview.demo.SettingsActivity.java
it.feio.android.checklistview.dragging.ChecklistViewDragShadowBuilder.java
it.feio.android.checklistview.dragging.ChecklistViewItemOnDragListener.java
it.feio.android.checklistview.dragging.ChecklistViewOnTouchListener.java
it.feio.android.checklistview.exceptions.ViewNotSupportedException.java
it.feio.android.checklistview.interfaces.CheckListChangedListener.java
it.feio.android.checklistview.interfaces.CheckListEventListener.java
it.feio.android.checklistview.interfaces.Constants.java
it.feio.android.checklistview.interfaces.EditTextEventListener.java
it.feio.android.checklistview.models.CheckListViewItem.java
it.feio.android.checklistview.models.CheckListView.java
it.feio.android.checklistview.models.EditTextMultiLineNoEnter.java
it.feio.android.checklistview.utils.AlphaManager.java
it.feio.android.checklistview.utils.DensityUtil.java