I made a spinner in which im using a arrayadapter to populate it with images and text. on OnItemSelected i want to select only and only the text not the image.
Here is my code for the MainActivity.java
ArrayList<ItemData> list = new ArrayList<>();
list.add(new ItemData("Select Plan Category",R.drawable.ic_bars));
list.add(new ItemData("Hookah",R.drawable.ic_006_hookah));
list.add(new ItemData("Drinks",R.drawable.ic_005_pint));
list.add(new ItemData("Gedi",R.drawable.ic_004_racing));
list.add(new ItemData("Snacks",R.drawable.ic_003_chips));
list.add(new ItemData("Shopping",R.drawable.ic_002_cart));
list.add(new ItemData("Bownling",R.drawable.ic_001_bowling));
SpinnerAdapter adapter = new SpinnerAdapter(getActivity(), R.layout.spinner_layout,R.id.categoryText,list);
categorySpinnerjava.setAdapter(adapter);
Here is my code for the ItemData.java
public class ItemData {
private String planCategorytext = "";
Integer imageId;
public ItemData(String text, Integer imageId)
{
this.planCategorytext=text;
this.imageId=imageId;
}
public String getPlanCategorytext() {
return planCategorytext;
}
public void setPlanCategorytext(String planCategorytext) {
this.planCategorytext = planCategorytext;
}
public Integer getImageId() {
return imageId;
}
public void setImageId(Integer imageId) {
this.imageId = imageId;
}
}
And here is my code for the SpinnerAdapter.java(that is extending the ArrayAdapter
int groupid;
Activity getActivity;
ArrayList<ItemData> list;
LayoutInflater inflater;
public SpinnerAdapter(Activity context, int groupid, int id, ArrayList<ItemData> list) {
super(context, id,list);
this.list=list;
inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.groupid=groupid;
}
public View getView(int position, View convertView, ViewGroup parent)
{
View itemView = inflater.inflate(groupid,parent,false);
ImageView imageView=(ImageView)itemView.findViewById(R.id.categoryVector);
imageView.setImageResource(list.get(position).getImageId());
TextView textView = (TextView)itemView.findViewById(R.id.categoryText);
textView.setText(list.get(position).getPlanCategorytext());
return itemView;
}
public View getDropDownView(int position, View convertView, ViewGroup parent)
{
return getView(position,convertView,parent);
}
I want to only select the text not the image. And when i normally do the
String spinnerselection = categorySpinnerjava.getSelectedItem().toString();
It gives me a output of "applicationpackage.ItemData#randomnumbers"
you are getting this error because
"applicationpackage.ItemData#randomnumbers"
your categorySpinnerjava.getSelectedItem(); return your model class ItemData not a String
Try this
ItemData itemData = (ItemData) categorySpinnerjava.getSelectedItem();
String data= itemData.getPlanCategorytext();
Integer imageId = itemData.getImageId();
You can get the selected spinner item's text in the following way:
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long l) {
String selectedText=list.get(pos).getPlanCategorytext();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
OR
String selectedItemText=list.get(spinner.getSelectedItemPosition()).getPlanCategorytext();
Where list is the arraylist with ItemData which you used above to populate the data in spinner.
Also about this:
String spinnerselection = categorySpinnerjava.getSelectedItem().toString();
You have to replace categorySpinnerjava.getSelectedItem().toString(); with list.get(spinner.getSelectedItemPosition()).getPlanCategorytext();
Try implementing using Interface.
Set text data inside SpinnerAdapter and extend Interface in Activity class to get the selected text
Try the following:
String spinnerselection = ((ItemData) categorySpinnerjava.getSelectedItem()).getPlanCategorytext();
Didn't try it yet, but in theory it should work.
Try like this,
ItemData spinnerselection = (ItemData)categorySpinnerjava.getSelectedItem();
String plan = spinnerselection.getPlanCategorytext();
Override getItem() in your adapter. Cause getSelectedItem() return :
adapter.getItem(position);
#Override
public String getItem(int position) {
return list.get(position);
}
Related
I can populate my spinner with the array list from API. But unable to select or populate the selected item from spinner and display to the user.
The onItemSelected method does not get the position of the selected item in the spinner.
CustomSpinnerAdapter.java
public class CustomSpinnerAdapter extends BaseAdapter {
Context context;
List<String> userNames;
LayoutInflater inflter;
public CustomSpinnerAdapter(Context applicationContext, List<String> userNames) {
this.context = applicationContext;
this.userNames = userNames;
inflter = (LayoutInflater.from(applicationContext));
}
#Override
public int getCount() {
return userNames.size();
}
#Override
public Object getItem(int i) {
return userNames.get(i);
}
#Override
public long getItemId(int i) {
return 0;
}
#NonNull
#SuppressLint({"ViewHolder", "InflateParams"})
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = inflter.inflate(R.layout.custom_spinner_item, null);
CustomTextView names = (CustomTextView) view.findViewById(R.id.tv_spinner_item);
names.setText(userNames.get(i));
return view;
}
}
My logic in fragment.
private SpinnerAdapter customAdapter;
private List<String> eqIds = new ArrayList<>;
apiInterface = ApiRequest.createService(ApiInterface.class);
Call<EquipmentTypeModel> call = apiInterface.getEquipmentType("application/json", token, id);
call.enqueue(new Callback<EquipmentTypeModel>() {
#Override
public void onResponse(Call<EquipmentTypeModel> call, Response<EquipmentTypeModel> response) {
if (response.isSuccessful()) {
eqIds.addAll(response.body().getData().getEquipmentList().getEquipIds());
}
}
#Override
public void onFailure(Call<EquipmentTypeModel> call, Throwable t) {
}
});
customAdapter = new CustomSpinnerAdapter(mContext, eqIds);
spTypeModel.setAdapter(customAdapter);
spTypeModel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(mContext, String.valueOf(parent.getAdapter().getItem(position)), Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
To get the selected value from spinner you should you
String selectedValue = spTypeModel.getSelectedItem().toString();
or
String selectedValue = String.valueOf(parent.getAdapter().getItem(position));
instead of
String selectedValue = String.valueOf(position);
Update: Change getItem method in your custom adapter to
#Override
public Object getItem(int i) {
return userNames.get(i);
}
Update 2: I saw your problem, please change your code.
private SpinnerAdapter customAdapter;
to
private CustomSpinnerAdapter customAdapter;
then add this line after you add new data to your adapter.
eqIds.addAll(response.body().getData().getEquipmentList().getEquipIds());
customAdapter.notifyDataSetChanged(); // Add this line to notify your adapter about new data
Update 3: From your xml file, because your spinner height is 18dp.
In spinner you set padding to 4dp (will be 8dp for top and bot)
In custom text view you also set padding 4dp (will be 8dp for top and bot)
So you only have equal or less than 2dp to display text content, it really small that why you can't see the content.
You can set your spinner height to wrap_content or keep current height but remove padding from spinner or from the custom text view. It's up to you.
Try if this works (It will show you the value, not the position)
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(mContext, parent.getItemAtPosition(position).toString(), Toast.LENGTH_SHORT).show();
}
I have a problem with a custom adapter for put hint in spinner.
I've made a class AdapterSpinnerhint that extends ArrayAdapter:
public class AdapterSpinnerHint extends ArrayAdapter {
int labelHint;
int textViewId;
int layout;
ArrayList<String> mItems;
Context context;
public AdapterSpinnerHint(Context context, int spinner_layout, int field, ArrayList<String> list, int label) {
super(context, spinner_layout, list);
textViewId = field;
labelHint = label;
layout = spinner_layout;
mItems=list;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v;
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(layout, null);
if (position == getCount()) {
((TextView)v.findViewById(textViewId)).setText(labelHint);
((TextView)v.findViewById(textViewId)).setHint((Integer) getItem(getCount())); //"Hint to be displayed"
}
return v;
}
#Override
public int getCount() {
return mItems.size()-1; // you dont display last item. It is used as hint.
}
And in my activity I've created a function for Create spinner
private void createSpinnerCustomer(JSONArray customers) {
Spinner spinner = (Spinner) findViewById(R.id.customers_spinner);
ArrayList<String> customersList=new ArrayList<String>();
for(int i=0;i<customers.length();i++){
try {
customersList.add(customers.getJSONObject(i).getString("name"));
} catch (JSONException e) {
e.printStackTrace();
}
}
customersList.add(String.valueOf(R.string.customer_label));
assert spinner != null;
AdapterSpinnerHint adapter=new AdapterSpinnerHint(
getApplicationContext(), R.layout.spinner_layout, R.id.txt, customersList, R.string.customer_label);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
spinner.setAdapter(adapter);
spinner.setSelection(adapter.getCount());
}
I would create a general adapter for all spinner that include hint.
But I'm getting this error on AdapterSpinnerHint in this line:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
In your function - getView see this line - .setHint((Integer)getItem(getCount()));
.setHint(string) requires string as a parameter and you are passing an Integer by parsing a string as an Integer.
do like this
.setHint(getItem(getCount));
When you are calling super in the constructor of ArrayAdapter and passing the list of strings as a parameter, basically you are telling the ArrayAdapter that they type of objects that will be in the list will be String. So when you do getItem(), it will be returning a String
I've changed approach:
in my activity:
private void createSpinnerCustomer(JSONArray customers) {
Spinner spinner = (Spinner) findViewById(R.id.customers_spinner);
AdapterSpinnerHint adapter2 = new AdapterSpinnerHint(ActivityActivity.this, android.R.layout.simple_spinner_dropdown_item, "Customers", customers, "name");
adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
assert spinner != null;
spinner.setAdapter(adapter2);
spinner.setSelection(adapter2.getCount());
}
And my adapter:
public class AdapterSpinnerHint extends ArrayAdapter {
String labelHint;
JSONArray mItems;
String property;
public AdapterSpinnerHint(Context context, int spinner_layout, String label, JSONArray list, String getValue) {
super(context, spinner_layout);
labelHint = label;
mItems = list;
property = getValue;
addValue(mItems);
}
private void addValue(JSONArray customers) {
for(int i=0;i<customers.length();i++){
try {
this.add(customers.getJSONObject(i).getString(property));
} catch (JSONException e) {
e.printStackTrace();
}
}
this.add(labelHint);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
if (position == getCount()) {
((TextView)v.findViewById(android.R.id.text1)).setText("");
((TextView)v.findViewById(android.R.id.text1)).setHint((String) getItem(getCount())); //"Hint to be displayed"
}
return v;
}
#Override
public int getCount() {
return super.getCount()-1; // you dont display last item. It is used as hint.
}
}
And it work, but I've to put cast on setHint((String) getItem(getCount())
because I cant' compile app without.
I am trying to implement a listview with a custom adapter. The problem is that it crashes whenever a onItemClickListener event is triggered.
java.lang.ClassCastException: imp.translator.diana.lang.CardItemData
cannot be cast to java.lang.String
at imp.translator.diana.lang.Speak$1.onItemClick(Speak.java:41)
at android.widget.AdapterView.performItemClick
This is my class:
final ListView list = (ListView) findViewById(R.id.list_view);
list.addHeaderView(new View(this));
list.addFooterView(new View(this));
BaseInflaterAdapter<CardItemData> adapter = new BaseInflaterAdapter<CardItemData>(new CardInflater());
CardItemData data = new CardItemData("Translate");
adapter.addItem(data, false);
CardItemData data2 = new CardItemData("Voice to Text");
adapter.addItem(data2, false);
CardItemData data3 = new CardItemData("Record");
adapter.addItem(data3, false);
CardItemData data4 = new CardItemData("Info");
adapter.addItem(data4, false);
list.setAdapter(adapter);
list.setClickable(true);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView myAdapter, View myView, int position, long mylng) {
String selectedFromList = (String) (myAdapter.getItemAtPosition(position));
}
});
and my adapter:
public class BaseInflaterAdapter<T> extends BaseAdapter
{
private List<T> m_items = new ArrayList<T>();
private IAdapterViewInflater<T> m_viewInflater;
public BaseInflaterAdapter(IAdapterViewInflater<T> viewInflater)
{
m_viewInflater = viewInflater;
}
public BaseInflaterAdapter(List<T> items, IAdapterViewInflater<T> viewInflater)
{
m_items.addAll(items);
m_viewInflater = viewInflater;
}
public void setViewInflater(IAdapterViewInflater<T> viewInflater, boolean notifyChange)
{
m_viewInflater = viewInflater;
if (notifyChange)
notifyDataSetChanged();
}
public void addItem(T item, boolean notifyChange)
{
m_items.add(item);
if (notifyChange)
notifyDataSetChanged();
}
public void addItems(List<T> items, boolean notifyChange)
{
m_items.addAll(items);
if (notifyChange)
notifyDataSetChanged();
}
public void clear(boolean notifyChange)
{
m_items.clear();
if (notifyChange)
notifyDataSetChanged();
}
#Override
public int getCount()
{
return m_items.size();
}
#Override
public Object getItem(int pos)
{
return getTItem(pos);
}
public T getTItem(int pos)
{
return m_items.get(pos);
}
#Override
public long getItemId(int pos)
{
return pos;
}
#Override
public View getView(int pos, View convertView, ViewGroup parent)
{
return m_viewInflater != null ? m_viewInflater.inflate(this, pos, convertView, parent) : null;
}
}
and the CardItemData:
public class CardItemData
{
private String m_text1;
public CardItemData(String text1)
{
m_text1 = text1;
}
public String getText1()
{
return m_text1;
}
}
Any idea what might be wrong here?
java.lang.ClassCastException: imp.translator.diana.lang.CardItemData
cannot be cast to java.lang.String
the above exception was due to
String selectedFromList = (String) (myAdapter.getItemAtPosition(position)); here you are try to convert CardItemData into String
try this:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView myAdapter, View myView, int position, long mylng) {
CardItemData selectedFromList = (CardItemData) (myAdapter.getItemAtPosition(position));
String pos = selectedFromList.getText1();
}
});
Any idea what might be wrong here?
your getItem is returning T which is, in your case, an instance of CardItemData, but here:
String selectedFromList = (String) (myAdapter.getItemAtPosition(position));
you are casting it to String. You probably want to cast it to CardItemData. Btw, Java supports covariant return types, so you should be able to use
#Override
public T getItem(int pos) {
return m_items.get(pos);
}
Its a typecast issue, you are type casting " CardItemData " to " String "
String selectedFromList = (String) (myAdapter.getItemAtPosition(position));
use "getItem" method to get clicked " CardItemData " item.
Check the link given below
Android Docs link
I have an arrayList of this class:
public class Lawyer extends DbHelper{
private int id;
private String fullName;
private String mobile;
private Context context;
public Lawyer(Context context,int id, String fullName, String mobile) {
super(context);
this.id = id;
this.fullName = fullName;
this.mobile = mobile;
this.context = context;
}
}
My arrayList is filled with information of a few people. Is it possible to have a spinner filled with "fullName" of all lawyers in the array list?
Currently I have this code to fill my spinner with static data from a simple array:
String [] items={"Lawyer1","Lawyer2","Lawyer3","Lawyer4","Lawyer5"};
final Spinner lstLawyers;
lstLawyers=(Spinner)findViewById(R.id.lstLawyers);
lstLawyers.setAdapter( new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item,items));
lstLawyers.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
EditText txtMessage = (EditText) findViewById(R.id.txtMessage);
txtMessage.setText(lstLawyers.getSelectedItem().toString());
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
Look at SpinnerAdaper.
If you have an alTypes ArrayList with Lawyer classes (with fullName, mobile etc...)
you should extend SpinnerAdapter (see AdapterForSpinner1 below)
and then set it to your spinner like this:
AdapterForSpinner1 spinad1 = new AdapterForSpinner1(activity, alTypes);
lstLawyers.setAdapter(spinad1);
AdapterForSpinner1
class AdapterForSpinner1 extends BaseAdapter implements SpinnerAdapter {
/**
* The internal data (the ArrayList with the Objects).
*/
private final List<Lawyer> data;
Context mContext;
public AdapterForSpinner1(Context context, List<Lawyer> data){
this.data = data;
mContext=context;
}
/**
* Returns the Size of the ArrayList
*/
#Override
public int getCount() {
return data.size();
}
/**
* Returns one Element of the ArrayList
* at the specified position.
*/
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int i) {
return i;
}
/**
* Returns the View that is shown when a element was
* selected.
*/
#Override
public View getView(int position, View recycle, ViewGroup parent) {
TextView text;
if (recycle != null){
// Re-use the recycled view here!
text = (TextView) recycle;
} else {
// No recycled view, inflate the "original" from the platform:
LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
text = (TextView) (li.inflate(android.R.layout.simple_dropdown_item_1line, parent, false) );
}
text.setTextColor(Color.BLACK);
text.setText(data.get(position).getFullname());
return text;
}
}
I have a listview and i am populating the data to the list view form DB using custom adapter. Its working fine, but when i click on the list item, i want to get the ID of the item which is clicked to pass it on to the next activity to do some stuff. But when i click on list item, i am not able to get the ID.
Any idea why is this happening?
my list listener:
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View view, int position,
long id) {
Intent intent = new Intent(MainActivity.this,
CountryActivity.class);
intent.putExtra("countryId", adapter.getItem(position).getId());//here i am getting error saying
//The method getId() is undefined for the type Object.
startActivity(intent);
}
});
But i have defined my countries.java (POJO) for type specification
public class Countries {
Integer id;
String countryName = "", countryIcon = "";
public Countries(Integer id, String countryName, String countryIcon) {
this.id = id;
this.countryName = countryName;
this.countryIcon = countryIcon;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public String getCountryIcon() {
return countryIcon;
}
public void setCountryIcon(String countryIcon) {
this.countryIcon = countryIcon;
}
}
i am fetching data out of cursor obj (visas) from the below code:
names = new ArrayList<Countries>();
do {
country = new Countries(Integer.parseInt(visas.getString(0)),
visas.getString(1), visas.getString(2));
// Log.d("VISA", visas.getString(0));
names.add(country);
} while (visas.moveToNext());
here is my adapter code:
public class VisaAdapter extends ArrayAdapter<Countries> {
private final Context context;
private final ArrayList<Countries> values;
Resources resc = getContext().getResources();
public VisaAdapter(Context context, ArrayList<Countries> values) {
super(context, R.layout.list_item, values);
this.context = context;
this.values = values;
}
#Override
public Countries getItem(int position) {
return values.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.list_item, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
ImageView imageView = (ImageView) rowView.findViewById(R.id.logo);
textView.setText(values.get(position).getCountryName());
// Change icon based on name
String icon = values.get(position).getCountryIcon();
int resIcon = resc.getIdentifier(icon, "drawable", "com.m7.visaapp");
rowView.setBackgroundResource(R.drawable.list_view_places_row);
imageView.setImageResource(resIcon);
return rowView;
}
}
You must cast the getItem(position) return value to a Countries object.
Change this:
intent.putExtra("countryId", adapter.getItem(position).getId());
To this:
Countries countries = (Countries)adapter.getItem(position);
intent.putExtra("countryId", countries.getId());
Update:
Actually, after reading #Tushar's comment, I think you should make names a VisaAdapter instead of an ArrayList<Countries>(). Then, your original line of code, above, should work as-is.
adapter.getItem(position)
function Returns an Object so type cast it to Country like
(Countries)adapter.getItem(position)