I made this app called UnitConverter...
unitarray=new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item);
unitarray.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
SpinnerUnit.setAdapter(unitarray);
unitarray.add(getResources().getString(R.string.unit1));
unitarray.add(getResources().getString(R.string.unit2));
unitarray.add(getResources().getString(R.string.unit3));
unitarray.add(getResources().getString(R.string.unit4));
unitarray.add(getResources().getString(R.string.unit5));
unitarray.add(getResources().getString(R.string.unit6));
unitarray.add(getResources().getString(R.string.unit7));
unitarray.add(getResources().getString(R.string.unit8));
unitarray.setNotifyOnChange(true);
everything's awesome but I want to put images next to each Unit!
is there anyone who can help me with this please? thanks!
Probably the simplest way would be to use android's R.layout.simple_spinner_item as the spinner elem layout and internally to add an image to the TextView using setCompoundDrawablesWithIntrinsicBounds
ArrayAdapter adapter = new ArrayAdapter(context, android.R.layout.simple_spinner_item, countries);
countrySpinner.setAdapter(adapter);
And the adapter:
class ImageSpinnerAdapter extends ArrayAdapter {
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = (TextView) super.getView(position, convertView, parent);
Elem elem = elemArray.get(position);
textView.setText(elem.toString());
textView.setCompoundDrawablesWithIntrinsicBounds(elem.getImage(), null, null, null);
return textView;
}
}
See detailed example here.
Related
So I use one adapter for my Spinner and AutoCompleteTextView, which extends ArrayAdapter<Object>. For View-related method, I only override getView.
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView tv = (TextView) view;
//I do something with TextView here, but won't affect the problem
return view;
}
Now, both declared like this:
adapterSpinner = new CustomAdapter(
this, R.layout.custom_layout_item, objects);
adapterService.setDropDownViewResource(
R.layout.custom_dropdown_layout);
spinner.setAdapter(adapterSpinner);
adapterAutoComplete = new CustomAdapter(
this, R.layout.custom_layout_item, objects);
adapterAutoComplete.setDropDownViewResource(
R.layout.custom_dropdown_layout);
autoComplete.setAdapter(adapterAutoComplete);
The result confusing me:
AutoCompleteTextView
Applies custom_layout_item to its dropdown View instead, and instead applies a style I gave in its element in xml to its TextView/EditText layout. It ignores custom_dropdown_layout I've set.
Spinner
Applies correctly all of them, its TextView view using custom_layout_item, and its dropdown view using custom_dropdown_layout. Though it ignores the style I gave to it in xml.
Functional, both works fine. But from UI, quite a mess... Why did it happen?
I am attempting to make a list view row empty if it has no text. I have achieved this before, but I'm not sure how I did it. At the moment, I have managed to get it to not show anything when the text is equal to nothing, however it still shows the row border.
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_2, android.R.id.text1, MainActivity.values) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView text1 = (TextView) view.findViewById(android.R.id.text1);
TextView text2 = (TextView) view.findViewById(android.R.id.text2);
text1.setText(MainActivity.values[position]);
text2.setText(MainActivity.numvalues[position]);
if (MainActivity.values[position].equals("")) {
text1.setVisibility(View.INVISIBLE);
text1.setVisibility(View.GONE);
text2.setVisibility(View.INVISIBLE);
text2.setVisibility(View.GONE);
//convertView.setVisibility(View.INVISIBLE);
//convertView.setVisibility(View.GONE);
view.setVisibility(View.INVISIBLE);
view.setVisibility(View.GONE);
}
else {
text1.setVisibility(View.VISIBLE);
text2.setVisibility(View.VISIBLE);
//convertView.setVisibility(View.INVISIBLE);
//convertView.setVisibility(View.GONE);
view.setVisibility(View.VISIBLE);
}
return view;
}
};
Before init ArrayAdapter remove from MainActivity.values and MainActivity.numvalues items that don't need to show.
VIEW.GONE won't work as you want, i've tried it, but there is one thing you can do to avoid this problem at all, maybe you should remove all of your empty rows before you past your items into adapter?
I have a ListView in which each row is a TextView, and display a line of text. I'm getting a problem where occasionally an unwanted empty row appears. The empty row goes away once list scrolls past that particular area.
I've verified my list rows contain the correct information by using the following code after pausing the app in the debugger. Nothing in the output shows up empty or null, etc.
for (int i = 0; i<list.getChildCount(); i++) {
System.out.print((TextView) list.getChildAt(i)).getText());
}
This shows the information I expected.
I also checked the data backing my Adapter for empty entries, new lines, etc.
My getView() method inside the Adapter is as follows:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView t;
if (convertView == null) {
convertView = mInflator.inflate(R.layout.single_message_row, null);
t = (TextView) convertView;
t.setMovementMethod(LinkMovementMethod.getInstance());
t.setTextSize(mMsgSize);
}
else {
t = (TextView) convertView;
}
CharSequence text = get(position);
t.setText(text);
return t;
}
Below is an image demonstrating the problem (the area in red):
Try after changing getView method as:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if(row==null){
LayoutInflater inflater=getLayoutInflater();
row=inflater.inflate(R.layout.single_message_row, parent, false);
}
TextView t=(TextView)row.findViewById(R.id.yourtextview);
t.setText("position "+position);
t.setMovementMethod(LinkMovementMethod.getInstance());
t.setTextSize(mMsgSize);
CharSequence text = get(position);
t.setText(text);
return row;
}
It seems the problem was caused by using match_parent for my TextView width in the ListView. Changing it to wrap_content seems to have fixed it.
For an unwanted empty list item occurring in the ListView, I tried this:
List<String> listofItems;
String strlist=listofItems.get(position);
if(strlist.isEmpty())
{
remove(strlist);
}
'position' is what i got as a parameter in View getView method, because i was implementing a custom adapter.
it worked fine for me!
I have made a ListView with an ArrayAdapter. It works. But I had to put the resource id for the item layout twice: in the adapter definition and in the getView, in the case when the View parameter is null.
// --------------------------------------------here is the FIRST use
lvShows.setAdapter(new ArrayAdapter<TvShow>(this, R.layout.show_row, allKnownShows) {
#Override
public View getView(int position, final View rowView, ViewGroup parent) {
LinearLayout showView;
if (rowView == null) {
// --------------------------------- here is the SECOND use
showView = (LinearLayout) inflater.inflate(R.layout.show_row, parent, false);
}
else {
showView = (LinearLayout) rowView;
}
((TextView) showView.getChildAt(0)).setText(time));
((TextView) showView.getChildAt(1)).setText(name);
return showView;
}
});
Such style is disgustful, of course. Could you kindly advise, what am I understanding wrong and how can I use the resource only once?
If creating a new ArrayAdapter I am setting the layout id, it should know it and use somehow. How could I reach it? Or better I would expect the Adapter to create item views automatically. Again - how can I use it?
What ArrayAdapter does with that resource we feed to it when creating a new one? All its constructors take the item resource and we manage this resource and inflate it "by hand". It is not the effective way.
You can override ArrayAdapter constructor and call super :
public ArrayAdapter<T>(Context context, TheDataType data) {
super(context, R.layout.show_row, data);
}
And store the id in a ArrayAdapter member variable. It avoid the adapter "user" to know what is the view needed for the adapter.
Or you can use a BaseAdapter.
I had looked into the source code of the ArrayAdapter, and it already does all this stuff about view creation:
// citation from public class ArrayAdapter<T>
private View createViewFromResource(int position, View convertView, ViewGroup parent,
int resource) {
View view;
TextView text;
if (convertView == null) {
view = mInflater.inflate(resource, parent, false);
} else {
view = convertView;
}
So, we should simply use it:
lvShows.setAdapter(new ArrayAdapter<TvShow>(this,
R.layout.show_row,
R.id.nameField,
allKnownShows){
public View getView(int position, final View convertView, ViewGroup parent) {
LinearLayout showView = (LinearLayout) super.getView(position, convertView, parent);
setAnythingForItem(showView);
return showView;
}
Attention: we have changed the constructor!
ArrayAdapter allows to use no-TextView item layout. But if it is not TextView itself, it should have one and the id of this very inner TextView field should be given to the constructor as the third parameter. ArrayAdapter needs it to be set, to write there Strings if the array connected to it has String elements.
It wants a TextView always, even if it doesn't need it really, if the array consists of Objects, not Strings. Otherway it checks the item layout for being a TextView and if it is not, throws an error.
I'm trying to change the font of a TextView in my ArrayAdapter. The font chantelli_antiqua.ttf is in the assets folder.
Here is my Java code:
listItemAdapter = new ArrayAdapter<MenuItem>(this, R.layout.listitem, menuItems);
Typeface font = Typeface.createFromAsset(getAssets(), "chantelli_antiqua.ttf");
TextView v = (TextView)listItemAdapter.getView(0, null, null);
v.setTypeface(font);
xml for the listitem layout:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="30sp"
/>
I'm quite sure the problem lies with the Adapter.getView(int, View, ViewGroup) method. I just don't really understand what to pass as variables and tried null. But this doesn't do what I would like it to.
How to change the font of the TextView in the Adapter to the custom font?
Update
According to Pixie's suggestion I created a MenuItemAdapter which extends ArrayAdapter<MenuItem>:
public class MenuItemAdapter extends ArrayAdapter<MenuItem>
{
private Typeface font;
public MenuItemAdapter(Context context, int textViewResourceId, List<MenuItem> objects)
{
super(context, textViewResourceId, objects);
font = Typeface.createFromAsset(context.getAssets(), "chantelli_antiqua.ttf");
}
#Override
public View getView(int position, View view, ViewGroup viewGroup)
{
((TextView)view).setTypeface(font);
return super.getView(position, view, viewGroup);
}
}
And changed my java code to:
listItemAdapter = new MenuItemAdapter(this, R.layout.listitem, menuItems);
But now my app crashes after the onCreate of the ListActivity, but before hitting the breakpoint in getView(...), I haven't been able to figure out yet why. Any suggestion?
Update2
Changed the code for getView(...) to:
#Override
public View getView(int position, View view, ViewGroup viewGroup)
{
View v = super.getView(position, view, viewGroup);
((TextView)v).setTypeface(font);
return v;
}
and this works. :)
You shouldn't call the getView() method of your adapter. The ListView does this for you. You have to extend the ArrayAdapter class and override the getView() method instead. In this method you have to inflate a new view or re-use convertView and set the typeface for this view.
I think the problem is in return super.getView(position, view, viewGroup); at the end of getView() method.
I think it should be like this
#Override
public View getView(int position, View view, ViewGroup viewGroup)
{
TextView tv = ((TextView)view).setTypeface(font);
tv.setText(<String> getItem());
return tv;
}
please note this code is example I didn't try it now but I made custom arrayAdapter before and it was something like that.
Here is a tutorial describing how to create custom arrayAdapter.