I'm using a custom Spinner widget with the code below.
Everything works fine on most devices except on Samsung's devices with Android 5.0. On click the Spinner should display a list of values but that doesn't happen.
On emulators and others brands devices with Android 5.0 it works fine.
Has anyone faced a similiar isse or have any idea of what might be happening?
xml
<?xml version="1.0" encoding="utf-8"?>
<Spinner
android:id="@+id/_combo_spinner"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusable="false"
android:background="@null"
android:clickable="false"
android:paddingBottom="@dimen/cell_text_section_text_padding_bottom"
android:paddingLeft="@dimen/cell_text_section_text_padding_left"
android:paddingRight="@dimen/cell_text_section_text_padding_right"
android:paddingTop="@dimen/cell_text_section_text_padding_top"
android:spinnerMode="dropdown" />
<View
android:layout_width="@dimen/drawable_stroke_width"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginTop="3dp"
android:background="@color/stroke_dark_grey"
android:paddingBottom="@dimen/cell_text_section_text_padding_bottom"
android:paddingTop="@dimen/cell_text_section_text_padding_top" />
<ImageView
style="@style/image__default"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/cell_text_section_text_padding_left"
android:layout_marginRight="@dimen/cell_text_section_text_padding_right"
android:src="@drawable/ic_action_expand" />
Java
public class ComboBoxView extends LinearLayout {
private Spinner mSpinner;
private OnItemSelectedListener mListener;
public ComboBoxView(Context context) {
super(context);
initializeLayout(context);
}
public ComboBoxView(Context context, AttributeSet attrs) {
super(context, attrs);
initializeLayout(context);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public ComboBoxView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initializeLayout(context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ComboBoxView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initializeLayout(context);
}
// Internal methods:
/**
* Initializes the layout
*
* @param context
*/
private void initializeLayout(final Context context) {
mListener = null;
// Inflate and retrieve the views:
this.setOrientation(LinearLayout.VERTICAL);
LayoutInflater.from(context).inflate(R.layout.view_combo_box, this);
mSpinner = (Spinner) findViewById(R.id._combo_spinner);
// Finish initialization:
final int paddingTop = (int) getResources().getDimension(R.dimen.cell_text_section_text_padding_top);
final int paddingBottom = (int) getResources().getDimension(R.dimen.cell_text_section_text_padding_bottom);
final int paddingLeft = (int) getResources().getDimension(R.dimen.cell_text_section_text_padding_left);
final int paddingRight = (int) getResources().getDimension(R.dimen.cell_text_section_text_padding_right);
setOnClickListener(onClick);
setOrientation(LinearLayout.HORIZONTAL);
setBackgroundResource(R.drawable.button_primary);
setClickable(true);
setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
private final OnClickListener onClick = new OnClickListener() {
@Override
public void onClick(View v) {
mSpinner.performClick();
}
};
@Override
public void clearFocus() {
super.clearFocus();
mSpinner.clearFocus();
}
// External methods:
/**
* Interface definition for a callback to be invoked when
* an item in this view has been selected (extracted from {@link AdapterView.OnItemSelectedListener}).
*/
public interface OnItemSelectedListener {
/**
* <p>Callback method to be invoked when an item in this view has been
* selected. This callback is invoked only when the newly selected
* position is different from the previously selected position or if
* there was no selected item.</p>
* <p/>
* Impelmenters can call getItemAtPosition(position) if they need to access the
* data associated with the selected item.
*
* @param parent The ComboBoxView where the selection happened
* @param position The position of the view in the adapter
* @param id The row id of the item that is selected
*/
void onItemSelected(ComboBoxView parent, int position, long id);
/**
* Callback method to be invoked when the selection disappears from this
* view. The selection can disappear for instance when touch is activated
* or when the adapter becomes empty.
*
* @param parent The ComboBoxView that now contains no selected item.
*/
void onNothingSelected(ComboBoxView parent);
}
public void setValuesAsString(final List<String> newValues) {
setValuesAsString(newValues, 0);
}
public void setValuesAsString(final List<String> newValues, int initialValue) {
List<CharSequence> result = new ArrayList<CharSequence>(newValues.size());
for(String value : newValues) {
result.add(value);
}
setValues(result, initialValue);
}
public void setValues(final List<CharSequence> newValues) {
setValues(newValues, 0);
}
public void setValues(final List<CharSequence> newValues, int initialValue) {
if((initialValue >= newValues.size()) || (initialValue < -1)) {
IllegalArgumentException ex = new IllegalArgumentException("Invalid value for initialValue");
LOG.error(LOG.SOURCE.UI, "Invalid",ex);
throw ex;
}
// Prepare the list of elements:
// NOTE: The last item in ComboBoxArrayAdapter must be empty. Items should also contain the
// same number of lines as the "tallest" entry:
final List<CharSequence> finalValues = new ArrayList<CharSequence>(newValues.size());
finalValues.addAll(newValues);
int maxLines = 1;
for(CharSequence text : newValues) {
final String[] lines = text.toString().split("\r\n|\r|\n");
maxLines = Math.max(maxLines, lines.length);
}
finalValues.add("");
// Prepare spinner:
final ComboBoxArrayAdapter adapter = new ComboBoxArrayAdapter(this.getContext(), R.layout.view_combo_box_item, finalValues);
adapter.setDropDownViewResource(R.layout.view_combo_box_item_dropdown);
adapter.setMaxLines(maxLines);
mSpinner.setOnItemSelectedListener(null);
mSpinner.setAdapter(adapter);
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
boolean firstSelection = true;
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (mListener != null) {
int index = (position >= (mSpinner.getCount() - 1)) ? -1 : position;
mListener.onItemSelected(ComboBoxView.this, index, id);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
if (mListener != null) {
mListener.onNothingSelected(ComboBoxView.this);
}
}
});
if (mListener != null) {
mListener.onNothingSelected(this);
}
// Set initial selection:
if(initialValue != -1) {
mSpinner.setSelection(initialValue);
} else {
mSpinner.setSelection(newValues.size());
}
}
public void setOnItemSelectedListener(final OnItemSelectedListener listener) {
mListener = listener;
}
public int getSelectedItem() {
int result = mSpinner.getSelectedItemPosition();
if(result >= mSpinner.getCount()) {
result = -1;
}
return result;
}
Spinner
Example Result
Thanks in advance.
I finally fixed this!
The android property clickable
was set to false
, but the click behaviour was performed in the ComboBoxView.java file on the following code:
private final OnClickListener onClick = new OnClickListener() {
@Override
public void onClick(View v) {
mSpinner.performClick();
}
};
This was working everywhere (devices and emulators) except on Samsung devices with Android 5.0. This I couldn't figure out why.
After I changed the cliclabke
property to true it started working.
android:clickable="true"
Thanks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With