public class CustomAdapter
private LayoutInflater mInflater;
private int mFieldId = 0;
private int mResource;
public CustomAdapter(Context context, int textViewResourceId,
String[] objects) {
super(context, textViewResourceId, objects);
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(position, convertView, parent, mResource);
}
@Override
public void setDropDownViewResource(int resource) {
this.mResource = resource;
}
private View createViewFromResource(int position, View convertView, ViewGroup parent,
int resource) {
View view;
TextView text;
if (convertView == null) {
view = mInflater.inflate(resource, parent, false);
} else {
view = convertView;
}
try {
if (mFieldId == 0) {
// If no custom field is assigned, assume the whole resource is a TextView
text = (TextView) view;
} else {
// Otherwise, find the TextView field within the layout
text = (TextView) view.findViewById(mFieldId);
}
} catch (ClassCastException e) {
Log.e("ArrayAdapter", "You must supply a resource ID for a TextView");
throw new IllegalStateException(
"ArrayAdapter requires the resource ID to be a TextView", e);
}
String item = getItem(position);
if (item instanceof CharSequence) {
text.setText((CharSequence)item);
} else {
text.setText(item.toString());
}
view.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
return view;
}
}
Most of createViewFromResource is Android code from ArrayAdapter. My modest contribution is only red line. If I specify there some values for width, instead of LayoutParams.FILL_PARENT then I will achieve this:
Well, items are narrower but container is still the same, so subclassing ArrayAdapter doesn’t really help. What needs to be resized and repositioned is AlertDialog which is holding those rows. We can find that out when we open Spinner source. Now I will again do minimalistic subclassing of Spinner.
public class CustomSpinner extends Spinner {
private AlertDialog mPopup;
public CustomSpinner(Context context) {
super(context);
}
public CustomSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mPopup != null && mPopup.isShowing()) {
mPopup.dismiss();
mPopup = null;
}
}
@Override
public boolean performClick() {
Context context = getContext();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
CharSequence prompt = getPrompt();
if (prompt != null) {
builder.setTitle(prompt);
}
mPopup = builder.setSingleChoiceItems(
new DropDownAdapter(getAdapter()), getSelectedItemPosition(),
this).show();
WindowManager.LayoutParams layout = mPopup.getWindow().getAttributes();
layout.x = -128;
layout.y = -110;
layout.height = 320;
layout.width = 240;
mPopup.getWindow().setAttributes(layout);
return true;
}
@Override
public void onClick(DialogInterface dialog, int which) {
setSelection(which);
dialog.dismiss();
mPopup = null;
}
/*
* here you copy and paste code for DropDownAdapter from Spinner
*/
}
Hardcoded values are good enough for illustration of subclassing. Now since we are using custom control we need to change tag in layout:
Now if we build and run application in emulator we will get this:
Not very complicated.
No comments:
Post a Comment