问题
I'm using a Spinner with a custom adapter class called AlgorithmAdapter and in principle everything's working fine, meaning the spinner popup appears and all containing views are properly inflated. However, what I'm not able to find out is how I "tell" the spinner when the selection is made. Of course I know about setSelection(), but that doesn't dispose the popup and return focus to the Activity.
So here's some of the relevant code:
In my activity, I create my adapter like this:
SpinnerAdapter spinnerAdapter = new AlgorithmAdapter(
this,
algorithmSpinner,
R.layout.algo_spinner_item_detail,
res.getStringArray(R.array.anaglyph_algorithm_titles),
res.getStringArray(R.array.anaglyph_algorithm_descriptions),
res.obtainTypedArray(R.array.anaglyph_algorithm_icons),
algorithmSpinner.getSelectedItemPosition()
);
algorithmSpinner.setAdapter(spinnerAdapter);
The constructor of AgorithmAdapter has the following signature:
public AlgorithmAdapter(Context context, Spinner spinner, int viewResourceId, String[] titles,
String[] descriptions, TypedArray icons, int selectedPosition) {
The getDropDownView() method of AlgorithmAdapter:
@Override
public View getDropDownView(final int position, View convertView, ViewGroup parent) {
if(convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(viewResourceId, parent, false);
}
final ImageView icon = (ImageView) convertView.findViewById(R.id.algoItemIcon);
final TextView title = (TextView) convertView.findViewById(R.id.algoItemTitle);
final TextView description = (TextView) convertView.findViewById(R.id.algoItemDescription);
final RadioButton radio = (RadioButton) convertView.findViewById(R.id.algoItemRadio);
icon.setImageDrawable(icons.getDrawable(position));
title.setText(titles[position]);
description.setText(descriptions[position]);
radioGroup.add(radio);
/* it's essential to uncheck in case the positions do not match, because
* the system reuses views that could still have a checked radio button */
radio.setChecked(position == selectedPosition);
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// uncheck every other radio button
for(RadioButton each : radioGroup)
each.setChecked(false);
// inform adapter and user that this button is selected now
radio.setChecked(true);
selectedPosition = position;
spinner.setSelection(position);
}
});
return convertView;
}
where radioGroup is a list of all RadioButtons from all drop down views in order to manage which one is currently checked and which ones have to be unchecked therefore.
That all works very well except for the fact that the popup doesn't close on setSelection() (which itself is working though).
I also tried to attach an OnItemClickListener to the Spinner and manage the selection stuff in there, but that throws an exception saying setOnItemClickListener cannot be used with a spinner, which is really annoying since it feels as if the framework stands in my way instead of helping me at this point. But anyway, that's the reason I have to pass the Spinner through to the adapter which I would be glad I had a different solution for…
So the only thing I'm missing is how I "close" or "dispose" the Spinners drop down. Could anybody help me with that? Is this even anywhere near the way do to it? It cannot be that difficult since writing custom adapters for Spinners is a pretty basic task.
EDIT: No idea if this helps, but maybe someone finds an error in the layout file of my drop down view item. algo_spinner_item_detail.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:background="@android:drawable/list_selector_background" >
<ImageView
android:id="@+id/algoItemIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:contentDescription="@string/algoIconDescription"
android:layout_marginRight="8dp" />
<RadioButton
android:id="@+id/algoItemRadio"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_marginLeft="10dp"
android:layout_centerVertical="false" />
<TextView
android:id="@+id/algoItemTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/algoItemIcon"
android:layout_alignTop="@id/algoItemIcon"
android:textStyle="bold"
android:layout_marginBottom="1dp" />
<TextView
android:id="@+id/algoItemDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/algoItemTitle"
android:layout_alignLeft="@id/algoItemTitle"
android:layout_toLeftOf="@id/algoItemRadio" />
</RelativeLayout>
How the heck do you close/dispose the f***ing Spinner drop down after you selected an item?
回答1:
Here's what did the trick for me (WARNING: don't show this code to your kids, you'd certainly go to hell for it):
In the onClick method of my convertView I put this line of code:
((View) parent.getParent().getParent().getParent().getParent()).setVisibility(View.GONE);
which not only gets rid of the LinearLayout in which the convertViews are contained, but also makes the com.android.internal.policy.impl.PhoneWindow$DecorView invisible, that was there to darken the Activity screen while a dialog/drop down is shown.
I'm still after a better solution.
来源:https://stackoverflow.com/questions/12917963/spinner-with-custom-adapter-doesnt-disappear-on-selection