All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.holoeverywhere.widget.ListView Maven / Gradle / Ivy

There is a newer version: 1.6.8
Show newest version

package org.holoeverywhere.widget;

import org.holoeverywhere.IHoloActivity;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build.VERSION;
import android.util.AttributeSet;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.Checkable;
import android.widget.ListAdapter;

import com.actionbarsherlock.internal.view.menu.ContextMenuBuilder.ContextMenuInfoGetter;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

public class ListView extends android.widget.ListView implements
        ContextMenuInfoGetter {
    public interface MultiChoiceModeListener extends ActionMode.Callback {
        public void onItemCheckedStateChanged(ActionMode mode, int position,
                long id, boolean checked);
    }

    protected class MultiChoiceModeWrapper implements MultiChoiceModeListener {
        protected MultiChoiceModeListener wrapped;

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            if (wrapped == null) {
                return false;
            }
            return wrapped.onActionItemClicked(mode, item);
        }

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            if (wrapped == null) {
                return false;
            }
            if (wrapped.onCreateActionMode(mode, menu)) {
                setLongClickable(false);
                return true;
            }
            return false;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            if (wrapped == null) {
                return;
            }
            wrapped.onDestroyActionMode(mode);
            actionMode = null;
            clearChoices();
            checkedItemCount = 0;
            updateOnScreenCheckedViews();
            invalidateViews();
            setLongClickable(true);
            requestLayout();
            invalidate();
        }

        @Override
        public void onItemCheckedStateChanged(ActionMode mode, int position,
                long id, boolean checked) {
            if (wrapped == null) {
                return;
            }
            wrapped.onItemCheckedStateChanged(mode, position, id, checked);
            if (checkedItemCount == 0) {
                mode.finish();
            }
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            if (wrapped == null) {
                return false;
            }
            return wrapped.onPrepareActionMode(mode, menu);
        }

        public void setWrapped(MultiChoiceModeListener wrapped) {
            this.wrapped = wrapped;
        }
    }

    private class OnItemLongClickListenerWrapper implements
            OnItemLongClickListener {
        protected OnItemLongClickListener wrapped;

        @Override
        public boolean onItemLongClick(AdapterView view, View child,
                int position, long id) {
            boolean handled = doLongPress(child, position, id);
            if (!handled) {
                if (wrapped != null) {
                    if (wrapped.onItemLongClick(view, child, position, id)) {
                        return true;
                    }
                }
                contextMenuInfo = createContextMenuInfo(view, position, id);
                handled = ListView.super.showContextMenuForChild(ListView.this);
                if (handled) {
                    performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
                    return true;
                }
            }
            return false;
        }
    }

    public static final int CHOICE_MODE_MULTIPLE_MODAL = AbsListView.CHOICE_MODE_MULTIPLE_MODAL;
    private ActionMode actionMode;
    private int checkedItemCount;
    private int choiceMode;
    private final MultiChoiceModeWrapper choiceModeListener = new MultiChoiceModeWrapper();
    private ContextMenuInfo contextMenuInfo;
    private IHoloActivity holoActivity;
    private final OnItemLongClickListenerWrapper longClickListenerWrapper = new OnItemLongClickListenerWrapper();

    public ListView(Context context) {
        super(context);
        init(context);
    }

    public ListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public ListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    protected ContextMenuInfo createContextMenuInfo(View view, int position,
            long id) {
        return new AdapterContextMenuInfo(view, position, id);
    }

    protected boolean doLongPress(final View child,
            final int longPressPosition, final long longPressId) {
        if (choiceMode == ListView.CHOICE_MODE_MULTIPLE_MODAL) {
            if (actionMode == null
                    && (actionMode = startActionMode(choiceModeListener)) != null) {
                setItemChecked(longPressPosition, true);
                performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
            }
            return true;
        }
        return false;
    }

    public final IHoloActivity getBase() {
        return holoActivity;
    }

    @Override
    public int getChoiceMode() {
        return choiceMode;
    }

    @Override
    public ContextMenuInfo getContextMenuInfo() {
        return contextMenuInfo;
    }

    protected void init(Context context) {
        super.setOnItemLongClickListener(longClickListenerWrapper);
        if (context instanceof IHoloActivity) {
            holoActivity = (IHoloActivity) context;
        }
    }

    @Override
    public boolean performItemClick(View view, int position, long id) {
        if (choiceMode == ListView.CHOICE_MODE_MULTIPLE_MODAL) {
            boolean newValue = !getCheckedItemPositions().get(position);
            setItemChecked(position, newValue);
            if (actionMode != null) {
                choiceModeListener.onItemCheckedStateChanged(actionMode,
                        position, id, newValue);
            }
            return true;
        }
        return super.performItemClick(view, position, id);
    }

    public final void setBase(IHoloActivity mBase) {
        holoActivity = mBase;
    }

    @Override
    public void setChoiceMode(int choiceMode) {
        if (this.choiceMode == choiceMode) {
            return;
        }
        this.choiceMode = choiceMode;
        if (actionMode != null) {
            actionMode.finish();
            actionMode = null;
        }
        if (choiceMode == ListView.CHOICE_MODE_MULTIPLE_MODAL) {
            super.setOnItemLongClickListener(longClickListenerWrapper);
            clearChoices();
            checkedItemCount = 0;
            setLongClickable(true);
            updateOnScreenCheckedViews();
            requestLayout();
            invalidate();
            super.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
        } else {
            super.setChoiceMode(choiceMode);
        }
    }

    @Override
    public void setItemChecked(int position, boolean value) {
        if (choiceMode == ListView.CHOICE_MODE_MULTIPLE_MODAL) {
            if (value && actionMode == null) {
                actionMode = startActionMode(choiceModeListener);
            }
            super.setItemChecked(position, value);
            checkedItemCount += value ? 1 : -1;
            if (actionMode != null) {
                ListAdapter adapter = getAdapter();
                if (adapter != null) {
                    choiceModeListener.onItemCheckedStateChanged(actionMode,
                            position, adapter.getItemId(position), value);
                }
            }
            requestLayout();
            invalidate();
        } else {
            super.setItemChecked(position, value);
        }
    }

    public void setMultiChoiceModeListener(MultiChoiceModeListener listener) {
        choiceModeListener.setWrapped(listener);
    }

    @Override
    public void setOnItemLongClickListener(OnItemLongClickListener listener) {
        longClickListenerWrapper.wrapped = listener;
    }

    public ActionMode startActionMode(ActionMode.Callback callback) {
        if (actionMode != null) {
            return actionMode;
        }
        if (holoActivity != null) {
            actionMode = holoActivity.startActionMode(callback);
        } else {
            throw new RuntimeException(
                    "ListView must have SBase (setSBase(SBase))");
        }
        return actionMode;
    }

    @SuppressLint("NewApi")
    private void updateOnScreenCheckedViews() {
        final int firstPos = getFirstVisiblePosition();
        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            final int position = firstPos + i;
            boolean state = getCheckedItemPositions().get(position);
            if (child instanceof Checkable) {
                ((Checkable) child).setChecked(state);
            } else if (VERSION.SDK_INT >= 11) {
                child.setActivated(state);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy