I've created a Master-Detail application from the given Android templates. I need to create a method to delete an item on longclick, but all the tutorials I've found on the subject involve
getListView().setOnItemLongClickListener...
// and so on
My problem is, I don't know where the ListView is! When I run the program with no modifications, just the base template Android creates, it runs fine. When I add "getListView" to the onCreate method, the program crashes.
There's obviously a ListView, because I see a list, but I don't know where in the default template it's buried. It's not listed in any xml or java files, so I don't know how to access it.
This may be a stupid question, but I've been at this for hours, and I would really appreciate any advice.
If you've created from Master-Detail template, you have a Fragment generated that extends ListFragment. Trying to call getListView() from onCreate() method in the Fragment will result in the following exception:
java.lang.IllegalStateException: Content view not yet created
You can't call this method before the view of the Fragment has been created (as the exception states). You can use it in the onViewCreated() method (or any method called after onViewCreated() was called). Hope this helps.
getListView is a method from ListActivity. If you are not extending that, you won't see it
Related
I am trying to get this button to launch a block of code but it can't seem to find it.
This is a button in a fragment that is trying to launch another fragment inside a single activity architecture.
Method that gets called (Notice how it's greyed out)
Button that calls the method
Android complaining that this doesn't exist yet
Design properties seeing function just fine
Error that I get
What exactly am I doing wrong here?
The answer to my problem was to just set up the calls programmatically vs in layout for fragments. Using a setOnClickListener with the binding in onCreateView worked. If you are using a binding, make sure to return binding.root in the onCreateView, or else it won't work.
Hello I'm new to the android ecosystem and wanted to inquire about best practices when it comes to defining a fragments content
currently I'm opening a connection to my database aswell as initialising onClick listeners in my fragment's onCreateView but I'm also aware that there exists onViewCreated and onCreate similar to a regular activity, while I'm familiar with where everything is placed in an activity, I'm not as sure about fragments, can someone help me out?
-thanks
onCreateView()
This is the place where you initialize your views (findViewById()) / attach listeners to them.
From android docs:
Called to have the fragment instantiate its user interface view
onCreate()
It's better to move the code that connects to the database here - code that doesn't depend on UI elements.
You can read more in the official docs here.
I'm using the viewpagerindicator library (http://viewpagerindicator.com/) to create some sort of wizard for my android app. It works fine and does exactly what I want.
I would like to "extend" the functionality a bit by having "previous"/"next" buttons in my ActionBar - pretty much as in Android's "Done Bar" tutorial - to step through the wizard. Works like a charm, too.
HOWEVER:
I would like to display information about the "next" & "previous" fragment in the ActionBar's buttons. Information I pass to the fragments that live in the ViewPager at the time of their "creation" (actually at the time of their object instantiation - using the classical "newInstance(...)" approach to create the instance of my fragment, store the parameters in a Bundle and extract them in the fragment's "onCreate" method). The same way the template does it, when you create a new fragment for your project.
So, this information is the thing I actually want to display in my wizards button to know what fragment is next and which was last.
The type of this information is not important for my problem. It could be a String or an icon or an int or ... anything else you want.
However, wherever I've tried to access my fragments data, the fragment has not yet been fully initialized (meaning its "onCreate" method has not been called yet).
I've tried it in the host fragment's "onViewCreated" method, because I thought that's where all its subviews should be initialized already (at least their "onCreate" method should have been called, I thought), but it seems that this is handled differently for ViewPager to retain only the number of fragments in memory that was set by setOffscreenPageLimit.
So, what I'm looking for (and probably just missing) is the correct callback method here. One that is called when the ViewPager's next Fragments have been loaded and initialized. If such a callback exists, I could place my little piece of code there to update the text in my "previous"/"next" buttons within the ActionBar.
Any help, comments, ideas are highly appreciated. If needed, I can also try to attach some code sample to better explain my setup, but I think it should be easy enough to understand what my problem is.
Thanks in advance!
P.S.: I also tried to do this by using EventBus to send "onFragmentInitialized" messages from my fragments within in the ViewPager and the hosting fragment. It actually worked, but it does not seems the proper way to do this.
When a Fragment's onCreate Method is called, its already preparing to be displayed, and practically its past the point where its considered a Next or Previous fragment instead its considered current.
A fragment's onCreateViews method is called after committing a transaction in the FragmentManager. which takes less than 1 sec to bring it in front of the user (depending on the device and runtime environment)
But in your case, your data should be initalized outside the Fragment that uses it, and displayed where ever you want by passing the data itself then displaying whatever you want form it.
decouple your data from android objects (Fragment, Activity ...) and you should be able to load, maintain, access it cleanly and without worrying about their callbacks.
The Fragment's arguments can be read and loaded in its onAttach callback rather than onCreate, the Activity will then (after onAttach is complete) get a onAttachFragment callback with the Fragment as a parameter. However, I doubt onAttachFragment will be called when switching between already loaded pages in the view pager.
If not, you could have the fragment notify the activity (through an interface) that it is now active during its onActivityCreated, onViewCreated or similar method.
But it sounds more like the activity should register as a page changed listener to the ViewPager itself, and update its state depending on the page rather than which fragment is active.
As a side note, ViewPagerIndicator is quite old now (hasn't been updated in 3 years), a more modern approach is the SlidingTabs example from Google, which has been built into a library available here: https://github.com/nispok/slidingtabs
I have a button that I want to change its value often, so my Activity has a private variable :
private Button p1_button = (Button)findViewById(R.id.firstbut);
This simple line makes my app crash. If I put inside the onCreate it works and I can interact with the button (change text etc).
EDIT : I think I found the reason. I should initialize AFTER setcontentview ?
EDIT: Thank you for the constructive answers. I have now a different problem I removed the initialization and I did it on onCreate and it works (But I keeped the p1_button declaration as a private field). But when I tried to modify the button in a different method of my activity (just changing the text), it crashes again. So the return value of findViewById is "local" to the method where it is called and I should setcontentview in every method that access UI elements ?
Do not call findViewById() until after you call setContentView(). Otherwise, the widget will not exist.
More generally, do not call inherited methods on Activity until after super.onCreate(), unless specifically advised to do so.
It depends where you are calling this line.
http://i.stack.imgur.com/6EQaU.png
The onCreate() method contains a call to setContentView() and before this is called, Android has no idea what to do with your button as it hasn't been inflated yet!
Therefore as a really easy rule of thumb, always make sure setContentView (or if you're dealing with fragments onCreateView()) have been called and completed. Only then will findViewById() work.
If you would like further guidance, please post some code in which the crash occurs.
edit: I tried to add the image properly but don't have enough rep.
To understand this you need to know the Activity lifecycle. You are trying to look a view which has not yet been created by Android.
As per the android lifecycle explained here "http://developer.android.com/training/basics/activity-lifecycle/starting.html". In onCreate() method the activity is created and you can access different views of the activity. If you will try to look for view before onCreate() the app will crash as it does not know whether that view exists or not.
I'm trying to define an onClick handler method in an XML layout for buttons in a Dialog but the app crashes when the buttons are clicked due to NoSuchMethodException (it can't find the method). The method signature is public void searchMovies(View) and I can guarantee that it is spelled consistently in the XML file and in code. This similar question provides a solution by putting the putting the method into the Activity that the Dialog belongs to, but that doesn't work for me.
However, I'm using a FragmentActivity and FragmentStatePagerAdapter, so maybe this is the reason it doesn't work for me? I've tried putting the method into the FragmentActivity, the FragmentStatePagerAdapter, the Fragment and also the anonymous OnClickListener class that handles launching the Dialog. None of them have worked, all give NoSuchMethodException error. Again, I can guarantee that the method is spelled correctly/consistently.
I know that I can do this programmatically, but it would be much more convenient if I could do it the other way. Is it possible? Thanks.
As I said in the comments above, this is the solution (I suppose this is a duplicate, then, but I reckon it still might be useful to someone looking for the solution. I don't mind if someone feels that it should be deleted though).