ListView list - reference variable or object? - java

When I create a class, let's assume class A, that the actual object should be created and the memory allocated to it, I have to perform the following procedure:
A a = new A();
And at this moment, via the variable a, I can refer directly to the object.
However, when I have a situation:
ListView list;
list = findViewById(R.id.listView);
Is an object created during the list variable declaration? Could someone comment on this? Because with this statement I met in one tutorial.

All variables reference to object in Java.
For your example:
ListView list;
list = findViewById(R.id.listView);
The first statement won't create any new object, i.e.: findViewById won't create a new instance of ListView, actually, ListView object was created during the phase when you call setContentView(R.layout.xx), under the hood the Android traverse through the layout XML and create corresponding objects for each tag.
So after setContentView(xx), you already have a ListView instance in memory.
When you perform list = findViewById(R.id.listview), the method findViewById returns the reference of the ListView, and pass the reference to list, so the list now refers to the ListView object.
If you want to know it more clear, I suggest reading the related chapter in Head First Java, which clarifies this relationship clearly.

#LiuWenbin_NO's answer perfectly describes the situation. However, I thought I might put some more info regarding this.
setContentView creates the View instances when called in the onCreate function of an Activity. It takes a layout resource Id or a single View as a parameter and inflates the view. To understand more clearly, only the setContentView is enough for your Activity to have the Android screen populated with the static views that you have designed in your layout file right? Hence if you want to modify something in your layout, you take the references of your views and modify the views accordingly.
Listview list; only creates a variable of ListView type (note that every layout instances extends View). When you have called the setContentView function, it creates the references of the views inflated and using the findViewById, you are just getting the references of those.
Previously we had to cast to specific view types while using findViewById which is not necessary for newer versions of Android SDK. Hence the object is not created when you have declared ListView list, it was created when you called setContentView.
If you want to create instances of your views first and then want to inflate that, you can do that using setContentView as well. For example, take a look at the following code.
TextView tv = new TextView(this);
setContentView(tv);
// Modify the TextView?
tv.setText("Hello there");
In this way, you can only pass a single view instance to the setContentView function. Hence to achieve a complex layout with multiple controls you need to use the layout.
Using layout resources with setContentView decouples your application logic from the presentation layer.
I highly recommend this book for better understanding.

Related

How do I get a view from other activity?

