The spinner works fine, when clicked it has a drop down menu that has checkboxes next to it. My problem is when I click on a check box it ticks, but when I close the spinner and open it back op again, the box is unticked. I want the boxes to remain checked how can I do this?
Here's my code.
ArrayList<StateVO> listbtop = new ArrayList<>();
for (int i = 0; i < btoppings.length; i++) {
StateVO stateVO = new StateVO();
stateVO.setTitle(btoppings[i]);
stateVO.setSelected(false);
listbtop.add(stateVO);
}
MyAdapter myAdapter = new MyAdapter(Guest.this, 0, listbtop);
spinnerbtop.setAdapter(myAdapter);
And Here's my Adapter Class.
public class MyAdapter extends ArrayAdapter<StateVO> {
private Context mContext;
private ArrayList<StateVO> listState;
private MyAdapter myAdapter;
private boolean isFromView = false;
public MyAdapter(Context context, int resource, List<StateVO> objects) {
super(context, resource, objects);
this.mContext = context;
this.listState = (ArrayList<StateVO>) objects;
this.myAdapter = this;
}
#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) {
return getCustomView(position, convertView, parent);
}
public View getCustomView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
LayoutInflater layoutInflator = LayoutInflater.from(mContext);
convertView = layoutInflator.inflate(R.layout.spinner_item, null);
holder = new ViewHolder();
holder.mTextView = (TextView) convertView.findViewById(R.id.text);
holder.mCheckBox = (CheckBox) convertView.findViewById(R.id.checkbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mTextView.setText(listState.get(position).getTitle());
// To check weather checked event fire from getview() or user input
isFromView = true;
holder.mCheckBox.setChecked(listState.get(position).isSelected());
isFromView = false;
if ((position == 0)) {
holder.mCheckBox.setVisibility(View.INVISIBLE);
} else {
holder.mCheckBox.setVisibility(View.VISIBLE);
}
holder.mCheckBox.setTag(position);
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int getPosition = (Integer) buttonView.getTag();
}
});
return convertView;
}
}
You must keep the checked state in your object "StateVO", could you try this implementation of getCustomView ?
public View getCustomView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
LayoutInflater layoutInflator = LayoutInflater.from(mContext);
convertView = layoutInflator.inflate(R.layout.spinner_item, null);
holder = new ViewHolder();
holder.mTextView = (TextView) convertView.findViewById(R.id.text);
holder.mCheckBox = (CheckBox) convertView.findViewById(R.id.checkbox);
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
listState.get((Integer) holder.mCheckBox.getTag()).setSelected(isChecked);
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mCheckBox.setTag(position);
holder.mTextView.setText(listState.get(position).getTitle());
holder.mCheckBox.setChecked(listState.get(position).isSelected());
return convertView;
}
Related
I'm having a ListView with a custom ArrayAdapter. The problem is that I cannot hide (setVisibility(View.GONE)) TextView in some elements of choice. Here is a minimized-readable summary part of my code:
public class ListViewAdapter extends ArrayAdapter<ItemModel> {
private int listItemLayout;
static class ViewHolder {
private TextView description;
}
public ListViewAdapter(Context context, int layoutId, List<ItemModel> itemList) {
super(context, layoutId, itemList);
this.listItemLayout = layoutId;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemModel item = getItem(position);
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(getContext()).inflate(listItemLayout, parent, false);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.description = convertView.findViewById(R.id.text_desription);
viewHolder.description.setText(item.getDescription());
if (TextUtils.isEmpty(item.getDescription())) {
viewHolder.description.setVisibility(View.GONE);
}
return convertView;
}
}
What am I doing wrong here? How can I hide a view inside item in ListView if its content String is empty?
Add else part of if condition to change visibility from GONE to VISIBLE as in below code.
public class ListViewAdapter extends ArrayAdapter {
private int listItemLayout;
static class ViewHolder {
private TextView description;
}
public ListViewAdapter(Context context, int layoutId, List itemList) {
super(context, layoutId, itemList);
this.listItemLayout = layoutId;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemModel item = getItem(position);
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(getContext()).inflate(listItemLayout, parent, false);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.description = convertView.findViewById(R.id.text_desription);
viewHolder.description.setText(item.getDescription());
if (TextUtils.isEmpty(item.getDescription())) {
viewHolder.description.setVisibility(View.GONE);
}else{
viewHolder.description.setVisibility(View.VISIBLE);
}
return convertView;
}
}
OR try if (item.getDescription()==null || item.getDescription().trim().length() == 0)
instead of if (TextUtils.isEmpty(item.getDescription()))
Check any white space should not be in your text. Try this-
if (TextUtils.isEmpty(item.getDescription().trim()) ||item.getDescription().trim().length()==0 ) {
viewHolder.description.setVisibility(View.GONE);
}
else{
viewHolder.description.setVisibility(View.VISIBLE);
}
I've been trying to implement a multi-select spinner on my own. So the problem is I'm able to select the checkboxes but when I close and open the spinner again, the selected checkboxes get deselected. So I thought I would implement my own itemclick listener to the spinner and use the positions to check the checkboxes. Now, my spinner is not dropping down.
Here's the code for the main activity.
public class MyProfileActivity extends Activity implements
View.OnClickListener, SpinnerMultiSelectAdapter.OnListItemClickListener{
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
lang_spinner_profile = findViewById(R.id.lang_spinner_profile);
ArrayList<String> options = new ArrayList<>();
options.add("English");
options.add("Japanese");
options.add("Chinese");
options.add("Korean");
lang_spinner_profile.setSelection(0);
final String[] languages = {
"Select Language", "English","Chinese","Japanese","Korean"};
for (int j = 0; j < languages.length; j++) {
StateVO stateVO= new StateVO();
stateVO.setTitle(languages[j]);
stateVO.setSelected(false);
listVOs.add(stateVO);
}
Log.d("Called","Called");
myAdapter = new SpinnerMultiSelectAdapter(MyProfileActivity.this, 0,
listVOs, this);
lang_spinner_profile.setAdapter(myAdapter);
}
#Override
public void onListItemClick(int position) {
Toast.makeText(this, "Clicked at: "+position, Toast.LENGTH_SHORT).show();
}
}
This is my custom pojo class for the spinner.
public class StateVO {
private String title;
private boolean selected;
private String selectedItem;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
This is the spinner custom layout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="text"
android:textAlignment="gravity" />
<CheckBox
android:id="#+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
And finally, this is my custom adapter.
public class SpinnerMultiSelectAdapter extends ArrayAdapter<StateVO> {
private Context mContext;
static private ArrayList<StateVO> listState;
private SpinnerMultiSelectAdapter myAdapter;
private boolean isFromView = false;
List<String> selected = new ArrayList<>();
static int i=0;
List<Integer> checked= new ArrayList<>();
View itemView;
int getPosition;
private OnListItemClickListener onListItemClickListener;
public SpinnerMultiSelectAdapter(Context context, int resource, List<StateVO> objects, OnListItemClickListener onListItemClickListener) {
super(context, resource, objects);
this.mContext = context;
this.listState = (ArrayList<StateVO>) objects;
this.myAdapter = this;
this.onListItemClickListener = onListItemClickListener;
}
#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) {
return getCustomView(position, convertView, parent);
}
public View getCustomView(final int position, View convertView,
ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
LayoutInflater layoutInflator = LayoutInflater.from(mContext);
convertView = layoutInflator.inflate(R.layout.spinner_item, null);
itemView = convertView;
holder = new ViewHolder();
holder.mTextView = (TextView) convertView
.findViewById(R.id.text);
holder.mCheckBox = (CheckBox) convertView
.findViewById(R.id.checkbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mTextView.setText(listState.get(position).getTitle());
// To check weather checked event fire from getview() or user input
isFromView = true;
holder.mCheckBox.setChecked(listState.get(position).isSelected());
isFromView = false;
if ((position == 0)) {
holder.mCheckBox.setVisibility(View.INVISIBLE);
} else {
holder.mCheckBox.setVisibility(View.VISIBLE);
}
holder.mCheckBox.setTag(position);
selected.clear();
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
getPosition = (Integer) buttonView.getTag();
holder.mCheckBox.setSelected(true);
//notifyDataSetChanged();
}
});
return convertView;
}
private class ViewHolder implements View.OnClickListener {
private TextView mTextView;
private CheckBox mCheckBox;
public ViewHolder(){
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onListItemClickListener.onListItemClick(getPosition);
}
}
public interface OnListItemClickListener {
public void onListItemClick(int position);
}
}
Any help is appreciated. Thank you.
Your adapter has few mistakes here is how it should be;
public class SpinnerMultiSelectAdapter extends ArrayAdapter<StateVO> {
private Context mContext;
private ArrayList<StateVO> listState;
private boolean isFromView = false;
List<String> selected = new ArrayList<>();
List<Integer> checked = new ArrayList<>();
private OnListItemClickListener onListItemClickListener;
public SpinnerMultiSelectAdapter(Context context, int resource, List<StateVO> objects, OnListItemClickListener onListItemClickListener) {
super(context, resource, objects);
this.mContext = context;
this.listState = (ArrayList<StateVO>) objects;
this.onListItemClickListener = onListItemClickListener;
}
#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) {
return getCustomView(position, convertView, parent);
}
public View getCustomView(final int position, View convertView,
ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
LayoutInflater layoutInflator = LayoutInflater.from(mContext);
convertView = layoutInflator.inflate(R.layout.spinner_item, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final String str = listState.get(position).getTitle();
holder.mTextView.setText(str);
if ((position == 0)) {
holder.mCheckBox.setVisibility(View.INVISIBLE);
} else {
holder.mCheckBox.setVisibility(View.VISIBLE);
}
holder.mCheckBox.setTag(position);
holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
listState.get(position).setSelected(isChecked);
}
});
return convertView;
}
private class ViewHolder implements View.OnClickListener {
private TextView mTextView;
private CheckBox mCheckBox;
public ViewHolder(View convertView) {
mTextView = (TextView) convertView
.findViewById(R.id.text);
mCheckBox = (CheckBox) convertView
.findViewById(R.id.checkbox);
convertView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
/*onListItemClickListener.onListItemClick(getPosition);*/
}
}
public interface OnListItemClickListener {
public void onListItemClick(int position);
}
}
in my listView i'm trying to divide (categorize) my data in to different section say i have a list of states and i wanna categorize them according to their Countries but what i have right now is categorizing my data Alphabetically and i have no clue how it is happening and how can i achieve what i want. can anyone guide me here ?
my adapter :
public class MyAdapter extends BaseAdapter implements StickyListHeadersAdapter {
private String[] countries;
private LayoutInflater inflater;
private ArrayList<States> statesArray;
public MyAdapter(Context context , ArrayList<States> states) {
inflater = LayoutInflater.from(context);
satesArray = states;
countries = context.getResources().getStringArray(R.array.all_countries);
}
#Override
public int getCount() {
return statesArray.size();
}
#Override
public Object getItem(int position) {
return statesArray.get(position).getName();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.list_view_row, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.listViewTextView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(statesArray.get(position).getName());
return convertView;
}
#Override
public View getHeaderView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
if (convertView == null) {
holder = new HeaderViewHolder();
convertView = inflater.inflate(R.layout.sticky_header, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.text1);
convertView.setTag(holder);
} else {
holder = (HeaderViewHolder) convertView.getTag();
}
//set header text as first char in name
String headerText = "" + countries[position];
holder.text.setText(headerText);
return convertView;
}
#Override
public long getHeaderId(int position) {
// return the first character of the country as ID because this is what headers are based upon
return satesArray.get(position).getName().subSequence(0, 1).charAt(0);
}
class HeaderViewHolder {
TextView text;
}
class ViewHolder {
TextView text;
}
}
UPDATE :
what i want is right here but instead of Alphabets at Section there would be Country name and at rows there would be states of respective Country :
righ here
I have an arraylist that needs to be updated using the adpater. I dont have any textviews for it. Here is my code -
public class MyAdapter extends BaseAdapter {
private LayoutInflater inflater = null;
private ArrayList<MyClass> favouriteMessageList;
private MyAdapter(Activity activity, ArrayList list) {
favouriteMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
MyClass favouriteMessage = favouriteMessageList.get(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.messaging_favorites_layout, null);
viewHolder = new ViewHolder();
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
return convertView;
}
public void setData(ArrayList<MyClass> data) {
favouriteMessageList = data;
notifyDataSetChanged();
}
}
The setData method will receive an arraylist and I need to populate the view with my Arraylist. I am using a viewHolder. How do I achieve this?
Try like this:
public class MyAdapter extends BaseAdapter {
private LayoutInflater inflater = null;
private ArrayList<MyClass> favouriteMessageList;
private MyAdapter(Activity activity, ArrayList list) {
favouriteMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
MyClass favouriteMessage = favouriteMessageList.get(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.messaging_favorites_layout, null);
viewHolder = new ViewHolder();
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//Update Your Views Here
return convertView;
}
#Override
public int getCount() {
if (favouriteMessageList != null) return favouriteMessageList.size();
return 0;
}
public void setData(ArrayList<MyClass> data) {
favouriteMessageList = data;
notifyDataSetChanged();
}
}
When I am checked any item like (position 0) its automatically checked randomly any item (like position 7) and when I scroll down or up the check position will be change every time... I am fed up from that problem...??
public class contactAdpter extends ArrayAdapter<ContactItem> {
Context context;
List<ContactItem> list;
public contactAdpter(Context context, int resource, List<ContactItem> items) {
super(context, resource,items);
this.context = context;
this.list = items;
}
static class ViewHolder {
ImageView imageview;
TextView tv1;
TextView tv2;
CheckBox ch;
}
#Override
public int getCount() {
return list.size();
}
#Override
public int getPosition(ContactItem item) {
return super.getPosition(item);
}
#Override
public long getItemId(int id) {
return id;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
View view = convertView;
ContactItem contactItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
view = mInflater.inflate(R.layout.contact_list, null);
holder = new ViewHolder();
holder.tv1 = (TextView) view.findViewById(R.id.name);
holder.tv2 = (TextView) view.findViewById(R.id.number);
holder.ch = (CheckBox) view.findViewById(R.id.checkbox1);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.tv1.setText(contactItem.getConatct_name());
holder.tv2.setText(contactItem.getNumber());
return view;
}
}
in ContactItem you need to maintain Checked Status. and change getView as follows,
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
View view = convertView;
ContactItem contactItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
view = mInflater.inflate(R.layout.contact_list, null);
holder = new ViewHolder();
holder.tv1 = (TextView) view.findViewById(R.id.name);
holder.tv2 = (TextView) view.findViewById(R.id.number);
holder.ch = (CheckBox) view.findViewById(R.id.checkbox1);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.tv1.setText(contactItem.getConatct_name());
holder.tv2.setText(contactItem.getNumber());
holder.ch.setOnCheckedChangeListener(null);
holder.ch.setChecked(contactItem.getCheckedStatus());
holder.ch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
contactItem.setCheckedStatus(isChecked);
}
});
return view;
}
you have to add another variable in ContactItem like below:
private boolean isSelected;
generate getter and setter method of this variable after that in your adapter :
public class contactAdpter extends ArrayAdapter {
Context context;
List<ContactItem> list;
public contactAdpter(Context context, int resource, List<ContactItem> items) {
super(context, resource,items);
this.context = context;
this.list = items;
}
static class ViewHolder {
ImageView imageview;
TextView tv1;
TextView tv2;
CheckBox ch;
}
#Override
public int getCount() {
return list.size();
}
#Override
public int getPosition(ContactItem item) {
return super.getPosition(item);
}
#Override
public long getItemId(int id) {
return id;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
View view = convertView;
ContactItem contactItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
view = mInflater.inflate(R.layout.contact_list, null);
holder = new ViewHolder();
holder.tv1 = (TextView) view.findViewById(R.id.name);
holder.tv2 = (TextView) view.findViewById(R.id.number);
holder.ch = (CheckBox) view.findViewById(R.id.checkbox1);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.tv1.setText(contactItem.getConatct_name());
holder.tv2.setText(contactItem.getNumber());
if(contactItem.isSelected){
holder.ch.isChecked(true);
} else {
holder.ch.isChecked(false);
}
holder.ch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(contactItem.isSelected){
holder.ch.isChecked(false);
contactItem.setChecked(false);
} else {
holder.ch.isChecked(true);
contactItem.setChecked(true);
}
notifyDatasetChanged();
}
});
return view;
}
}