Reputation: 253
I have been working on a spinner which has a custom layout for the dropdown. Here's my problem, when I select, let's say the 2nd item in the drop down, it gets selected and the drop down closes. When I reopen the drop down, the first row remains the same but the second row gets renamed to the first row. But it tells when I print out a log.d into console, that position:2 was selected.
Here's my code,
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = (TextView) convertView.inflate(getContext(), android.R.layout.simple_spinner_item, null);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
textView.setTextColor(ContextCompat.getColor(getActivity().getApplicationContext(), R.color.blue));
if(list.getIsRecent()){
textView.setText("Most Recent ");
} else {
textView.setText(list.get(position).getName());
}
return textView;
}
public View getCustomView(final int position, View convertView, ViewGroup parent) {
boolean isRecent;
isRecent = list.get(position).getIsRecent();
if (convertView == null) {
convertView = inflater.inflate(R.layout.custom_spinner_layout, parent, false);
savedSearchName = (TextView) convertView
.findViewById(R.id.custom_spinner_layout_text_view);
btnDelete = (ImageButton) convertView
.findViewById(R.id.custom_spinner_layout_button);
relativeLayoutContainer = (RelativeLayout) convertView.findViewById(R.id.relativeLayout_item_name_container);
relativeLayoutContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG,"relativeLayoutContainer: setOnClickListener: position"+position);
Method method = null;
if(mSavedSearchCriteriaSpinner != null) {
mSavedSearchCriteriaSpinner.setSelection(position);
try {
method = Spinner.class.getDeclaredMethod("onDetachedFromWindow");
method.setAccessible(true);
method.invoke(mSavedSearchCriteriaSpinner);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
if(isRecent){
btnDelete.setVisibility(View.INVISIBLE);
savedSearchName.setText(list.get(position).getName() + "MOSTRECENT");
} else {
savedSearchName.setText(list.get(position).getName());
btnDelete.setVisibility(View.VISIBLE);
btnDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//AlertDialog
});
}
}
return convertView;
}
And No, this is not a homework question.
Upvotes: 0
Views: 513
Reputation: 6583
In getView()
, you're using the convertView wrong. This can be either null
or an old view that needs to be recycled. If it's null
, you have to inflate a new view, as you're doing. If not, this is an old item that needs to be recycled (i.e. you need to modify the text, you don't even need to set text size and color again):
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = convertView;
if (convertView == null) {
LayoutInflater li = LayoutInflater.from(parent);
textView = (TextView) li.inflate(getContext(), android.R.layout.simple_spinner_item, null);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
textView.setTextColor(ContextCompat.getColor(getActivity().getApplicationContext(), R.color.blue));
}
if(list.getIsRecent()){
textView.setText("Most Recent ");
} else {
textView.setText(list.get(position).getName());
}
return textView;
}
Also, getCustomView is storing btnDelete and savedSearchName in fields in your object, and probably this is messing up with old contents. Also, update the convertView always (now, if convertView is not null you don't update it):
public View getCustomView(final int position, View convertView, ViewGroup parent) {
boolean isRecent;
isRecent = list.get(position).getIsRecent();
if (convertView == null) {
convertView = inflater.inflate(R.layout.custom_spinner_layout, parent, false);
}
TextView savedSearchName = (TextView) convertView.findViewById(R.id.custom_spinner_layout_text_view);
ImageButton btnDelete = (ImageButton) convertView.findViewById(R.id.custom_spinner_layout_button);
RelativeLayout relativeLayoutContainer = (RelativeLayout) convertView.findViewById(R.id.relativeLayout_item_name_container);
relativeLayoutContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG,"relativeLayoutContainer: setOnClickListener: position"+position);
Method method = null;
if(mSavedSearchCriteriaSpinner != null) {
mSavedSearchCriteriaSpinner.setSelection(position);
try {
method = Spinner.class.getDeclaredMethod("onDetachedFromWindow");
method.setAccessible(true);
method.invoke(mSavedSearchCriteriaSpinner);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
if(isRecent){
btnDelete.setVisibility(View.INVISIBLE);
savedSearchName.setText(list.get(position).getName() + "MOSTRECENT");
} else {
savedSearchName.setText(list.get(position).getName());
btnDelete.setVisibility(View.VISIBLE);
btnDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//AlertDialog
});
}
return convertView;
}
About storing savedSearchName
and btnDelete
in fields, I guess is because you want to avoid searching them again. In that case I'd suggest using a holder pattern. See for example Hold View Objects in a View Holder in the following Google guide.
Upvotes: 1