Let's say I have two activities/classes. MainActivity and SecondActivity. For each of these activities I have individual XML files. In SecondActivity, I have a ListView with ID listview.
How can I retreive the ListView from SecondActivity in MainActivity?
I tried just plain and simple (in MainActivity.java):
ListView listview = (ListView) findViewById(R.id.listview);
But that crashes my app when I try to set an adapter on it (nullPointerException). I tried placing it directly inside my class, and inside the onCreate method. Both causes a crash.
The line that causes the crash looks like this:
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrayList);
listview.setAdapter(adapter); //crash (nullpointerexception pointing to nullobject)
What I want to do is get that ListView and use the "listview" object to add elements to the listview in my MainActivity.
In Android (with exceptions) you cannot have more than one activity running at the same time. You can have multiple Fragments, but a single activity is shown at a single time (ok, this is not 100% true anymore, but for all intents and purposes, this is still the case).
What you're trying to do is considered extremely bad practice in Android (and iOS for what is worth).
What can/should you do?
Your requirements appear to be some form of: I have a list of items, and I also have another activity where I want to add or remove things from said list.
This is fine, but you don't need "two activities" to do this.
Have one activity to show the list, and when you want to add the contents, either launch another activity to show the UI of the "edit/add" or use Fragments (one Fragment would have the list, the other would have the UI to edit the list).
Where is the data in all this?
Stored in a THIRD place (let's call it "YourListRepository"), which is a class where:
From the "List" you'd simply say: Repository, give me the latest list!
From the "Edit" screen, you'd say: Repository, give me the item "N" from the list. And then, you'd say: Repository, here's the updated item "N", refresh it.
Going back to 1 (to display the updated list) is automatic, since it asks "for the latest list".
Where to learn more?
Given the tenure of the question you posted, it appears that you're relatively new to Android development, and therefore I suggest you spend an hour of your time, reading Application Fundamentals from the official Google documentation.

Save custom ArrayList on screen orientation change

I have a ListActivity where the ListView is driven by a custom array adapter which has custom objects in it. The custom object is a Site.
On orientation change, my current implementation is trying to hit the database again to populate the ListView and I want to save the current ArrayAdapter then re-attach it to the ListView after the orientation change.
Whilst I wasn't keen on it, I resigned myself to the fact that I would need Site to implement Parcelable so I could then save the entire ArrayAdpter to the bundle as an array of Paracables.
I have looked at this post which does pretty much what I need to do.
However, my Site object has variables within it which are also custom objects and those objects themselves also have other objects such as DateFormat in them. I can't figure out from the post that I linked to above how to implement this so that the objects within the objects that make up part of the Site object can be included in the Parcel, since this example only deals with strings and the parcel doesn't seem to have a writeObject() method!
Are there any alternatives? (I'd love to avoid using Parcelable at all, but if I have to that's ok)
thanks
Aaron
You are using ListActivity, that means your UI is similar in both orientations ?
If yes, you can avoid the condition of recreation of activity on orientation change by adding android:configChanges="orientation|screenSize" in your manifest for this activity.
If not, then you should use a FragmentActivity and make a listview in that, and then you can use onRetainCustomNonConfigurationInstance() to return your adapter object and after configuration changes get it using getLastCustomNonConfigurationInstance()

List Adapter and getView function explanation

I'm thoroughly confused about the life cycle of list view. More specifically, what does the list adapter do exactly? Does it just provide data to the given view? And when/where does the getView() function gets called? And what purpose does this getView() function provide? From just looking at the code, it looks like getView() is "assigning" data to the view to be displayed. I'd like to be able to use list views without having to memorize, do this and then this in order for it to work. I'd much rather understand it so I can use it properly. Someone please help me understand all of this.
Also, if someone can explain to me.. what's the difference between BaseAdapter and ArrayAdapter? and any other kind of adapters that comes with Android.
What I have understood is your adapter constructor instantiated by activity and then on activity launch the getView() method is called. the {#param position, view, viewGroup}
position: it refers to the position of the view as given by adapter. Please Note it is different from the position in {OnItemClick(AdapterView adapter, View v, int position,long id)} here position is the list item position. The {position} in {getView()} changes after particular object in the list are displayed again for eg. when you scroll.
view: the view here is the view you want to be presented through getView(). It can be a particular XML layout for each row. So this states clearly that getView is called to plot every row. this view needs to be valid one or another layout (LinearLayout by default) will be selected to maintain uniqueness.
viewgroup: as you might know and as name says will be the container of your #param:view
any other point is appreciated.
getView() fills in the data into the item's view with the given index. The view which is given as a parameter may be a pre-inflated view. If it is not, you have to infalte it yourself.
An ArrayAdapter simply calls setText on the given view with the result of toString() of the object with the respective index from the array. If you override it, you can do more complex stuff, like assigning a picture or filling in more TextViews.
I recommend the following tutorial: http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/
Hi list adaper provides view for listview.
when user scrolls listview at that time getview is called.
getview is used to populate your view with data hence the name adapter.
The Adapter does all the "rember to do this" for you. If you change a list view's backing data structure through the adapter's methods (e.g. "add()") it will fire all the datachanged and update events you'll need for the list view to show the new state of the data.

Creating xml template for feed/list items in Android?

I'm helping a friend create an android app that will have screens with lists of info similar to a feed. I've been learning xml layout in Android and have some of the basics down, but don't have a lot of familiarity with doing the java stuff. I've successfully created includes to seperate layout files for compontents within a screen, but what I'm wondering is if such a component can be used as a kind of template for feed/list items that get inserted programmatically on the back end. IE, is there a way to have Android create a list and for each list item it uses the external xml as a template? Sorry if this is somewhat vague, I'm new to this and trying to understand what our options are. TIA!
Yes, every list item can be a custom layout. In fact you always have to define a layout for the list entries. You can either choose a prebuilt one from android.R.layout or you can use your own from R.layout. You can specify it when you create the list adapter in code.
Have a look at one of the ArrayAdapter constructors for example:
public ArrayAdapter (Context context, int resource, int
textViewResourceId)
Since: API Level 1 Constructor Parameters
context - the current context.
resource - The resource ID for a layout file containing a
layout to use when instantiating views.
textViewResourceId - The id of the TextView within the layout resource to be populated
The constructor takes a layout that will be used for the ListView childs. Works similar with other adapters.
What you usually do is inflating the layout inside getView() of the adapter though. When you did that, fill all the data you need into the views of the layout, and return the view.
Note that you get an argument called convertView. This is one of the older layouts you already inflated before. In most cases the user just scrolled down and that entry is not visible anymore. If this convertView is not null, you can fill your data in there instead of inflating the whole layout again (thats expensive).
You can find a working example inside the
ANDROID_SDK\samples\android-10\ApiDemos\src\com\example\android\apis\view\List5.java file. Also take a look at the other list examples in that folder.

Android - CursorAdapter-ish Subclass, for ListView

I currently use a bunch of subclassed CursorAdapters with custom layouts throughout my app, populating them with a Cursor returned by an SQLite query, then allowing them to populate my ListView, after setting them with
setListAdapter(new SearchAdapter(this, searchCursor));
Is there anyway I can get the same behavior but instead of passing in a Cursor pass in an
ArrayList<String[]>
Would there be a different class to subclass? (Obviously) Or, should I convert the ArrayList to a Cursor somehow? Or, is there a different method I am missing?
Thanks!
you can do it with an array Adapter (also you can subclass Base adapter) and implement your own way of displaying objects in a list. there are plenty of tutorials on google on how to do that.
Just search ArrayAdapter, Base adapter. :D
Hope this helps,
Take care.

Categories