I have a fragment activity that creates several fragments for a viewpager. The first fragment I'm making is a port from previously being an activity. Before the activity's onCreate method set a textview based on some prior user input.
However now that this is a fragment the same code in onCreateView is ignoring the setText() method and only ever shows the default XML layout text inside the UI elements.
I've seen other people with this issue and yet not found it to be resolved. How can I setText for a textview in a fragment, the way it used to work for onCreate in an activity?
Thanks.
edit: The text I'm trying to set comes in through an intent when the host FragmentActivity (which makes the fragments) is created. So
Activity A + String str -->
creates FragmentActivity (gets str from intent). -->
Fragment 1, textView TV, TV.sestText(str);
If you need to see code, its from this example:
http://thepseudocoder.wordpress.com/2011/10/04/android-tabs-the-fragment-way/
http://thepseudocoder.wordpress.com/2011/10/05/android-page-swiping-using-viewpager/
Where inside Tab1Fragment, I've added a textview to the XML file, and I'm trying to call setText inside the onCreateView method in Tab1Frag.
If I recall, it goes something like this...
public RelativeLayout onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (container == null) {
return null;
}
View view = inflater.inflate(R.layout.frag1_layout, null);
title = (TextView) view.findViewById(R.id.frag1_title);
title.setText("Success!");
return (RelativeLayout)inflater.inflate(R.layout.frag1_layout, container, false);
}
Related
I have an Android Activity, from which I want to show a Dialog. It would probably be a custom DialogFragment. Now when the user clicks on specific buttons I want the layout's inside the dialog to change with the data from the previous DialogFragment and so that it would have an ability to also go back to previous Layout.
I dont think there is an easy way to change views inside of the same DialogFragment so what would be the best way to do this?
I have tried doing it in method onViewCreated and when a button is clicked, but nothing happens.
In my activity I call the fragment like this at the moment:
FragmentManager fm = getSupportFragmentManager();
NewDialog newDialog = NewDialog.newInstace(userId, loc, currentId);
newDialog.setNewClickListener(new NewDialog.OnNewClickListener() {
#Override
public void onCancelClicked() {
finishAdd();
}
#Override
public void onAcceptClicked() {
...
}
});
newDialog.show(fm, "new_frag");
And the fragment:
public class NewDeliveryPointDialog extends DialogFragment {
private LayoutInflater inflater;
private ViewGroup container;
public NewDialog(){
}
public static NewDialog newInstace(){
...
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
this.inflater = inflater;
this.container = container;
return inflater.inflate(R.layout.dialog_layout_1, container);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
saveButton.setOnClickListener(v -> {
View.inflate(getContext(), R.layout.dialog_layout_2, container);
view.invalidate();
view.refreshDrawableState();
}
});
}
}
A DialogFragment is not made to have navigation to other fragments within the same dialog.
You basically have these options:
On your button click you close the Dialog and open another Dialog. But this seems odd. If there is so much happening, probably dialogs are not the best shot.
Instead of DialogFragments have another fragment container overlaying the original one (basically what a Dialog fragment does for you). Within the second container you can easily navigate to other fragments and set it to gone when the user finished interaction.
If there are just a few Views in the Dialog, you could consider setting the old ones to gone and the new ones to visible
I think your code didn't work, because container is null. Method onCreateView gives you #Nullable ViewGroup container, which is null for DialogFragment (but non null for Fragment). So when you call View.inflate(getContext(), R.layout.dialog_layout_2, container), it just creates a view in memory and doesn't attach it to container, cause it is null. See LayoutInflater.inflate, cause View.inflate is just a convenience wrapper for this function.
I dont think there is an easy way to change views inside of the same DialogFragment so what would be the best way to do this?
Instead of changing dialog root you can just manipulate child views inside dialog root layout (add, remove them, or change visibility).
Also my advice is to use recommended way to create dialog with custom layout (onCreateDialog + setView), but if you don't want to do that, you can refer view you've created in onCreateView as dialog root.
You can try creating a dialog fragment with an empty shell layout in which you would replace your two different fragments with ChildFragmentManager and regular fragment transactions
passing data between them can be done using the activity's view model since they both live in the same activity.
So add the ShellDialogFragment using the activity's FragmentManager and in the shell fragment class change between NewDialog & NewDeliveryPointDialog on your button click listener with ChildFragmentManager
This question already has answers here:
NullPointerException accessing views in onCreate()
(13 answers)
Closed 8 years ago.
EDIT
Changed title.
SDK Guide document says, Activity.onCreate complete after Fragment.onCreateView and Fragment.onAcvityCreated.
But If I try findViewById for a view of the fragment it returns null.
How can I access contents of the fragment?
I'm very new to Android UI dev.
Below is a sample code generated by Eclipse IDE.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
// this is null
View rootView = findViewById(R.id.txtView);
}
}
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
First of all, I want to access inner contents of the 'fragment_main'.
Can I do this with findViewById?
I found that calling findViewById for a view of the fragment at onCreate call is not working.
How do I know when the Fragment views are ready at the Activity level?
I read How to implement OnFragmentInteractionListener
Am I needed to manually implement a event listener for this?
I think short answer is 'impossible' or 'not works like that'.
If one want to manage inner contents of fragments just delete fragments and move all the contents to the activity layout.
But If I try findViewById for a view of the fragment it returns null.
You can not just access the view of the fragment in your activity's oncreate or where ever, you can call view of the fragment in your activity.
I found that calling findViewById for a view of the fragment at onCreate call is not working.
That is because the view is not inflated yet in your fragment thus returning null.
Have a look at the fragment life cycle:
(source: xamarin.com)
As you can see onCreate is before onCreateView which you inflate your view for the fragment's layout.
solution:
you call findViewByIdit in your fragment's onActivityCreated.
sample:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
TextView sample = (TextView) getView().findViewById(your_id);
}
I have an activity with several tabs (using the 'fixed tabs + swipe' style). Each tab layout is defined as a fragment xml file.
Eg, my activity is called ModifyCustActivity. This uses an almost-empty xml file called activity_modify_cust.xml. Each tab on this page is represented by various xml files such as fragment_modify_cust_basic and fragment_modify_cust_address etc etc. Each of these fragment xml files contains EditTexts, Spinners and more.
When the activity starts, I need to be able to access these views from the activity code, as I need to pre-populate them, and get their results once they are edited. However, because these views exist in a fragment xml file, I don't seem to be able to reach them in code. Is there a way to access a view contained in a fragment xml file?
Is there a way to access a view contained in a fragment xml file?
Yes it is, but your fragment should be declared in the XML layout file, which seems to be your case.
For example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...">
<fragment
android:name="com.example.MyFragment"
android:id="#+id/my_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
And you would access the fragment like this:
FragmentManager manager = getSupportFragmentManager();
MyFragment fragment = (MyFragment)manager.findFragmentById(R.id.my_fragment);
Then using the fragment instance you could further access your views, for example by calling a public method from the fragment which updates some particular view.
UPDATE:
Suppose you have a TextView that appears in layout of the fragment, and need to update from the activity.
Let this be the fragment class:
public class MyFragment extends Fragment{
private TextView textView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, null, false);
textView = (TextView)view.findViewById(R.id.textView);
return view;
}
public void updateTextView(String text){
textView.setText(text);
}
}
Then you would update the TextView by calling in your activity the updateTextView() method:
fragment.updateTextView("text");
You can reach fragments views from activity. If you want to send a data from fragment to another fragment. Your sender fragment must communicate with activity and your activity can manipulate the view in other fragment
http://developer.android.com/training/basics/fragments/communicating.html
Just created a new project in the newest ADT release in Eclipse and found that it will setup up certain environments for you to get things started. I choose Tabs + Swipe.
It has this code I have question on:
public static class DummyFragment extends Fragment {
public DummyFragment () {
}
public static final String ARG_SECTION_NUMBER = "section_number";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
textView.setGravity(Gravity.CENTER);
Bundle args = getArguments();
textView.setText(Integer.toString(args.getInt(ARG_SECTION_NUMBER)));
return textView;
}
}
Both tabs refer to this same fragment. All it does is switch the content on the TextView that has the tab position number on it (1,2, or 3).
The more advanced question first: I want two different Fragments that the tab switches to. In the example code, it points to the same fragment. Where does this change take place? and can I see brief code example?
Easier question: I have two pre-defined XML layouts I'd like to set each tab (or Fragment) with. Do I do this in the actual Fragment? And if so, where? setContentView does't seem to be working in the onCreateView method?
Not really sure what this question is asking exactly, but if I understand correctly the TabHost (or whatever you are using to manage the Fragment tabs) is instantiating multiple instances of the DummyFragment and then attaching each to the screen when a tab is clicked. This is all done behind the scenes... all you need to worry about is implementing the Fragment and telling the TabHost when it should be instantiated/displayed.
Fragments don't have a setContentView method. You should inflate your Fragment's layout from xml in onCreateView. For instance with,
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout, container, false);
}
I'm new to Android developing and of course on Fragments.
I want to access the controls of my fragment in main activity but 'findViewById' returns null.
without fragment the code works fine.
Here's part of my code:
The fragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="HardcodedText" >
<EditText
android:id="#+id/txtXML"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:ems="10"
android:scrollbars="vertical">
</EditText>
</LinearLayout>
the onCreate of MainActivity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
this.initialisePaging();
EditText txtXML = (EditText) findViewById(R.id.txtXML);}
on this point the txtXML is null.
What's Missing in my code or what should I do?
Try like this on your fragments on onCreateView
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
return null;
}
LinearLayout ll = (LinearLayout )inflater.inflate(R.layout.tab_frag1_layout, container, false);
EditText txtXML = (EditText) ll.findViewById(R.id.txtXML);
return ll;
}
You should inflate the layout of the fragment on onCreateView method of the Fragment then you can simply access it's elements with findViewById on your Activity.
In this Example my fragment layout is a LinearLayout so I Cast the inflate result to LinearLayout.
public class FrgResults extends Fragment
{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
//some code
LinearLayout ll = (LinearLayout)inflater.inflate(R.layout.frg_result, container, false);
//some code
return ll;
}
}
I'm late, but for anyone else having this issue. You should be inflating your view in the onCreateView method. Then override the onCreateActivity method and you can use getView().findViewById there.
#Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment, container, false);
}
You can't access the the view of fragment in activity class by findViewById instead what you can do is...
You must have an object of Fragment class in you activity file, right? create getter method of EditText class in that fragment class and access that method in your activity.
create a call back in Fragment class on the event where you need the Edittext obj.
1) Try this:
Eclipse menu -> Project -> Clean...
update
2) If you have 2 or more instances of 'main' layout, check if all of them have a view with 'txtXML' id
3)
A Fragment is a piece of an application's user interface or behavior that can be placed in an Activity. Interaction with fragments is done through FragmentManager, which can be obtained via Activity.getFragmentManager() and Fragment.getFragmentManager().
The Fragment class can be used many ways to achieve a wide variety of results. It is core, it represents a particular operation or interface that is running within a larger Activity. A Fragment is closely tied to the Activity it is in, and can not be used apart from one. Though Fragment defines its own lifecycle, that lifecycle is dependent on its activity: if the activity is stopped, no fragments inside of it can be started; when the activity is destroyed, all fragments will be destroyed.
Study this. you must use FragmentManager.
If you want use findViewById as you use at activities onCreate, you can simply put all in overrided method onActivityCreated.
All the answers above tell you how you should "return the layout" but don't exactly tell you how to reference the layout that was returned so I was unable to use any of the solutions given. I used a different approach to solve the problem. In the Fragment class that handles the fragment, got to the onViewCreated() class and create a context variable in it that saves the context of the parent activity (main activity in my case).
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Context fragmentContext = (MainActivity) view.getContext();
}
Once that is done, you can use the new context to access items on your fragment from inside the onViewCreated() method.
EditText editText = context.findViewById(R.id.textXML);