I am trying to create a custom object adapter, and part of the code require referencing object by their ID. However, I am getting error saying the ID does not exist:
private static class GeoAreaAdapter extends BaseAdapter implements Filterable{
private LayoutInflater mInflater;
private int resource;
private GeoArea _myGeoArea;
public GeoAreaAdapter(Context context, int resource, GeoArea myGeoArea) {
mInflater = LayoutInflater.from(context);
_myGeoArea = myGeoArea;
}
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout GeoAreaView;
if (GeoAreaView == null) {
GeoAreaView = new LinearLayout(mInflater.getContext());
String inflater = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater vi;
vi = (LayoutInflater)mInflater.getContext().getSystemService(inflater);
vi.inflate(resource, GeoAreaView, true);
}
else {
GeoAreaView = (LinearLayout) convertView;
}
TextView name = (TextView) convertView.findViewById(R.id.txtGeoAreaName);
name.setText(_myGeoArea.name);
return convertView;
}
....
}
It happen with "R.id.txtGeoAreaName".
Here is my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/txtGeoAreaName" />
</LinearLayout>
So as you can see, "txtGeoAreaName" is definitely defined.
What am I doing wrong?
You need to inflate your layout this way:
LayoutInflater li = LayoutInflater.from(getContext());
convertView = li.inflate(R.layout.yourlayoutid, null);
and then you can find views:
convertView.findViewById(R.id.someid);
Use "txtGeoAreaName" as the id attribute of TextView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/txtGeoAreaName" />
</LinearLayout>
Update the getView method as follows
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(resource, GeoAreaView, true);
}
TextView name = (TextView) convertView.findViewById(R.id.txtGeoAreaName);
name.setText(_myGeoArea.name);
return convertView;
}
Also, you must use Holder Pattern to reuse the views for better performance of ListView.
Related
I am using GridView to show product items. And everything was fine. But when I scroll, the items that are below the screen size are getting to the top when I am scrolling down. Point to note the items are in the fragment of tabview.
I have tried ViewHolder() method previously but that is deprecated.
Here is my GridView Adapter java file code
public class GridAdapter extends BaseAdapter {
Context context;
private final String [] titles;
private final int [] images;
View view;
LayoutInflater layoutInflater;
ImageView imageTrending;
public GridAdapter(Context context, String[] titles, int[] images) {
this.context = context;
this.titles = titles;
this.images = images;
}
#Override
public int getCount() {
return titles.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
layoutInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
view = new View(context);
view = layoutInflater.inflate(R.layout.single_item, null);
imageTrending = (ImageView) view.findViewById(R.id.trendingImage);
TextView titleTrending = (TextView) view.findViewById(R.id.trendingTitle);
titleTrending.setText(titles[position]);
imageTrending.setImageResource(images[position]);
}
return view;
}
}
Here is the .xml file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Trending">
<!-- TODO: Update blank fragment layout -->
<GridView
android:id="#+id/trendingGridView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:numColumns="auto_fit"
android:columnWidth="150dp">
</GridView>
</RelativeLayout>
In Fragment here is the Inflater
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_trending, container, false);
gridView = (GridView) rootView.findViewById(R.id.trendingGridView);
GridAdapter gridAdapter = new GridAdapter(getContext(), titles, products);
gridView.setAdapter(gridAdapter);
return rootView;
}
Here is the single_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="150dp"
android:padding="8dp"
android:gravity="center">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="150dp">
<ImageView
android:id="#+id/trendingImage"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="#+id/trendingTitle"
android:gravity="bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.cardview.widget.CardView>
</LinearLayout>
Finally solved it, the fact here is in getView,
The parameter View convertView needs to use to inflate the
single_item.xml view.
The convertView has to be used for initializing the View().
And using the same convertView to set the content in view.
Finally Returning the convertView.
Here is the new solved code...
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
layoutInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = new View(context);
convertView = layoutInflater.inflate(R.layout.single_item, null);
imageTrending = (ImageView) convertView.findViewById(R.id.trendingImage);
TextView titleTrending = (TextView) convertView.findViewById(R.id.trendingTitle);
titleTrending.setText(titles[position]);
imageTrending.setImageResource(images[position]);
}
return convertView;
}
Here is how the code was before...
public View getView(int position, View convertView, ViewGroup parent) {
layoutInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
view = new View(context);
view = layoutInflater.inflate(R.layout.single_item, null);
imageTrending = (ImageView) view.findViewById(R.id.trendingImage);
TextView titleTrending = (TextView) view.findViewById(R.id.trendingTitle);
titleTrending.setText(titles[position]);
imageTrending.setImageResource(images[position]);
}
return view;
}
Thanks everyone who tried to solve it!
I have successfully implemented Spinners in my project using the Spinner class which exists in this link:
How to make an Android Spinner with initial text "Select One"
Also, I customized the layout of each item and named it as spinner_entries_style.xml ..
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical" >
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="2dp"
android:background="#640c1c"
android:maxEms="10"
android:padding="10dp"
android:singleLine="false"
android:textColor="#d7a801"
android:textSize="18sp" />
</LinearLayout>
Also, These are the Adapter classes I used in my code..
class LoanTypeAdapter extends ArrayAdapter<String> {
Context context;
String[] items;
public LoanTypeAdapter(Context context, String[] items) {
super(context, R.layout.spinner_entries_style, R.id.textView, items);
this.context = context;
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder = null;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(android.R.layout.simple_spinner_item,
parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.textView.setText(items[position]);
holder.textView.setTextColor(Color.parseColor("#d7a801"));
holder.textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
holder.textView.setSingleLine(true);
return holder.textView;
// ------------------------------------------
}
class ViewHolder {
final TextView textView;
ViewHolder(View view) {
textView = (TextView) view;
}
}
}
And this..
class LoanProgramAdapter extends ArrayAdapter<String> {
Context context;
String[] items;
public LoanProgramAdapter(Context context, String[] items) {
super(context, R.layout.spinner_entries_style, R.id.textView, items);
this.context = context;
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder = null;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(android.R.layout.simple_spinner_item,
parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.textView.setText(items[position]);
holder.textView.setTextColor(Color.parseColor("#d7a801"));
holder.textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
holder.textView.setSingleLine(true);
return holder.textView;
}
class ViewHolder {
final TextView textView;
ViewHolder(View view) {
textView = (TextView) view;
}
}
}
But, there is something strange I encountered after building the spinners. When running the app in Android versions (4.2 or less), there is a white space below the dropdown list.
Here are the screenshots of what happens..
http://www.mediafire.com/view/cqj51t8e3aju18m/01.png
http://www.mediafire.com/view/ure788yetrt00v3/02.png
That is not just on the emulator, but also in the real devices having Android 4.2 or less. Also, this white space seems a bit bigger in some devices.
Is there any idea to hide or kill these white area? Any solution for this problem?
I found the solution of this problem after reading this post.
How to wrap lengthy text in a spinner
In my layout called spinner_entries_style.xml, I should specify the height of text view like that:
android:layout_height="?android:attr/listPreferredItemHeight"
And it will be like that:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical" >
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:layout_marginBottom="2dp"
android:background="#640c1c"
android:maxEms="10"
android:padding="10dp"
android:singleLine="false"
android:textColor="#d7a801"
android:textSize="18sp" />
</LinearLayout>
That solved my problem successfully..
Remove this line from spinner_entries_style.xml.
android:layout_marginBottom="2dp"
I created my own custom adapter that extends Array Adapter:
public class AdapterGeoArea extends ArrayAdapter<GeoArea>{
private Context _context;
private int resource;
private ArrayList<GeoArea> _myGeoArea;
public AdapterGeoArea(Context context, ArrayList<GeoArea> myGeoArea) {
super(context, 0, myGeoArea);
_context = context;
_myGeoArea = myGeoArea;
}
public int getCount() {
return _myGeoArea.size();
}
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout GeoAreaView;
if (convertView == null) {
GeoAreaView = new LinearLayout(_context);
LayoutInflater li = LayoutInflater.from(_context);
convertView = li.inflate(R.layout.layout_geo_areas, null);
}
else {
GeoAreaView = (LinearLayout) convertView;
}
GeoArea curGeoArea = _myGeoArea.get(position);
TextView name = (TextView) GeoAreaView.findViewById(R.id.txtGeoAreaName);
name.setText(curGeoArea.name);
return convertView;
}
static class ViewHolder {
TextView name;
RelativeLayout childContainer;
}
#Override
public Filter getFilter() {
return null;
}
}
And here is how I am using it in my main:
public class ActivityGeoAreas extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_geo_areas);
GeoArea.searchTerm = "Bar & Grill";
GeoArea torontoArea = new GeoArea("cityOfToronto");
ArrayList<GeoArea> testList = new ArrayList<GeoArea>();
testList.add(torontoArea);
AdapterGeoArea adapter = new AdapterGeoArea(this, testList);
ListView lv = (ListView) findViewById(R.id.textGeoArea);
lv.setAdapter(adapter);
}
}
Everything seem to be fine except for this line:
TextView name = (TextView) GeoAreaView.findViewById(R.id.textGeoArea);
And here is how I defined my layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".ActivityGeoAreas" >
<TextView
android:id="#+id/textGeoArea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Choose Area"
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout
android:id="#+id/LinearLayoutGeoAreas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textGeoArea"
android:layout_below="#+id/textGeoArea"
android:orientation="vertical" >
<ListView
android:id="#+id/listViewGeoArea"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
</RelativeLayout>
It simply can't find the TextView textGeoArea and this line become null, what am I doing wrong?
Change this
TextView name = (TextView) GeoAreaView.findViewById(R.id.txtGeoAreaName);
to
TextView name = (TextView) convertView.findViewById(R.id.txtGeoAreaName);
I guess you have got confused.
Move textview to a new layout list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/textGeoArea"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="14dp"
android:text="Choose Area"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
Now change your getView as below
LayoutInflater inflater;
public AdapterGeoArea(Context context, ArrayList<GeoArea> myGeoArea) {
super(context, 0, myGeoArea);
_context = context;
_myGeoArea = myGeoArea;
inflater = LayoutInflater.from(context); // initialize inflater
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_row,parent,false);
holder = new ViewHolder();
holder.tv = (TextView)convertView.findViewById(R.id.textGeoArea);
holder.setTag(convertView);
}
else {
holder = (ViewHolder) convertView.getTag();
}
GeoArea curGeoArea = _myGeoArea.get(position);
holder.tv.setText(curGeoArea.name);
return convertView;
}
static class ViewHolder // use a view holder for smooth scrolling an performance
{
TextView tv;
}
On the first pass, GeoAreaView is a childless LinearLayout since you just created it. convertView is the View initialized your layout which holds the TextView. So you need to use that to find the TextView.
TextView name = (TextView) convertView.findViewById(R.id.txtGeoAreaName);
I see you have a ViewHolder but you don't appear to be using it. You may want to take a little time and go through a good tutorial on using ListView.
This guy usually seems to have good tutorials
I started using fragments to develop a new app, one of the fragments is a ListFragment,
when I use the adapter I made to show the list's rows I get some null from some findViewById that I use on the getView() method.
The structure is:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/fragment_container">
</FrameLayout>
</RelativeLayout>
frag_detail.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/list"
android:layout_gravity="center"/>
</LinearLayout>
detail_list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/detailItemLayout" >
<ImageButton
android:layout_width="64dp"
android:layout_height="64dp"
android:id="#+id/imgIcon"
android:layout_below="#+id/txtTitle"
android:layout_centerHorizontal="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="txtTitle"
android:id="#+id/txtTitle"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="label1"
android:id="#+id/label1"
android:layout_below="#+id/imgIcon"
android:layout_alignParentLeft="true"/>
</RelativeLayout>
DetailFragment class
public class DetailFragment extends ListFragment {
private Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.frag_detail,container,false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
MonsterDataSource ds = new MonsterDataSource(context);
List<Monster> lsMonster = ds.getAllMonsters();
//ListView lsView = (ListView)this.getActivity().findViewById(R.id.lsDetail);
MonsterListAdapter adapter = new MonsterListAdapter(context,lsMonster);
//lsView.setAdapter(adapter);
setListAdapter(adapter);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
context = activity.getApplicationContext();
}
}
And the MonsterListAdapter class
public class MonsterListAdapter extends BaseAdapter {
static class ViewHolder {
private TextView txtTitle;
private ImageView imgIcon;
private TextView txtHealth;
}
private Context context;
private LayoutInflater inflater;
private List<Monster> data;
private ViewHolder holder;
public MonsterListAdapter(Context c, List<Monster> data){
context = c;
this.data = data;
inflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/*Basic BaseAdapter Methods*/
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
view = inflater.inflate(R.layout.menu_list_item, null);
holder = new ViewHolder();
/*Those Guys get null*/
RelativeLayout layout = (RelativeLayout)view.findViewById(R.id.detailItemLayout);
holder.txtTitle = (TextView) view.findViewById(R.id.txtTitle);
holder.imgIcon = (ImageView) view.findViewById(R.id.imgIcon);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
Monster monster = data.get(i);
holder.txtTitle.setText(monster.name);
holder.imgIcon.setImageResource(monster.imgResID);
holder.txtHealth.setText(monster.health);
return view;
}
}
In case anyone asking, I'm trying to retrieve the relative layout to add some controls dynamically after.
Thanks
You posted the XML for detail_list_item.xml but in your code you inflate menu_list_item.xml.
detail_list_item.xml contains all of the IDs you are trying to find so it appears you have accidentally inflated the wrong View in getView
Additionally, you should remove your ViewHolder as a member variable and place it as a local variable in the getView method. You are reusing that variable for multiple views at the same time which means you have the potential for modifying the wrong views at different positions (data going to the wrong positions, etc).
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
...
...//all of your other code here
}
Try without affecting "view"
RelativeLayout layout = (RelativeLayout)findViewById(R.id.detailItemLayout);
holder.txtTitle = (TextView) findViewById(R.id.txtTitle);
holder.imgIcon = (ImageView) findViewById(R.id.imgIcon);
Edit This works for me... My texviews nbCommentaires and Comment give NullPointerException if i inflate View to them... I thought you get the same issue...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.comment_row, null);
}
v.setTag(position);
Commentaires o = Global_reco.CommRecos.get(position);
if (o != null) {
TextView nom = (TextView) v.findViewById(R.id.nom_com);
TextView com = (TextView) v.findViewById(R.id.com);
ImageView photo = (ImageView) v.findViewById(R.id.profile_com);
TextView nbCommentaires = (TextView) findViewById(R.id.nb_commentaires);
TextView Comment = (TextView)findViewById(R.id.nbre_comment);
photo.setTag(position);
I'm trying to get my spinneradapter working. I get no error's but
the spinner remains empty. I have read multiple tutorials but they aren't seem to work
very well. I'm trying to turn every row in a specifik color, that's why I need the adapter.
This is my code:
public class spinnerAdapter extends ArrayAdapter<String> implements
SpinnerAdapter {
Context context;
ArrayList<String> dateArray;
public spinnerAdapter(Context context, ArrayList<String>dateArray) {
super(context, R.layout.ruilen2_spinner);
this.context = context;
this.dateArray = dateArray;
}
static class ViewHolder {
public TextView textView;
public TextView textView2;
}
#Override
public View getDropDownView(int position, View view, ViewGroup parent) {
View rowView = view;
final ViewHolder holder;
if (rowView == null) {
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
rowView = vi.inflate(R.layout.ruilen2_spinner, null);
holder = new ViewHolder();
holder.textView = (TextView)rowView.findViewById(R.id.spinnerdate);
//holder.textView2 = (TextView)rowView.findViewById(R.id.spinnerworkplace);
rowView.setTag(holder);
}
else{
holder = (ViewHolder) rowView.getTag();
}
holder.textView.setText(dateArray.get(position));
return super.getDropDownView(
position, rowView, parent);
}
}
Here's the code snippet where I call the class:
s.setAdapter(new spinnerAdapter(getParent(),namen));
And last but not least the XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:background="#color/white"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/spinnerdate" android:textColor="#color/black"></TextView>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/spinnerworkplace" android:textColor="#color/black"></TextView>
</LinearLayout>
If it is displaying but is empty then you might not be creating your dateArray properly. Did you check to make sure namen in s.setAdapter(new spinnerAdapter(getParent(),namen)); has anything in it?