/*
* Copyright (C) 2011 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 android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.javarosa.core.model.data.IAnswerData;
import org.javarosa.form.api.FormEntryPrompt;
import org.odk.collect.android.R;
import org.odk.collect.android.application.Collect;
import org.odk.collect.android.views.MediaLayout;
import java.util.ArrayList;
import java.util.List;
public abstract class QuestionWidget extends LinearLayout {
@SuppressWarnings("unused")
private final static String t = "QuestionWidget";
private static int idGenerator = 1211322;
/**
* Generate a unique ID to keep Android UI happy when the screen orientation
* changes.
*
* @return
*/
public static int newUniqueId() {
return ++idGenerator;
}
private LinearLayout.LayoutParams mLayoutParams;
protected FormEntryPrompt mPrompt;
protected final int mQuestionFontsize;
protected final int mAnswerFontsize;
private TextView mQuestionText;
private MediaLayout mediaLayout;
private TextView mHelpText;
public QuestionWidget(Context context, FormEntryPrompt p) {
super(context);
mQuestionFontsize = Collect.getQuestionFontsize();
mAnswerFontsize = mQuestionFontsize * 4;
mPrompt = p;
setOrientation(LinearLayout.VERTICAL);
setGravity(Gravity.TOP);
setPadding(0, 7, 0, 0);
mLayoutParams =
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
mLayoutParams.setMargins(10, 10, 10, 0);
addQuestionText(p);
// addHelpText(p);
}
public void playAudio() {
mediaLayout.playAudio();
}
public void playVideo() {
mediaLayout.playVideo();
}
public FormEntryPrompt getPrompt() {
return mPrompt;
}
// http://code.google.com/p/android/issues/detail?id=8488
private void recycleDrawablesRecursive(ViewGroup viewGroup, List<ImageView> images) {
int childCount = viewGroup.getChildCount();
for(int index = 0; index < childCount; index++)
{
View child = viewGroup.getChildAt(index);
if ( child instanceof ImageView ) {
images.add((ImageView)child);
} else if ( child instanceof ViewGroup ) {
recycleDrawablesRecursive((ViewGroup) child, images);
}
}
viewGroup.destroyDrawingCache();
}
// http://code.google.com/p/android/issues/detail?id=8488
public void recycleDrawables() {
List<ImageView> images = new ArrayList<ImageView>();
// collect all the image views
recycleDrawablesRecursive(this, images);
for ( ImageView imageView : images ) {
imageView.destroyDrawingCache();
Drawable d = imageView.getDrawable();
if ( d != null && d instanceof BitmapDrawable) {
imageView.setImageDrawable(null);
BitmapDrawable bd = (BitmapDrawable) d;
Bitmap bmp = bd.getBitmap();
if ( bmp != null ) {
bmp.recycle();
}
}
}
}
public boolean forceSetAnswer(Object answer) {
return false;
}
// Abstract methods
public abstract IAnswerData getAnswer();
public abstract void clearAnswer();
public abstract void setFocus(Context context);
public abstract void setOnLongClickListener(OnLongClickListener l);
/**
* Override this to implement fling gesture suppression (e.g. for embedded WebView treatments).
* @param e1
* @param e2
* @param velocityX
* @param velocityY
* @return true if the fling gesture should be suppressed
*/
public boolean suppressFlingGesture(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
/**
* Add a Views containing the question text, audio (if applicable), and image (if applicable).
* To satisfy the RelativeLayout constraints, we add the audio first if it exists, then the
* TextView to fit the rest of the space, then the image if applicable.
*/
protected void addQuestionText(FormEntryPrompt p) {
String imageURI = p.getImageText();
String audioURI = p.getAudioText();
String videoURI = p.getSpecialFormQuestionText("video");
// shown when image is clicked
String bigImageURI = p.getSpecialFormQuestionText("big-image");
String promptText = p.getLongText();
// Add the text view. Textview always exists, regardless of whether there's text.
mQuestionText = (TextView) LayoutInflater.from(getContext())
.inflate(R.layout.template_text_view_question, null);
// TODO: Un-unscreamify once server work is done.
mQuestionText.setText(promptText == null ? "" : promptText);
// TODO: Remove this hack!
if (promptText != null && promptText.toLowerCase().equals("date of birth")) {
mQuestionText.setText("Age");
}
// mQuestionText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mQuestionFontsize);
// mQuestionText.setTypeface(null, Typeface.BOLD);
// mQuestionText.setPadding(0, 0, 0, 7);
mQuestionText.setId(QuestionWidget.newUniqueId()); // assign random id
// Wrap to the size of the parent view
// mQuestionText.setHorizontallyScrolling(false);
// mQuestionText.setLayoutParams(mLayoutParams);
if (promptText == null || promptText.length() == 0) {
mQuestionText.setVisibility(GONE);
}
// Create the layout for audio, image, text
mediaLayout = new MediaLayout(getContext());
mediaLayout.setAVT(p.getIndex(), "", mQuestionText, audioURI, imageURI, videoURI, bigImageURI);
addView(mediaLayout, mLayoutParams);
}
//
// /**
// * Add a TextView containing the help text.
// */
// private void addHelpText(FormEntryPrompt p) {
//
// String s = p.getHelpText();
//
// if (s != null && !s.equals("")) {
// mHelpText = new TextView(getContext());
// mHelpText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mQuestionFontsize - 3);
// mHelpText.setPadding(0, -5, 0, 7);
// // wrap to the widget of view
// mHelpText.setHorizontallyScrolling(false);
// mHelpText.setText(s);
// mHelpText.setTypeface(null, Typeface.ITALIC);
//
// addView(mHelpText, mLayoutParams);
// }
// }
//
/**
* Every subclassed widget should override this, adding any views they may contain, and calling
* super.cancelLongPress()
*/
public void cancelLongPress() {
super.cancelLongPress();
if (mQuestionText != null) {
mQuestionText.cancelLongPress();
}
if (mHelpText != null) {
mHelpText.cancelLongPress();
}
}
}