package com.marvinlabs.widget.floatinglabel.itempicker;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
import com.marvinlabs.widget.floatinglabel.FloatingLabelTextViewBase;
import com.marvinlabs.widget.floatinglabel.LabelAnimator;
import com.marvinlabs.widget.floatinglabel.R;
import com.marvinlabs.widget.floatinglabel.anim.TextViewLabelAnimator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* A widget to pick one or more items from a list
* <p/>
* Created by Vincent Mimoun-Prat @ MarvinLabs, 28/08/2014.
*/
public class FloatingLabelItemPicker<ItemT> extends FloatingLabelTextViewBase<TextView> {
private static final String SAVE_STATE_KEY_SELECTED_INDICES = "saveStateSelectedIndices";
public interface OnWidgetEventListener<ItemT> {
public void onShowItemPickerDialog(FloatingLabelItemPicker<ItemT> source);
}
public interface OnItemPickerEventListener<ItemT> {
public void onSelectionChanged(FloatingLabelItemPicker<ItemT> source, Collection<ItemT> selectedItems);
}
/**
* The available items
*/
protected List<ItemT> availableItems;
/**
* The selected items indices within the available items
*/
protected int[] selectedIndices;
/**
* Something to turn our items into strings
*/
protected ItemPrinter<ItemT> itemPrinter;
/**
* The listener to notify when this widget has something to say
*/
protected OnWidgetEventListener<ItemT> widgetListener;
/**
* The listener to notify when the selection changes
*/
protected OnItemPickerEventListener<ItemT> itemPickerListener;
// =============================================================================================
// Lifecycle
// ==
public FloatingLabelItemPicker(Context context) {
super(context);
}
public FloatingLabelItemPicker(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FloatingLabelItemPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// =============================================================================================
// Overridden methods
// ==
@Override
protected int getDefaultLayoutId() {
return R.layout.flw_widget_floating_label_item_picker;
}
@Override
protected int getDefaultDrawableRightResId() {
return R.drawable.ic_picker;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
getInputWidget().setClickable(true);
getInputWidget().setOnClickListener(inputWidgetClickListener);
}
@Override
protected void restoreInputWidgetState(Parcelable inputWidgetState) {
getInputWidget().onRestoreInstanceState(inputWidgetState);
}
@Override
protected Parcelable saveInputWidgetInstanceState() {
return getInputWidget().onSaveInstanceState();
}
@Override
protected void putAdditionalInstanceState(Bundle saveState) {
if (selectedIndices != null) {
saveState.putIntArray(SAVE_STATE_KEY_SELECTED_INDICES, selectedIndices);
}
}
@Override
protected void restoreAdditionalInstanceState(Bundle savedState) {
selectedIndices = savedState.getIntArray(SAVE_STATE_KEY_SELECTED_INDICES);
// setSelectedIndices(selectedIndices);
}
@Override
protected void setInitialWidgetState() {
if (selectedIndices == null || selectedIndices.length == 0) {
setLabelAnchored(true);
getInputWidget().setText("");
} else {
setLabelAnchored(false);
getInputWidget().setText(getItemPrinter().printCollection(getSelectedItems()));
}
}
@Override
protected LabelAnimator<TextView> getDefaultLabelAnimator() {
return new TextViewLabelAnimator<TextView>();
}
// =============================================================================================
// Item picking
// ==
/**
* Sets the items that can be selected from this widget
*
* @param availableItems
*/
public void setAvailableItems(List<ItemT> availableItems) {
this.availableItems = availableItems;
}
public List<ItemT> getAvailableItems() {
return availableItems;
}
/**
* Set the indices of the items currently selected
*
* @param indices The positions of the selected items within the available item list
*/
public void setSelectedIndices(int[] indices) {
selectedIndices = indices;
onSelectedItemsChanged();
}
/**
* Get the indices of the items currently selected
*
* @return an array of indices within the available items list
*/
public int[] getSelectedIndices() {
return selectedIndices;
}
/**
* Get the items currently selected
*
* @return
*/
public Collection<ItemT> getSelectedItems() {
if (availableItems == null || selectedIndices == null || selectedIndices.length == 0) {
return new ArrayList<ItemT>(0);
}
ArrayList<ItemT> items = new ArrayList<ItemT>(selectedIndices.length);
for (int index : selectedIndices) {
items.add(availableItems.get(index));
}
return items;
}
/**
* Refreshes the widget state when the selection changes
*/
protected void onSelectedItemsChanged() {
final Collection<ItemT> selectedItems = getSelectedItems();
if (selectedItems.isEmpty()) {
anchorLabel();
getInputWidget().setText("");
} else {
getInputWidget().setText(getItemPrinter().printCollection(selectedItems));
floatLabel();
}
if (itemPickerListener != null) itemPickerListener.onSelectionChanged(this, selectedItems);
}
/**
* Show the item picker
*/
protected void requestShowPicker() {
if (widgetListener != null) widgetListener.onShowItemPickerDialog(this);
}
// =============================================================================================
// Other methods
// ==
public OnItemPickerEventListener<ItemT> getItemPickerListener() {
return itemPickerListener;
}
public void setItemPickerListener(OnItemPickerEventListener<ItemT> itemPickerListener) {
this.itemPickerListener = itemPickerListener;
}
public OnWidgetEventListener<ItemT> getWidgetListener() {
return widgetListener;
}
public void setWidgetListener(OnWidgetEventListener<ItemT> widgetListener) {
this.widgetListener = widgetListener;
}
public void setItemPrinter(ItemPrinter<ItemT> itemPrinter) {
this.itemPrinter = itemPrinter;
}
public ItemPrinter<ItemT> getItemPrinter() {
if (itemPrinter == null) {
itemPrinter = new ItemPrinter.ToStringItemPrinter<ItemT>();
}
return itemPrinter;
}
/**
* Listen to click events on the input widget
*/
OnClickListener inputWidgetClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
requestShowPicker();
}
};
}