/*
* Copyright (C) 2009 University of Washington
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.odk.collect.android.widgets;
import java.util.Vector;
import org.javarosa.core.model.SelectChoice;
import org.javarosa.core.model.data.IAnswerData;
import org.javarosa.core.model.data.SelectOneData;
import org.javarosa.core.model.data.helper.Selection;
import org.javarosa.form.api.FormEntryPrompt;
import org.odk.collect.android.R;
import android.content.Context;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
/**
* SpinnerWidget handles select-one fields. Instead of a list of buttons it uses a spinner, wherein
* the user clicks a button and the choices pop up in a dialogue box. The goal is to be more
* compact. If images, audio, or video are specified in the select answers they are ignored.
*
* @author Jeff Beorse (jeff@beorse.net)
*/
public class SpinnerWidget extends QuestionWidget {
Vector<SelectChoice> mItems;
Spinner spinner;
String[] choices;
public SpinnerWidget(Context context, FormEntryPrompt prompt) {
super(context, prompt);
mItems = prompt.getSelectChoices();
spinner = new Spinner(context);
choices = new String[mItems.size()];
for (int i = 0; i < mItems.size(); i++) {
choices[i] = prompt.getSelectChoiceText(mItems.get(i));
}
// The spinner requires a custom adapter. It is defined below
SpinnerAdapter adapter =
new SpinnerAdapter(getContext(), android.R.layout.simple_spinner_item, choices,
TypedValue.COMPLEX_UNIT_DIP, mQuestionFontsize);
spinner.setAdapter(adapter);
spinner.setPrompt(prompt.getQuestionText());
spinner.setEnabled(!prompt.isReadOnly());
spinner.setFocusable(!prompt.isReadOnly());
// Fill in previous answer
String s = null;
if (prompt.getAnswerValue() != null) {
s = ((Selection) prompt.getAnswerValue().getValue()).getValue();
}
if (s != null) {
for (int i = 0; i < mItems.size(); ++i) {
String sMatch = mItems.get(i).getValue();
if (sMatch.equals(s)) {
spinner.setSelection(i);
}
}
}
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
/*
* (non-Javadoc)
* @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(android.widget.AdapterView, android.view.View, int, long)
*/
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
if(hasListener){
widgetChangedListener.widgetEntryChanged();
}
}
/*
* (non-Javadoc)
* @see android.widget.AdapterView.OnItemSelectedListener#onNothingSelected(android.widget.AdapterView)
*/
@Override
public void onNothingSelected(AdapterView<?> parent) {
//do nothing here
}
});
addView(spinner);
}
/*
* (non-Javadoc)
* @see org.odk.collect.android.widgets.QuestionWidget#getAnswer()
*/
@Override
public IAnswerData getAnswer() {
int i = spinner.getSelectedItemPosition();
if (i == -1) {
return null;
} else {
SelectChoice sc = mItems.elementAt(i); // - RANDOM_BUTTON_ID);
return new SelectOneData(new Selection(sc));
}
}
/*
* (non-Javadoc)
* @see org.odk.collect.android.widgets.QuestionWidget#clearAnswer()
*/
@Override
public void clearAnswer() {
// It seems that spinners cannot return a null answer. This resets the answer
// to its original value, but it is not null.
spinner.setSelection(0);
}
/*
* (non-Javadoc)
* @see org.odk.collect.android.widgets.QuestionWidget#setFocus(android.content.Context)
*/
@Override
public void setFocus(Context context) {
// Hide the soft keyboard if it's showing.
InputMethodManager inputManager =
(InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getWindowToken(), 0);
}
// Defines how to display the select answers
private class SpinnerAdapter extends ArrayAdapter<String> {
Context context;
String[] items = new String[] {};
int textUnit;
float textSize;
public SpinnerAdapter(final Context context, final int textViewResourceId,
final String[] objects, int textUnit, float textSize) {
super(context, textViewResourceId, objects);
this.items = objects;
this.context = context;
this.textUnit = textUnit;
this.textSize = textSize;
}
/*
* (non-Javadoc)
* @see android.widget.ArrayAdapter#getDropDownView(int, android.view.View, android.view.ViewGroup)
*/
@Override
// Defines the text view parameters for the drop down list entries
public View getDropDownView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.custom_spinner_item, parent, false);
}
TextView tv = (TextView) convertView.findViewById(android.R.id.text1);
tv.setText(items[position]);
tv.setTextSize(textUnit, textSize);
tv.setPadding(10, 10, 10, 10); // Are these values OK?
return convertView;
}
/*
* (non-Javadoc)
* @see android.widget.ArrayAdapter#getView(int, android.view.View, android.view.ViewGroup)
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(android.R.layout.simple_spinner_item, parent, false);
}
TextView tv = (TextView) convertView.findViewById(android.R.id.text1);
tv.setText(items[position]);
tv.setTextSize(textUnit, textSize);
return convertView;
}
}
/*
* (non-Javadoc)
* @see org.odk.collect.android.widgets.QuestionWidget#setOnLongClickListener(android.view.View.OnLongClickListener)
*/
@Override
public void setOnLongClickListener(OnLongClickListener l) {
spinner.setOnLongClickListener(l);
}
/*
* (non-Javadoc)
* @see org.odk.collect.android.widgets.QuestionWidget#cancelLongPress()
*/
@Override
public void cancelLongPress() {
super.cancelLongPress();
spinner.cancelLongPress();
}
}