In the wake of a question asked yesterday, I am still attempting to write to little app without any xml whatsoever. Here is my attempt (origin code here), that works, but fails because of "Resources$NotFoundException" if the two commented out lines replace the two lines before them:
public class SpinnerExample extends Activity {
private Spinner spinner;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this);
setContentView(linearLayout);
spinner = new Spinner(this);
linearLayout.addView(spinner);
List<String> list = new ArrayList<String>();
list.add("Android");
list.add("Java");
list.add("Spinner Data");
list.add("Spinner Adapter");
list.add("Spinner Example");
TextView textView = new TextView(this);
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,list);
//ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, 0x7f030012, list);
CheckedTextView checkedTextView = new CheckedTextView(this);
checkedTextView.setId(0x7f030022); // arbitrary value
dataAdapter.setDropDownViewResource(android.R.layout.spinner_dropdown);
//dataAdapter.setDropDownViewResource(0x7f030012);
spinner.setAdapter(dataAdapter);
}
// Add spinner data
public void addListenerOnSpinnerItemSelection(){
spinner.setOnItemSelectedListener(new CustomOnItemSelectedListener());
}
}
The xml resources refer to:
android.R.layout.simple_spinner_item:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="?android:attr/spinnerItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:textAlignment="inherit"/>
android.R.layout.spinner_dropdown:
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="?android:attr/dropdownListPreferredItemHeight"
android:ellipsize="marquee"
android:textAlignment="inherit"/>
Can somebody explain to may why this exception occurs and how to prevent it and have an app without xml?
Thanks in advance.
UPDATE: added the suggestion of 323go and made this class:
public class MyArrayAdapter<T> extends ArrayAdapter<T> {
List<T> list;
public MyArrayAdapter(Context context, int resource, List<T> objects) {
super(context, resource, objects);
// TODO Auto-generated constructor stub
list = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
CheckedTextView tv = new CheckedTextView( this.getContext() );
tv.setText( "This is item " + position );
return tv;
}
}
...and obviously replacede ArrayAdapter with MyArrayAdapter in the original code. The result is that the spinner is shown with "This is item 0", but still gives the original exception is you tap on the spinner.
UPDATE-2
The question is half solved, I can get rid of the first xml reference with this ArrayAdapter:
public class MyArrayAdapter<T> extends ArrayAdapter<T> {
List<T> list;
public MyArrayAdapter(Context context, int resource, List<T> objects) {
super(context, resource, objects);
list = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
CheckedTextView tv = new CheckedTextView( this.getContext() );
tv.setText(list.get(position).toString());
return tv;
}
}
Now the code in SpinnerExample can be modified like this:
TextView textView = new TextView(this);
MyArrayAdapter<String> dataAdapter = new MyArrayAdapter<String>(this, textView.getId(), list);
New is that I learned that Android attributes an id to a widget created in code as well. So no need for this:
textView.setId(0x7f030012); // arbitrary int
You're going about it the wrong way. XML or not, you still need IDs if you want to access elements by ID. Hardcoding IDs is not a good idea, and there's nothing wrong using the android.R.id... constants.
Further, the reason why your code fails is that setDropDownViewResource() expects the id of a layout, not of an actual view. A layout will tell Android what views to create through the LayoutInflater. If your code worked, then the same view would be referenced by id for each of the Spinner rows.
If you want to completely handle the UI creation yourself, you'll need to override the ArrayAdapter so that getView returns the view for each element. It might be easier, however, to just use the android.R layouts, unless you need something different.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView( context, parent );
tv.setText( "This is item " + position );
return tv;
}
Related
Appreciate some help here on a spinner issue I'm getting.
The list appears fine when clicking on the drop-down arrow. However, when clicking on the selection, the spinner view still appears as blank. The selection's text does not appear. What gives?
On Android Studio's preview, it appears fine from my assigned android:entries. Screenshot here: (https://imgur.com/a/vmdPA)
As you can see, the background is grey, and everything else is white background as well. So I don't think the color is the issue here.
I've checked and changed background colors, and even removed some widget so that I can see what if anything was blocking the selection to appear.
Is there something aside from the normal declaration of Spinner, Arraylist, creating a new arrayadapter, setDropDwonViewResource, setting the arrayadapter to the spinner that I need to do?
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, spinnerArray);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mStoreSpinner.setAdapter(adapter);
The XML for the spinner is also as "simple" as can be:
<Spinner
android:id="#+id/s_spinner"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#+id/recyclerord"
app:layout_constraintLeft_toRightOf="#+id/orderID"
app:layout_constraintTop_toBottomOf="#+id/header"
app:layout_constraintRight_toRightOf="#+id/ConstraintLayout"
android:visibility="visible"
android:layout_marginStart="0dp"
android:entries="#array/array_test"
>
</Spinner>
Thank you.
Edited:
This is what I've added.
mStoreSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View v, int postion, long arg3) {
// TODO Auto-generated method stub
String spinnerValue= parent.getItemAtPosition(postion).toString();
Log.d(TAG, "test");
Toast.makeText(getBaseContext(), "Selected item" + spinnerValue, Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, spinnerArray);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mStoreSpinner.setAdapter(adapter);
I have not implemented the onClickListeners yet - do they need to be there before the spinner will work fine?
I guess yes.
Add a setOnItemSelectedListener to your Spinner like this :
mStoreSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View v,
int postion, long arg3) {
// TODO Auto-generated method stub
String spinnerValue= parent.getItemAtPosition(postion).toString();
Toast.makeText(getBaseContext(),
"Selected item" + spinnerValue,
Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
Also feel free to see this tutorial to understand it a little bit more
EDIT
You should follow steps :
Declare your Spinner
Spinner spinner = (Spinner) findViewById(R.id.s_spinner);
Create the ArrayAdapter
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getApplicationContext(),
spinerArray, android.R.layout.simple_spinner_item);
Set the DropDown
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Set the adapter
spinner.setAdapter(adapter);
There are two ways to implement the setOnItemSelectedListener()
Implementing its interface : implements OnItemSelectedListener
Using setOnItemSelectedListener(new OnItemSelectedListener() {...}
first of remove in xml in spinner control in this line android:entries="#array/array_test" because if you are passing in adapter in list then already spinner control containing arraylist there for remove it and used below code ...
List<String> spinnerArray=new ArrayList<>(); // hear you can add in any array.
spinnerArray.add("Color");
spinnerArray.add("abd");
spinnerArray.add("cde");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, spinnerArray);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
This is working code, may this helps you:
<Spinner
android:id="#+id/spinner"
style="?android:attr/textViewStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:spinnerMode="dialog"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#color/colorBlack"
android:textColorHint="#color/colorGray"
android:textSize="#dimen/_14sdp" />
Make custom R.layout.list_item
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/_4sdp"
android:paddingLeft="#dimen/_14sdp"
android:paddingRight="#dimen/_14sdp"
android:paddingTop="#dimen/_4sdp"
android:text="Test"
android:textColor="#color/colorGray"
android:textSize="#dimen/_14sdp" />
Set adapter like this:
SpinnerAdapter adapter = new SpinnerAdapter(mActivity, R.layout.list_item,
android.R.id.text1, yourListHere);
spinner.setAdapter(adapter);
SpinnerAdapter code:
public class SpinnerAdapter extends ArrayAdapter {
public SpinnerAdapter(#NonNull Context context, #LayoutRes int resource, #IdRes int textViewResourceId, #NonNull Object[] objects) {
super(context, resource, textViewResourceId, objects);
}
public SpinnerAdapter(#NonNull Context context, #LayoutRes int resource, #IdRes int textViewResourceId, #NonNull List objects) {
super(context, resource, textViewResourceId, objects);
}
#Override
public int getCount() {
return super.getCount();
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = super.getView(position, convertView, parent);
view.setPadding(0, view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom());
return view;
}
}
I had same problem. As per my experience with this:
If we create ArrayList suppose of String type and we used ArrayAdapter to Bind list. Then Please make sure you have converted your ArrayList to String Array.
ArrayAdapter<String> yourAdapter =
new ArrayAdapter<>(this, android.R.layout.simple_spinner_item,
yourArrayList.toArray(new String[yourArrayList.size()]));
This works!
This question already has answers here:
How to change color and font on ListView
(9 answers)
Closed 8 years ago.
Thanks all of you!! I am beginning of Android.I have a little problem.I use ListView, When I run this programe then my all List Item is White Color!!! How do this text color black or anthor please anyone help me!!
package com.example.shikkokoverflow_listview;
import android.os.Bundle;
import android.app.ListActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends ListActivity {
String[] country={"Bangladesh","usa","america","india","Florida"};
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
adapter=new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, country);
setListAdapter(adapter);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
//super.onListItemClick(l, v, position, id);
Toast.makeText(getApplicationContext(), country[position], Toast.LENGTH_LONG).show();
}
}
getListView().setCacheColorHint(Color.rgb(36, 33, 32));
Here, do these steps
Go to sdk folder \sdk\platforms\android-\data\res\layout
Copy simple_list_item_1 and paste it in your projects res\layout folder
Now open \res\layout\simple_list_item_1
Add color attribute there.
then change your
adapter=new ArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_list_item_1, country);
to
adapter=new ArrayAdapter<String>(getApplicationContext(), R.layout.simple_list_item_1, country);
Use a customized layout. Define a layout file with your own Views where you can customize your font, font color, font size, images if you need... and then simply use it in your ArrayAdapter declaration.
myAdapt = new MyArrayArrayAdapter(this, R.id.your_layout, list);
Make a new layout file in res/layout. In that make the root element, a TextView (which cannot have any child). Then set all the necessary attributes and in addition to that set android:textColor="#000000". In your code, while making the ArrayAdapter write this:
adapter=new ArrayAdapter<String>(getApplicationContext(), R.layout.new_layout, country);
setListAdapter(adapter);
You will use instead of predefined Adapter into custom list adapter the process of custom adapter is...
You can get the custom adapter in class like this...
ListView listView = (ListView)findViewById(R.id.listview);
CustomAdapter mAdapter = new CustomAdapter(this, R.layout.listitem, mListItems);//listitem is your custom layout.....
listView .setAdapter(mAdapter);
Custom adapter class you just add this....in your project...
public class CustomAdapter extends ArrayAdapter<Sample> {
public ArrayList<Sample> mlist;
public Context context;
public LayoutInflater inflater;
private LinearLayout layout;
private View view;
private View mLastView;
public CustomAdapter(Context context, int resource, ArrayList<Sample> mlist) {
super(context, resource);
this.mlist = mlist;
this.context = context;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getPosition(Sample item) {
return super.getPosition(item);
}
#Override
public Sample getItem(int position) {
return mlist.get(position);
}
#Override
public int getCount() {
return mlist.size();
}
#Override
public long getItemId(int position) {
return super.getItemId(position);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
view = inflater.inflate(R.layout.listitem, null);//listitem will be a your cutom layout here i use two textview in the same item...
layout = (LinearLayout)view.findViewById(R.id.linearlayoutSample);;
TextView text1 = (TextView) view.findViewById(R.id.item1);
TextView text2 = (TextView) view.findViewById(R.id.item2);
layout.setBackgroundColor(Color.BLACK);
text1.setText(mlist.get(position).getListitem1());
text2.setText(mlist.get(position).getListitem2());
return view;
}
}
You should make another activity with a colored textview and relate your listview to it ..... with
list1.setAdapter(new ArrayAdapter<String>(this,R.layout.row,R.id.row_txt,item));
Is it possible to inflate Textview from #android:id/text1 ?
I don't want to create own layout, I would like just get a little modified text.
Here is my code:
First, I created variable to store data
private List<HashMap<String, String>> dataCities = new ArrayList<HashMap<String, String>>();
//Hashmap with keys and values
//id - 0
//name - default
Second, I created custom adapter in onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
//...
Spinner citiesSpinner = (Spinner) findViewById(R.id.city_sp);
citiesAdapter = new CustomArrayAdapter(this, R.layout.sherlock_spinner_item, dataCities);
citiesSpinner.setAdapter(citiesAdapter);
}
Third, I created my listener. It works but after calling notifyDataSetChanged nothing happens. Why?
#Override
public void onRequestJsonResponded(RequestType type, JSONArray array) {
//my enum type
switch (type) {
case cities:
//returns hashmap in arraylist, ArrayList<HashMap<String,String>> ...
dataCities = parseJSonArray(array);
Log.d(TAG, "End of parsing");
citiesAdapter.notifyDataSetChanged();
break;
case mark:
//...
break;
case model:
break;
}
}
Here is my custom arrayadapter
private class CustomArrayAdapter extends ArrayAdapter<HashMap<String, String>> {
public CustomArrayAdapter(Context context, int textViewResourceId, List<HashMap<String, String>> objects) {
super(context, textViewResourceId, objects);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
View v = layoutInflater.inflate(R.layout.sherlock_spinner_item, null);
TextView tv = (TextView)v.findViewById(android.R.id.text1);
tv.setText(getItem(position).get("name"));
return v;
}
}
Could someone tell me why do I get blank spinner data? (Spinner is empty). And how I get modified text without creating new layout? I would like just to use sherlock spinner item layout. Please help.
Simple, the list in your adapter is not the same as the list that you retrieved:
//In here you update your activity's list to the returned values
dataCities = parseJSonArray(array);
Log.d(TAG, "End of parsing");
//But the adapter is using the original value of dataCities (new ArrayList<HashMap<String, String>>() )
citiesAdapter.notifyDataSetChanged();
Since your adapter depends on ArrayAdapter, the easiest solution might be to just create a new adapter when the data is received.
I am trying to populate a a spinner but I am getting an error with my String array saying "Array constants can only be used in initializers". My code works fine when i employ the string array as a local variable, but as a global variable it doesn't. I really need to be able to use my string array as a global variable. Thank you in advance. Here is my code:
deleteselection = (Spinner)view.findViewById(R.id.deletespinner);
ArrayAdapter<String> adapterdeletetype;
//createdenominationsarray = getResources().getStringArray(R.array.createdenominations); //<--works
//String [] createdenominationsarray = {"Select Portfolio", "Two", "Three"}; //<--works
createdenominationsarray = {"Select Portfolio", "Two", "Three"};// <--doesn'twork
adapterdeletetype = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,createdenominationsarray){
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent)
{
View v = null;
// If this is the initial dummy entry, make it hidden
if (position == 0) {
TextView tv = new TextView(getContext());
tv.setHeight(0);
tv.setVisibility(View.GONE);
v = tv;
}
else {
// Pass convertView as null to prevent reuse of special case views
v = super.getDropDownView(position, null, parent);
}
// Hide scroll bar because it appears sometimes unnecessarily, this does not prevent scrolling
parent.setVerticalScrollBarEnabled(false);
return v;
}
};
adapterdeletetype.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
denominationselection.setAdapter(adapterdeletetype);
I did the same thing for one of my project and it works for me. Below is the code snippet for your reference..
ArrayList<String> languages = new ArrayList<String>();
languages.add("English");
languages.add("German");
languages.add("French");
ArrayAdapter<String> langAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,languages);
ListView lv =(ListView)findViewById(R.id.listmain);
lv.setAdapter(langAdapter);
lv.setOnItemClickListener(new listclklisten(MainActivity.this));
public class listclklisten implements OnItemClickListener{
private Context parent;
public listclklisten(Context p){
parent=p;
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TO DO your code here
}
}
inside string.xml Write:
<string-array name="spinner_array_environtment">
<item>Test</item>
<item>Production</item>
</string-array>
Inside your MainActivity.java :
public class MainActivity extends Activity {
Spinner spinner_environment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
spinner_environment = (Spinner) findViewById(R.id.spinnerview);
adapter =ArrayAdapter.createFromResource(this, R.array.spinner_array_environtment,R.layout.spinner_phone);
adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
spinner_environment.setAdapter(adapter);
}
Inside spinner_phone.xml :
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinnerTarget"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="13dp"
android:textColor="#4C4646" />
try this out. Hope it will help you.
friends,
i am using following code to display list with radio buttons
now i want to select specific radio button of list by default so using setSelection property which does not work.
final String [] items=new String[]{"Item1","Item2","Item3","Item4"};
ArrayAdapter<string> ad=new ArrayAdapter<string>(this,android.R.layout.simple_list_item_single_choice,items);
list=(ListView)findViewById(R.id.List);
list.setAdapter(ad);
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
list.setSelection(2);
list.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
TextView txt=(TextView)findViewById(R.id.txt);
txt.setText(list.getItemAtPosition(arg2).toString());
}
}
);
please guide what mistake am i doing?
You'r looking for:
list.setItemChecked(2, true);
I might be completely off, but I think setSelection doesn't necessarely checks your item (as in checkbox, or radio), it navigates to it though.
As a workaround (maybe there is a more elegant solution) you can extend ArrayAdapter and set checked manually in a getView() method.
Add something like this to your class:
private static class MArrayAdapter extends ArrayAdapter<String> {
public Adapter(final Context context, final String[] objects) {
super(context, android.R.layout.simple_list_item_single_choice, objects);
}
#Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final CheckedTextView view = (CheckedTextView) super.getView(position, convertView, parent);
view.setChecked(position == 2);
return view;
}
}
And change your way of getting an adapter to new MArrayAdapter(this, items);
P.S.
On my previous comment, my mistake, you better call setChoiceMode (it's just in my app, I call notifyDataSetChanged, so I don't really need it). I think your'r up to some weird behaviour without choice mode.