I created new project with Navigation Drawer Activity template in Android Studio 2.2.2. I decided to use FrameLayout, so as i click on navigation menu item, new fragment loads.
In my content_main.xml i have FrameLayout element like this:
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
That is Frame where the content will be shown.
Then i have layout fragment_one.xml and its class FragmentOne and they look like this:
fragment_one.xml
<Button
android:text="Default Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/mybutton" />
FragmentOne class
public class FragmentOne extends Fragment {
Button btn;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
btn = (Button) view.findViewById(R.id.mybutton);
return view;
}
public void changeBtnText(String txt)
{
btn.setText(txt);
}
}
In MainActivity's onCreate() method i have code:
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.content_frame, new FragmentOne()).commit();
FragmentOne fragment_obj = (FragmentOne)getSupportFragmentManager().
findFragmentById(R.id.frOne);
fragment_obj.changeBtnText("Changed text");
Here i get error:
Attempt to invoke virtual method 'void com.example.user.myapplication.FragmentOne.changeBtnText(java.lang.String)' on a null object reference
How I can change fragment's Button text from Main Activity by using changeBtnText(String txt) method?
Call changeBtnText(String txt) inside fragment not in the activity.
EDIT:
inside FragmentOne.class
public FragmentOne newInstance(String text) {
FragmentOne fragmentOne = new FragmentOne ();
Bundle args = new Bundle();
args.putInt("text", text);
fragmentOne .setArguments(args);
return fragmentOne ;
}
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
btn = (Button) view.findViewById(R.id.mybutton);
String text = getArguments().getString("text", null);
changeBtnText(text);
return view;
}
in the Activity
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.content_frame, FragmentOne.newInstance("text")).commit();
You haven't created the Fragment, which is why it's null. You create a new one in line but don't save it.
Try this;
FragmentOne fragment_obj = new FragmentOne();
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.content_frame, fragmentOne).commit();
fragment_obj.changeBtnText("Changed text");
Related
I have button to go to (load) this new fragment
buttonToFragment1.setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View arg0) {
// return inflater.inflate( R.layout.fragment_one, container, false);
Fragment fr = new FragmentOne();
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_awal, fr);
fragmentTransaction.commit();
}
}
);
the current fragment (R.id.fragment_awal) now replaced with loaded new fragment (R.id.fragment_one) which has layout (fragment_one.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:orientation="vertical"
android:background="#00c4ff">
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Ini fragment 1"
android:textStyle="bold" />
</LinearLayout>
and the class is :
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment
return inflater.inflate( R.layout.fragment_one, container, false);
}
}
My question is how to load this TextView1 so that I can do such :
TextView textFragment = (TextView)findViewById(R.id.textView1);
textFragment.setText(" new text");
which basically set text to a view inside the new loaded fragment.
EDIT : May I know who answered this question earlier??? basically he did answered this correct, I just somehow so confused. He just deleted the answer. I want to accept his answer.
Fragments are essentially view containers that contain a hierarchy of views. When a fragment is inserted into the view hierarchy, it must have an activity as its root. There can be more 0 or more fragments active at any given time.
In loose words, you're replacing the current view with the view of another fragment (FragmentOne).
To access the TextView with id textView1, you need to qualify the findViewById method with the current view of the fragment.
Change your fragment code to:
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment
View view = inflater.inflate( R.layout.fragment_one, container, false);
// The findViewById method returns child views from either a Context,
// an Activity or another View itself.
TextView textFragment = (TextView) view.findViewById(R.id.textView1);
textFragment.setText(" new text");
return view;
}
}
You need to inflate the layout and after that you can reference the TextView:
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment
View view = inflater.inflate( R.layout.fragment_one, container, false);
TextView textFragment = (TextView) view.findViewById(R.id.textView1);
textFragment.setText(" new text");
return view;
}
So I'm trying to change my layout with a button using fragment, but I can't get it to work, probably because I don't really understand how it works. I'm very new to programming overall so I have a bit trouble understanding some stuff. Anyways, this is what I want to do.
MainActivity
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragmenttwo thenewfrag = new Fragmenttwo();
fragmentTransaction.replace(android.R.id.content, thenewfrag);
Button splay = (Button) findViewById(R.id.splay);
splay.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragmentone newfrag = new Fragmentone();
fragmentTransaction.replace(android.R.id.content, newfrag);
fragmentTransaction.commit();
}
});
fragmentTransaction.commit();
}
}
Fragmentone
public class Fragmentone extends Fragment {
public Fragmentone() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.mainmenu, container, false);
return view;
}
}
Fragmenttwo
public class Fragmenttwo extends Fragment{
public Fragmenttwo() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.start_board, container, false);
return view;
}
}
mainmenu.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainmenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/mainmenu" >
<Button
android:id="#+id/splay"
android:layout_width="195dp"
android:layout_height="64dp"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
LogCat (I get NullPointerException on the onClickLitsener? Error happends when button pressed)
E/AndroidRuntime(2001): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gerfort.gerfortrps/com.gerfort.gerfortrps.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
Any ideas how to do fix this? Or how to change layout using a button?
Button yourButton = (Button) rootView
.findViewById(R.id.btnid);
yourButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Fragment newFragment = new YourFragment();
FragmentTransaction transaction = getFragmentManager()
.beginTransaction();
// Replace whatever is in the fragment_container view with this
// fragment,
// and add the transaction to the back stack
transaction.replace(android.R.id.content, newFragment);
transaction.addToBackStack("tag");
// Commit the transaction
transaction.commitAllowingStateLoss();
}
});
Your button splay is in mainmenu.xml, which is loaded in FragmentOne. So you would need to find its reference like this:
public class Fragmentone extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.mainmenu, container, false);
Button splay = (Button) view.findViewById(R.id.splay);
//onClick here
return view;
}
}
Your button splay is null. So you are getting
E/AndroidRuntime(2001): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gerfort.gerfortrps/com.gerfort.gerfortrps.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
Hope it helps.
P.S: reference for better understanding of fragments
My Fragment
public class CustomFrag extends Fragment {
private Button btn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment, container, false);
btn = (Button)view.findViewById(R.id.button1);
return view;
}
public void sendItem(String item) {
btn.setText(item);
}
}
And in my activity
public void loadFragment(String data) {
// Load up new fragment
Fragment fragment = new CustomFrag();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.contentFragment, fragment, "custFrag");
transaction.addToBackStack("custFrag");
transaction.commit();
// Required before calling fragment methods
getSupportFragmentManager().executePendingTransactions();
// Load fragment with data
CustomFrag frag = (CustomFrag) getSupportFragmentManager().findFragmentByTag("custFrag");
frag.sendItem(data);
}
I'm getting a nullpointer exception any time I attempt to use the views of my fragment. If I try to load the view inside the method as well, it will not work
i.e. inside sendItem()
btn = (Button)getView().findViewById(R.id.button1);
My layout (button_fragment) contains the button:
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Because you have executed the transaction does not mean that the fragment has actually created its view. Which is why btn is still null.
To pass data from the activity to the fragment, use the argument bundle:
Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);
Then, in onCreateView:
btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments().getString("item"));
See this Best practice for instantiating a new Android Fragment question and the first answer.
The problem here is that the fragment's layout is not drawn yet when sendItem(...) is called. Which means btn is null at that point. Instead, this is how you're supposed to do it (see http://developer.android.com/guide/components/fragments.html):
public class CustomFrag extends Fragment {
private Button btn;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.button_fragment, container, false);
btn = (Button)view.findViewById(R.id.button1);
btn.setText(getArguments.getString("item"));
return view;
}
}
And
public void loadFragment(String data) {
// Load up new fragment
Fragment fragment = new CustomFrag();
Bundle args = new Bundle();
args.putString("item", data);
fragment.setArguments(args);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.contentFragment, fragment, "custFrag");
transaction.addToBackStack("custFrag");
transaction.commit();
// Required before calling fragment methods
getSupportFragmentManager().executePendingTransactions();
}
Edit:
njzk2 was faster, but I hope the details I gave will help you further. In any case, the link he gave explains nicely why you should do it like that.
Hi I'm new to android and was trying to dynamically add content to a Fragment.
I've two Fragments inside an Activity. The first point to the second like this:
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_welcome,
container, false);
Button searchActivityBtn = (Button) rootView.findViewById(R.id.SearchActivityBtn);
searchActivityBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("##SecondActivity", "search btn click");
getFragmentManager().beginTransaction()
.replace(R.id.welcome_fragment, new searchAnnouncementsFragment()).addToBackStack(null).commit();
}
});
return rootView;
}
}
the second Fragment class is
public static class searchAnnouncementsFragment extends Fragment {
public searchAnnouncementsFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_search,
container, false);
return rootView;
}
//public void onStart(){
// super.onStart();
// RelativeLayout root = (RelativeLayout) getActivity().findViewById(R.id.annunciContainer);
// Log.d("##onstart", "root:" + (root == null));
//}
}
As you can see i tried to do something in onStart method but I've always a bunch of errors, the R.id.annunciContainer is the id of the fragment_search.xml layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id ="#+id/annunciContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white" >
What I'm trying to achieve is to dynamically add elements like other FrameLayout to my Fragment ( represented by the above RelativeLayout ).
Any thought?
You didn't mention the name of the activity, lets say the name as Activity1,
First create a linear layout or frame layout in the Activity1
Second add the following lines of code to your Activity1 for inflating PlaceholderFragment into your layout in Activity1
PlaceholderFragment pf = new PlaceholderFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.annunciContainer, pf,"place_holder");
ft.commit();
For inflating searchAnnouncementsFragment replace PlaceholderFragment with searchAnnouncementsFragment.
What I was searching for are ListView
So I am building an Android application which utilize view pager code. The first view of the view pager is a list where user can choose one and view more detail regarding items of which the user selected. I have managed to successfully do this using fragment inside fragment method.
My current issue is with the third view of the view pager. the third view show a summary of action that has been done in the first view and then user can click a button which will replace the current third view with another fragment. The code I used is identical with the one i used in the first view, which is:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.cart_fragment_layout, container, false);
btn_1 = (Button) rootView.findViewById(R.id.btn_1);
btn_1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
fm = getChildFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
CF = new CustomFragment();
ft.addToBackStack("fragment_a");
ft.add(R.id.fragment_custom_container, CF, "custom_fragment1");
ft.commit();
fm.executePendingTransactions();
}
});
return rootView;
}
The onCreateView code for the container of the fragment is as follow:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
try{
rootView = inflater.inflate(R.layout.cart_container, container, false);
fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
CF = new CustomFragment();
Bundle arguments = new Bundle();
ft.addToBackStack("somewords");
ft.add(R.id.fragment_custom_container, CF, "custom_fragment");
CF.setRetainInstance(true);
ft.commit();
fm.executePendingTransactions();
}
catch(Exception E)
{
E.printStackTrace();
System.out.println("exception:"+E.getMessage());
}
return rootView;
}
Whereas the xml layout file of the container is as follow:
<?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"
android:id="#+id/ll_fragment_custom_layout"
android:background="#fff">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_custom_container"
/>
</LinearLayout>
However the code did not work and I received exception:
05-07 12:29:54.570: E/AndroidRuntime(7365): java.lang.IllegalArgumentException: No view found for id 0x7f060045 (com.example.fragmentname:id/fragment_cart_container) for fragment fragmenta{42bae2a0 #0 id=0x7f060045 fragment b}
Is there any error that I made?