playmusicexporter/framework/src/main/java/de/arcus/framework/utils/SelectionList.java
2015-11-09 21:25:51 +01:00

277 lines
7.8 KiB
Java

/*
* Copyright (c) 2015 David Schulte
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.arcus.framework.utils;
import android.support.annotation.ColorRes;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* Selection list
*/
public abstract class SelectionList<T> {
/**
* The selected items
*/
private List<T> mItems = new ArrayList<>();
/**
* The activity
* We need the activity to show the action mode when some items are selected
*/
private AppCompatActivity mActivity;
/**
* The action mode
*/
private ActionMode mActionMode;
/**
* The callback for the action mode
*/
private ActionMode.Callback mActionModeCallback;
/**
* Flag to not close the activity when action mode is closing
*/
private boolean mDoNotCloseActionMode;
public boolean getDoNotCloseActionMode() { return mDoNotCloseActionMode; }
public void setDoNotCloseActionMode(boolean doNotCloseActionMode) { mDoNotCloseActionMode = doNotCloseActionMode; }
/**
* The colors
*/
private @ColorRes int mResColorNormal;
private @ColorRes int mResColorSelected;
/**
* Gets the activity
* @return Returns the activity
*/
public AppCompatActivity getActivity() {
return mActivity;
}
/**
* Sets the colors of the view.
* Use @SuppressWarnings("ResourceAsColor") to prevent Lint errors
* @param colorNormal Normal state
* @param colorSelected Selected state
*/
public void setColor(@ColorRes int colorNormal, @ColorRes int colorSelected) {
mResColorNormal = colorNormal;
mResColorSelected = colorSelected;
}
/**
* Sets up the action mode for this selection list
* @param activity The activity
*/
public void setupActionMode(AppCompatActivity activity) {
mActivity = activity;
mActionModeCallback = createActionMode(activity);
// Updates the action mode
updateActionModeMenu();
}
/**
* Set the selection state of the item
* @param item The item
* @param state The selection state
*/
public void setSelected(T item, boolean state) {
// Adds the item to the selection list
if (state && !mItems.contains(item))
mItems.add(item);
// Removes the item from the selection list
if (!state && mItems.contains(item))
mItems.remove(item);
// Updates the action mode
updateActionModeMenu();
}
/**
* Set the selection state of the item and change the item background
* @param item The item
* @param state The selection state
* @param view The view
*/
public void setSelected(T item, boolean state, View view) {
// Set the selection state
setSelected(item, state);
if (view != null) {
// Change the background
if (state)
view.setBackgroundColor(ContextCompat.getColor(view.getContext(), mResColorSelected));
else
view.setBackgroundColor(ContextCompat.getColor(view.getContext(), mResColorNormal));
}
}
/**
* Toggles the item
* @param item The selected item
* @return Returns whether the item is now selected
*/
public boolean toggle(T item) {
boolean state = isSelected(item);
setSelected(item, !state);
return !state;
}
/**
* Toggles the item
* @param item The selected item
* @param view The view
* @return Returns whether the item is now selected
*/
public boolean toggle(T item, View view) {
boolean state = isSelected(item);
setSelected(item, !state, view);
return !state;
}
/**
* Gets all selected items
* @return Returns a list with all selected items
*/
public List<T> getSelectedItems() {
return mItems;
}
/**
* Clears the selection
*/
public void clear() {
clear(false);
}
/**
* Clears the selection
* @param doNotCloseActionMode Close the action mode?
*/
public void clear(boolean doNotCloseActionMode) {
mDoNotCloseActionMode = doNotCloseActionMode;
mItems.clear();
// Updates the action mode
updateActionModeMenu();
// Reset the flag
mDoNotCloseActionMode = false;
}
/**
* Clears the action mode
*/
public void clearActionMode() {
mActionMode = null;
}
/**
* Call this after the view was created.
* This will change the background color.
* @param item The selected item
* @param view The view
*/
public void initView(T item, View view) {
// Change the background
if (isSelected(item))
view.setBackgroundColor(ContextCompat.getColor(view.getContext(), mResColorSelected));
else
view.setBackgroundColor(ContextCompat.getColor(view.getContext(), mResColorNormal));
}
/**
* Updates the action mode menu
*/
private void updateActionModeMenu() {
updateActionModeMenu(false);
}
/**
* Updates the action mode menu
* @param doNotCloseActivity Prevent the closing of the activity
*/
private void updateActionModeMenu(boolean doNotCloseActivity) {
// Null check
if (mActionModeCallback != null && mActivity != null && !mActivity.isFinishing()) {
// Some items are selected, shows the action mode
if (mItems.size() > 0 && mActionMode == null) {
mActionMode = mActivity.startSupportActionMode(mActionModeCallback);
}
// Close the action mode
if (mItems.size() == 0 && mActionMode != null) {
// Set mActionMode to null before call finish to prevent recursion
ActionMode actionMode = mActionMode;
mActionMode = null;
// Close the action mode
actionMode.finish();
}
// Set the text
if (mActionMode != null) {
// Update the action mode
mActionMode.invalidate();
}
}
}
/**
* This is called every time a new activity opens.
* This method has to create a action mode callback
* @param activity The new activity
* @return Returns the action mode callback
*/
protected abstract ActionMode.Callback createActionMode(AppCompatActivity activity);
/**
* Gets whether the item is selected
* @param item The selected item
* @return Returns true if the item is selected
*/
public boolean isSelected(T item) {
return mItems.contains(item);
}
}