I would like to color each item´s backround of the spinner individual.
The items are set with this code:
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.duesentypen, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
The hex values are stored in an array. Whereas the index count refers to the item count. E.g.:
String[] hex = {"#886da8", "#ffc3cf","#ef9b00", "#2bb430", "#f7dc01", "#bc65a2", "#487ebf","#e00124","#b36634","#949494", "#ffffff","#000000","#4bbbd0", "#8b6d9f", "#8ccff4"};
//color for the first spinner item: hex[0]
//color for the second spinner item: hex[1]
How could I do that in the best way?
You need to create a custom Spinner adapter and override getView() to set the color and text of each item.
Here I am wrapping colors around the array of colors using the modulus operator (%) in order to avoid IndexOutOfBoundsExecption if the items are greater than the available colors.
The custom adapter
public class ColorAdapter extends BaseAdapter {
private ArrayList<Integer> mColors;
private String[] mItems;
ColorAdapter2(String[] items) {
mItems = items;
String[] hex = {"#886da8", "#ffc3cf", "#ef9b00", "#2bb430", "#f7dc01", "#bc65a2", "#487ebf", "#e00124", "#b36634", "#949494", "#ffffff", "#000000", "#4bbbd0", "#8b6d9f", "#8ccff4"};
mColors = new ArrayList<>();
for (String color : hex) {
mColors.add(Color.parseColor(color));
}
}
#Override
public int getCount() {
return mItems.length;
}
#Override
public Object getItem(int args) {
return mColors.get(args);
}
#Override
public long getItemId(int args) {
return args;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(android.R.layout.simple_spinner_dropdown_item, null);
holder = new ViewHolder();
holder.textView = convertView.findViewById(android.R.id.text1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setBackgroundColor(mColors.get(position % mColors.size()));
holder.textView.setText( mItems[position]);
return convertView;
}
/* Return spinner text of the item at particular position*/
public String getItemAtPosition(int position) {
if (position > -1 && position < mItems.length)
return mItems[position];
else
return null;
}
static class ViewHolder {
TextView textView;
}
}
Usage
Spinner spinner = findViewById(R.id.spinner);
spinner.setAdapter(new ColorAdapter(getResources().getStringArray(R.array.myItems)));
strings.xml
<resources>
<string name="app_name">Color Activity</string>
<string-array name="myItems">
<item>item1</item>
<item>item2</item>
<item>item3</item>
<item>item4</item>
<item>item5</item>
</string-array>
</resources>
Result
Edit
How can I get the text of the selected item?
spinner.getItemAtPosition(spinner.getSelectedItemPosition()).toString()
isn´t working anymore. The returned value is a big number.
Now as we created a custom adapter, then you have to customize any related data and you can't rely on the API of the default Spinner adapter; so I've added a getItemAtPosition() method above at the custom adapter that takes a position, and returns the text of this item.
Usage
String item = ((ColorAdapter)spinner.getAdapter()).getItemAtPosition(position));
And you can get it whenever an item is selected:
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, "onItemSelected: " +
((ColorAdapter)spinner.getAdapter()).getItemAtPosition(position));
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Try to change color according to Position.
final List<String> plantsList = new ArrayList<>(Arrays.asList(plants));
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.duesentypen, android.R.layout.simple_spinner_item){
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
View view = super.getDropDownView(position, convertView, parent);
TextView tv = (TextView) view;
switch(position) {
case 0:
tv.setTextColor(Color.parseColor("#FF7C7967"));
case 1:
tv.setTextColor(Color.parseColor("#FF7C7967"));
}
return view;
}
};
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
Related
I've tried so many things and have spent countless hours on this issue without any luck.
What I have is a ListView inside a fragment. The ListView starts off empty, but when a button is clicked in the parent Fragment, a row is generated in the ListView containing both a TextView(generated via user input) and a Spinner. The Spinner added to each row is identical using the same set of pre-built data. The row is then sorted alphabetically based on the name fed into the TextView. The rows in the ListView can also be deleted with the click of other set parameters from the parent Fragment.
All of this works perfectly fine.
What I need to do is to uniquely identify each spinner object that is added so that the user can save and recall the positional value of each spinner object that is associated with each name within the containing row of the ListView.
What I have been able to do is, as the list grows, point to the very first spinner object, the very last spinner object, and the spinner object that last had an item selected, but I cannot figure out how to point to each specific spinner object in the row.
P.S. I am able to point to each TextView object being that they are names that have been added to an ArrayList.
Working with arrays generally works well for me, but while I know how to store spinner position values into an array so that I can have them retrieved for specific spinners, I can't figure out how to store them for multiples of essentially the same spinner... I feel I need to create an ArrayList of Spinners containing each spinner as it's added, and while I know how to access the positional value of the spinner, I don't know how to access the positional value of each spinner contained within an array of spinners, if that makes sense.
I've tried setId and setTag [using position] for each spinner as it's generated, but with no luck. What seems to happen is the Id and Tag only stick to the last spinner added.
I've also tried using Intent but with no such luck. The app crashes every time I try passing it out of the child Fragment.
Any help would be greatly appreciated.
Here's some code for the problem points:
parent fragment -
charSav.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
relationsListArray.add(charNameString);
if (frag2_3.relationsSpinner != null && frag2_3.currentRowSpinner != null) {
for (int i = 0; i < frag2_3.relationsListView.getCount(); i++) {
Toast.makeText(getActivity(), "row " +
// outputs outputs name displayed in each textview within each row
relationsListView.getItemAtPosition(i) + "\nT. " +
// outputs top most spinner item selected
currentRowSpinner.getSelectedItem().toString() + "\nB. " +
// outputs bottom most spinner item selected
relationsSpinner.getSelectedItem().toString() + "\nL. " +
// outputs the last spinner item selected whether it be first, last, or somewhere in the middle
relationsItem, Toast.LENGTH_LONG).show();
}
}
}
child fragment containing adapter class -
public class RelationsListViewAdapter extends ArrayAdapter<String> {
HashMap<String, Integer> mIdMap = new HashMap<String, Integer>();
public RelationsListViewAdapter(Context context, int textViewResourceId, ArrayList<String> objects) {
super(context, textViewResourceId, objects);
relationsListArray = objects;
for (int i = 0; i < objects.size(); ++i) {
mIdMap.put(objects.get(i), i);
}
}
#Override
public int getCount() { return relationsListArray.size(); }
#Override
public String getItem(int position) { return relationsListArray.get(position); }
#Override
public long getItemId(int position) { String item = getItem(position); return mIdMap.get(item); }
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.listview_spinner_row, null);
}
// Spinner Adapter
adapterRelationsSpinner = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.preStoryPlanRelations)){
#Override
public boolean isEnabled(int position){
if(position == 0) { return false; }
else { return true; }
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
View view = super.getView(position, convertView, parent);
TextView tv = (TextView) view.findViewById(android.R.id.text1);
if (position == 0) {
tv.setTextColor(Color.parseColor("#424242"));
}
tv.setTextSize(12);
tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
return view;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView tv = (TextView) view.findViewById(android.R.id.text1);
if (position == 0) {
tv.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
tv.setTextColor(Color.parseColor("#424242"));
tv.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
}
else {
tv.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
tv.setTextColor(Color.BLACK);
tv.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);
}
return view;
}
};
TextView tv = (TextView) view.findViewById(R.id.row_item_textview);
tv.setText(relationsListArray.get(position));
relationsSpinner = (Spinner) view.findViewById(R.id.row_item_spinner);
relationsSpinner.setAdapter(adapterRelationsSpinner);
relationsSpinner.setTag(R.id.row_item_spinner+position);
relationsSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
selectedRowView = (ViewGroup) relationsListView;
currentRowSpinner = (Spinner) selectedRowView.findViewById(R.id.row_item_spinner);
relationsItem = currentRowSpinner.getItemAtPosition(i).toString();
relationsRowPosition = relationsListView.getItemAtPosition(position).toString();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
// TODO Auto-generated method stub
}
});
return view;
}
}
The method onItemSelected doesn't work and I don't know why.
Below is my code.
Array adapter:
public class MyListAdapter extends ArrayAdapter {
Spinner spinner;
ListView listView;
/*public MyListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}*/
public MyListAdapter(Context context) {
super(context, R.layout.single_listview_item);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
spinner = (Spinner) convertView.findViewById(R.id.simpleSpinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
getContext(),
R.array.country_arrays,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
System.out.println("ciao1");
// spinner.setOnItemSelectedListener(this);
return row;
}
/* #Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selState = (String) spinner.getSelectedItem();
System.out.println(selState);
Toast.makeText(
getContext(),
"Clicked on Planet: " + selState + "", Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}*/
}
fragment:
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_list2, container, false);
listView = (ListView) rootView.findViewById(R.id.listview);
ListAdapter listAdapter = new MyListAdapter(getContext());
listView.setAdapter(listAdapter);
// listView.setOnItemClickListener(this);
listView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> parent, View view, int position, long i)
{
listView.setSelection(position);
String selState = (String) listView.getSelectedItem();
Toast.makeText(
getContext(),
"Clicked on Planet: " + selState + "", Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
On ListViews you use onItemClicked. OnItemSelected is for Spinners. It's one of those Android nuisances...
In your method of setting OnItemSelectedListener(this) within the ArrayAdapter, I believe the issue is that, because every spinner in the list references the same instance of MyListAdapter, your OnItemSelected method is not distinguishing which spinner within your list was actually selected from-- it just references the spinner object that was last set to the MyListAdapter.spinner reference, which should be the last one in the list.
To remedy this, don't use spinner.getSelectedItem(). Instead use ((Spinner) parent).getSelectedItem(), since the parent object will be the actual spinner selected from. And at that point, you should make the spinner variable local to the getView method.
In the method of calling listView.setOnItemSelectedListener(...) in the fragment, I expect you meant to have listView.setOnItemClickListener(...), but that will listen for a click on a row in your list, not a selection from a spinner.
To detect a selection from one of your spinners, make the first modification above. To detect a click on a row in your listView as well, change to listView.setOnItemClickListener. Without more context for your objective or the actual errors occurring, it's hard to tell if both or just the first is desired.
EDIT:
From your comments, I think you should have this in your MyListAdapter:
public class MyListAdapter extends ArrayAdapter implements AdapterView.OnItemSelectedListener {
public MyListAdapter(Context context) {
super(context, R.layout.single_listview_item);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
Spinner spinner = (Spinner) row.findViewById(R.id.simpleSpinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
parent.getContext(),
R.array.country_arrays,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
return row;
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selState = (String) ((Spinner) parent).getSelectedItem();
System.out.println(selState);
Toast.makeText(
parent.getContext(),
"Clicked on Planet: " + selState + "", Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
And this in your fragment (no listeners):
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_list2, container, false);
listView = (ListView) rootView.findViewById(R.id.listview);
ListAdapter listAdapter = new MyListAdapter(getContext());
listView.setAdapter(listAdapter);
I use simple_list_item_1 to show list in my app. I want to change the list so each element in list will have an image + radio button in addition to his text which taken from Const.practisesList.
This is the code now :
ListAdapter listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, Const.practisesList);
final ListView tests_list = (ListView)findViewById(R.id.tests_list);
tests_list.setAdapter(listAdapter);
tests_list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
switch(position){
case Const.TEST_TYPE1_MATH:
p = practiseCreator(1)
break;
case Const.TEST_TYPE4_INSTRUCTIONS:
p = practiseCreator(4)
break;
}
}
});
What is the way to do it?
thanks
Create custom layout for your row. Implement custom adapter extended from ArrayAdapter.
private class SchemeAdapter extends ArrayAdapter<String> {
private int layout;
public SchemeAdapter(final Context context, final List<String> objects) {
//row layout id, content view id
super(context, R.layout.list_row_practice, R.id.list_row_practice_name,
objects);
layout = R.layout.list_row_practice;
}
#Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final View row =
(convertView == null) ? getLayoutInflater().inflate(layout, parent, false) :
convertView;
if (row != null) {
final TextView name = (TextView) row.findViewById(R.id.list_row_practice_name);
//set here your text, image view src and radio button value.
}
return row;
}
}
Android not parsing JSON data into ListView, I am using this tutorial and just made few changes in ListViewAdapter.java
Like in my new implementation i used ViewHolder, and my code looks like this:
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context context;
ArrayList<HashMap<String, String>> data;
ImageLoader imageLoader;
HashMap<String, String> resultp = new HashMap<String, String>();
ViewHolder holder;
public ListViewAdapter(Context context,
ArrayList<HashMap<String, String>> arraylist) {
this.context = context;
data = arraylist;
imageLoader = new ImageLoader(context);
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
static class ViewHolder {
public ViewHolder(View convertView) {
// TODO Auto-generated constructor stub
}
TextView rank;
TextView country;
TextView population;
ImageView flag;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// Declare Variables
// Avoid unneccessary calls to findViewById() on each row, which is expensive!
holder = null;
/*
* If convertView is not null, we can reuse it directly, no inflation required!
* We only inflate a new View when the convertView is null.
*/
if (convertView == null) {
convertView = ((Activity) context).getLayoutInflater().inflate(R.layout.listview_item, null);
// Create a ViewHolder and store references to the two children views
holder = new ViewHolder(convertView);
holder.rank = (TextView) convertView.findViewById(R.id.rank);
holder.country = (TextView) convertView.findViewById(R.id.country);
holder.population = (TextView) convertView.findViewById(R.id.population);
// Locate the ImageView in listview_item.xml
holder.flag = (ImageView) convertView.findViewById(R.id.flag);
// The tag can be any Object, this just happens to be the ViewHolder
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// Capture position and set results to the TextViews
holder.rank.setText(resultp.get(MainActivity.RANK));
holder.country.setText(resultp.get(MainActivity.COUNTRY));
holder.population.setText(resultp.get(MainActivity.POPULATION));
// Capture position and set results to the ImageView
// Passes flag images URL into ImageLoader.class
imageLoader.DisplayImage(resultp.get(MainActivity.FLAG), holder.flag);
// Capture ListView item click
return convertView;
}
}
Edited: Click on ListItem code
#Override
protected void onPostExecute(Void args) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this, arraylist);
// Set the adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
listview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// code to handle click
}
});
}
But i don't no why i am not getting data into ListView !
The issue is that you are not assigning the HashMap to `resultp that has the information you want to display
public View getView(final int position, View convertView, ViewGroup parent) {
holder = null;
if (convertView == null) {
convertView = ((Activity) context).getLayoutInflater().inflate(R.layout.listview_item, null);
holder = new ViewHolder(convertView);
holder.rank = (TextView) convertView.findViewById(R.id.rank);
holder.country = (TextView) convertView.findViewById(R.id.country);
holder.population = (TextView) convertView.findViewById(R.id.population);
holder.flag = (ImageView) convertView.findViewById(R.id.flag);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Here's the change
resultp = data.get(position);
// Here's the change
holder.rank.setText(resultp.get(MainActivity.RANK));
holder.country.setText(resultp.get(MainActivity.COUNTRY));
holder.population.setText(resultp.get(MainActivity.POPULATION));
imageLoader.DisplayImage(resultp.get(MainActivity.FLAG), holder.flag);
return convertView;
}
To attach OnItemClickListener to your ListView, in the Activity that contains the ListView, add the following:
public class MyActivity implements OnItemClickListener{
ListView lv;
#Override
public void onCreate(Bundle savedInstanceState() {
....
....
// lv initialized here
// adapter of lv set here
attachListeners();
}
private void attachListeners() {
....
....
// attach listeners to other views if you like
lv.setOnItemClickListener(this);
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// code to handle click
}
}
Or, if you don't want your Activity to implement OnItemClickListener, then,
public class MyActivity {
ListView lv;
#Override
public void onCreate(Bundle savedInstanceState() {
....
....
// lv initialized here
// adapter of lv set here
attachListeners();
}
private void attachListeners() {
....
....
// attach listeners to other views if you like
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// code to handle click
}
});
}
}
First of all try to fix this:
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
I have a ListView of Spinners I'm trying to get the selected values out of. Some of the Spinners have the first selection automatically selected if there is only 1 item in the list, so I feel
setOnItemSelectedListener
won't necessarily work? Either way, I'm unsure how to code this scenario. Even if I had the listener coded correctly, How do I use it in my class to work with the adapter?
CustomAdapter
public class CustomPLNViewAdapter extends BaseAdapter{
private static ArrayList<ArrayList<String>> partLotNumbersArrayList;
private static ArrayList<String> partNames;
private LayoutInflater mInflater;
private Context myContext;
public CustomPLNViewAdapter(Context context, ArrayList<ArrayList<String>> results, ArrayList<String> parts){
partLotNumbersArrayList = results;
partNames = parts;
mInflater = LayoutInflater.from(context);
myContext = context;
}
#Override
public int getCount() {
return partLotNumbersArrayList.size();
}
#Override
public Object getItem(int position) {
return partLotNumbersArrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.view_assembly_parts, null);
holder = new ViewHolder();
holder.txtName = (TextView) convertView.findViewById(R.id.partName);
holder.spinner = (Spinner) convertView.findViewById(R.id.LotNumbers);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtName.setText(partNames.get(position));
ArrayAdapter<String> adp1=new ArrayAdapter<String>(myContext, android.R.layout.simple_list_item_1, partLotNumbersArrayList.get(position));
adp1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//set the adapter to the spinnner
holder.spinner.setAdapter(adp1);
//if there is only one other part besides "" then set that as default part
if(partLotNumbersArrayList.get(position).size() == 2){
holder.spinner.setSelection(1);
}
return convertView;
}
static class ViewHolder {
TextView txtName;
Spinner spinner;
}
}
Where I am calling the code. Obviously I get an error here because an ArrayList cannot be cast to Spinner, but I'm unsure how to get the View of the Adapter and then the subsequent spinner?
// save button click event
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Log.d("lv count", Integer.toString(lv.getCount()));
//iterate through listview,
for(int i = 0; i < lv.getCount(); i++){
Spinner temp = (Spinner) lv.getItemAtPosition(i);
Log.d("lv isItemCheck", temp.getSelectedItem().toString());
}
//check to make sure all items have been selected
if(!checkAllParts()){
Toast.makeText(getApplicationContext(), "Please Select All List Items", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "All items have been selected", Toast.LENGTH_SHORT).show();
}
//go back to previous intent, return 100 that saving succeeded
//close intent
}
});