In advance, thank you for taking a few moments to read through this question and point out what is most likely an obvious mistake in my code. I've done some research and can't find a similar question- so here it is.
I am trying to create an android screen that shows 3 fragments separated on the screen like this- (first fragment in upper left as a search fragment, second (beneath it as a recycler layout) and the third detail fragment which inflates once an object is clicked on from the recycler list.
Page layout example:
I've accomplished this using a linear layout with two fragment containers with layout_weights, so when the search button is clicked in the first fragment, the recycler list takes the spot of the search fragment, and once clicked on inflates the detail container on the right, but again ideally id like all three fragments to be on the screen at the same time.
Here's the XML test layout that'd like to use:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/fragmentTest1"
android:name="com.swimlabs.pcms.progressionapp.SearchFragment"
android:layout_width="319dp"
android:layout_height="179dp"
android:layout_marginEnd="2dp"
app:layout_constraintBottom_toTopOf="#+id/divider"
app:layout_constraintEnd_toStartOf="#+id/divider2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/divider"
android:layout_width="325dp"
android:layout_height="14dp"
android:layout_marginEnd="2dp"
android:layout_marginTop="200dp"
android:background="?android:attr/listDivider"
app:layout_constraintEnd_toStartOf="#+id/divider2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/divider2"
android:layout_width="14dp"
android:layout_height="711dp"
android:layout_marginEnd="938dp"
android:background="?android:attr/listDivider"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/fragmentTest1"
app:layout_constraintTop_toTopOf="parent" />
<fragment
android:id="#+id/fragmentTest2"
android:name="com.swimlabs.pcms.progressionapp.SwimmerListFragment"
android:layout_width="270dp"
android:layout_height="424dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/divider2"
app:layout_constraintStart_toStartOf="parent" />
<fragment
android:id="#+id/fragment5"
android:name="com.swimlabs.pcms.progressionapp.ProgressionFragment"
android:layout_width="923dp"
android:layout_height="640dp"
android:layout_marginBottom="7dp"
android:layout_marginEnd="9dp"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/divider2" />
</android.support.constraint.ConstraintLayout>
Here are code excerpts how I am dynamically creating the fragments. Here is my singleton fragment class. What's commented out here is my old code which worked for with the linear layout with 2 containers.
public abstract class SingleFragmentActivity extends AppCompatActivity {
protected abstract Fragment createFragment();
#LayoutRes
protected int getLayoutResId() {
// return R.layout.master_coach;
return R.layout.test;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResId());
FragmentManager fm = getSupportFragmentManager();
// Fragment fragment = fm.findFragmentById(R.id.fragment_container);
Fragment fragment = fm.findFragmentById(R.id.fragmentTest1);
if (fragment == null) {
fragment = createFragment();
fm.beginTransaction()
// .add(R.id.fragment_container, fragment)
.add(R.id.fragmentTest1, fragment)
.commit();
}
}
}
Here is the onClick method from within the search fragment. I've tried overriding the onCreateView method from the SwimmerListActivity, and also tried playing with the fragment manager, but none of this works.
mSearchButton.setOnClickListener(new View.OnClickListener () {
#Override
public void onClick(View v) {
// Fragment fragment = SwimmerListFragment.newInstance();
// FragmentManager fm =
// getActivity().getSupportFragmentManager();
// fm.beginTransaction()
// .add(R.id.fragmentTest2, fragment)
// .commit();
Intent intent = new Intent(getActivity(),
SwimmerListActivity.class);
startActivity(intent);
}
});
I keep getting an error like this:
08-13 19:04:59.291 21931-21931/com.swimlabs.pcms.progressionapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.swimlabs.pcms.progressionapp, PID: 21931
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.swimlabs.pcms.progressionapp/com.swimlabs.pcms.progressionapp.CoachActivity}: android.view.InflateException: Binary XML file line #41: Binary XML file line #41: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
Where line 41 is the test.xml line where the second fragment begins.
If you can't tell I'm very new to this but I appreciate any resources or even general advice from you guys that can point me in the right direction to fix this. I don't expect anyone here to write my code for me. Thanks, please let me know if I can include any other information.
If you have to replace one fragment to another use .replace instead .add...ignore if that is not the case, sorry cant post an comment
It is easy these days. You can easily inflate fragments over constraint layout where ever you want to.
In .xml file, state three different constraint layout with IDs (No fragment View as stated above), constraint1,constraint2,constraint3. The design can be as you prefer.
Then use code like this for inflating fragments over these constraints:
FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
Fragment fragment=new YourFragment1();
fragmentTransaction.replace(R.id.constraint1,fragment,null).commit();
Change your fragment name and respective constraint you want to inflate those fragment.
Related
I have MainActivity and added 2 fragments in R.id.container.
The MainActivity looks like the following.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
getSupportFragmentManager().beginTransaction()
.add(R.id.container, Fragment1.newInstance())
.commit();
getSupportFragmentManager().beginTransaction()
.add(R.id.container, Fragment2.newInstance())
.commit();
}
}
Fragmnet1 and Fragment2 have the same code with different layouts.
public class Fragment1 extends Fragment {
public static Fragment1 newInstance() {
return new Fragment1();
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_1, container, false);
}
}
And the associated layout fragment1.xml is
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
tools:context=".ui.main.Fragment1">
<TextView
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Layout for Fragment2 is fragmnet2.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
tools:context=".ui.main.Fragment1">
<TextView
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Test2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Here is the Debug GPU overdraw MainActivity after adding Fragment1 and Fragment2
See this image below. This is the one more drawing of GPU because the layout in Fragment1 remains in the MainActivity.
How can I add fragments without loading/showing the fragment below?
You are adding two fragments in the same container. This is the exact behaviour as per your code. If you need to show the fragment added later only, you need to replace the fragment instead of add.
I do not know the exact use case of yours. However, I guess you are trying to show fragment1 and fragment2 based on some checking. In that case, you might consider having two functions like the following in your MainActivity.
public boolean fragment1Loaded = false;
public void switchToFrag1() {
fragment1Loaded = true;
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, Fragment1.newInstance())
.commit();
}
public void switchToFrag2() {
fragment1Loaded = false;
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, Fragment2.newInstance())
.commit();
}
Now in the onCreate function, you need to call a function based on a condition which is necessary.
if (showFirstFragment) switchToFrag1();
else switchToFrag2();
You can do the switching whenever necessary from MainActivity.
Hope that helps!
Update
You can handle the back button click in your MainActivity and handle the logic by yourself. Override the onBackPressed function and then switch the fragments based on your necessity. For example, see the modified functions above. I am keeping a reference of which fragment is loaded in the screen right now. Then override the onBackPressed function like the following.
#Override
public void onBackPressed() {
if (fragment1Loaded) super.onBackPressed();
else switchToFrag1();
}
Hope you get the idea.
even though i googled extensively, i cant find a solution to my problem. I am new to programming, so please consider that in your answer.
I have a Main Activity and a Menu bar at the bottom. Since the menu bar is scrollable and i want to have it for all the different screens, i figured out that i could - instead of making an intent for a new activity - just put a fragment on top of the existing screen (and spare out the menu bar).
But i fail at programatically opening that fragment. I tried the following, but it doesnt even recognice the ID of the FrameLayout.
I was trying to replace a FrameLayout in my Main Activities' xml file with the fragment:
FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft =
fragmentManager.beginTransaction();
ft.replace(R.id.idOfFrameLayout, new nameOfFragmentClass());
ft.commit();
EDIT:
It works after i implemented OnFragmentInteractionListener into the Main Activity. Thanks to everyone!
My original answer suggested using add instead of replace for the Fragment transaction. I have since learned that either can be used in this case. For more info on the differences, see this, this and this
Since my add/replace idea was off base, I've changed my answer to a simple Fragment tutorial. One Fragment inflated from one Activity. I've included the code for Fragment to Activity communication (the reason for the OPs problem) but left comments on what could be deleted if that's not needed. The only thing done in the Activity is launching the Fragment then receiving a message back from that Fragment. The Fragment has a button that will cause a message to be sent back to the Activity. The message will then be Logged.
In both classes, if no communications is needed from the Fragment to the Activity, delete anything that is marked TODO:
// this is what controls whether you use a Fragment from the support library
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class SimpleActivity extends AppCompatActivity
// TODO: delete "implements SimpleFragment.OnFragmentInteractionListener" from this
// line (leave the '{')
implements SimpleFragment.OnFragmentInteractionListener {
private static final String TAG = SimpleActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple);
SimpleFragment fragment = new SimpleFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
// TODO: this entire method can be deleted
#Override
public void onFragmentInteraction(String message) {
// This is where you can act on the message from the Fragment. You would do
// things that are done from an Activity or you may pass the message on
// to another Fragment.
Log.d(TAG, message);
}
}
Most import statements aren't shown, I left this one in to indicate using the support library
import android.support.v4.app.Fragment;
public class SimpleFragment extends Fragment {
private OnFragmentInteractionListener mListener; // TODO: delete this line
public SimpleFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_simple, container, false);
Button button = (Button)rootView.findViewById(R.id.msg_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// TODO: delete these 3 lines, do something else with the button click
if (mListener != null) {
mListener.onFragmentInteraction("Message from Fragment");
}
}
});
return rootView;
}
// TODO: this entire method can be deleted
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
// TODO: this entire method can be deleted
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
// TODO: this entire method can be deleted
public interface OnFragmentInteractionListener {
void onFragmentInteraction(String message);
}
}
Now the layout files. 1st activity_simple.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_container"
>
</FrameLayout>
</android.support.constraint.ConstraintLayout>
Then fragment_simple.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Info to Activity"
android:id="#+id/msg_button"
/>
</RelativeLayout>
This is a very basic sample. Here is a more extensive guide for Fragment usage.
When you use the 'replace' method, you need 3 things:
1- the container id, which is the view that is going to hold your fragment's view.
2- the fragment instance you want to use and
3- the fragment instance's tag, but this is optional.
Given that, let's say you have the following layout for your activity:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
...
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?android:attr/windowBackground"
app:menu="#menu/navigation" />
</android.support.design.widget.CoordinatorLayout>
The FrameLayout which id is "container" is the holding view, so that's the id you've gotta use:
ft.replace(R.id.container, new nameOfFragmentClass());
I suggest use this library to manage fragments:
FragmentManagerAndroid
I am trying to get a fragment to show that contains an EditText and a button. I am new to using fragments, so I am not sure exactly what the error message I get when trying to create the fragment means.
I have a class that extends Fragment, this is where the EditText and button are created.
public class EditNameFragment extends android.support.v4.app.Fragment {
EditText editText;
ImageButton button;
public EditNameFragment(){
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.edit_name_dialog, container, false);
editText = (EditText) view.findViewById(R.id.editTextDialog);
button = (ImageButton) view.findViewById(R.id.submitNewItemButtonDialog);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//stuff
}
});
return view;
}
Here is edit_name_dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:id="#+id/edit_name_dialog"
>
<EditText
android:id="#+id/editTextDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageButton
android:id="#+id/submitNewItemButtonDialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
And here in my main activity (which must extend FragmentActivity because of another part) is where I try to set up my Fragment. I think it has something to do with what id I am referencing. I have seen some people using container classes when using fragments, but I do not understand why this is done.
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
EditNameFragment fragment = new EditNameFragment();
fragmentTransaction.add(R.id.edit_name_dialog, fragment, "tag");
fragmentTransaction.commit();
I get the error message when trying to run the code above
No view found for id 0x7f09002a (com.myapp:id/edit_name_dialog) for fragment EditNameFragment
If anyone could explain what I am missing here/ why people use container classes, that would be great. I know some people add fragments using XML, but I would like to do this only using java.
EDIT
I have added a class that extends FragmentActivity, following the model for a container class
public class EditNameFragmentActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_name_fragment_container);
}
}
Is the parameter for setContentView supposed to be the layout, or an id?
Here is the xml file that defines where the fragment should be
edit_name_fragment_container.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
>
<fragment android:name="com.returnjump.spoilfoil.EditNameFragment"
android:id="#+id/edit_name_fragment_container"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="#layout/edit_name_fragment" />
</LinearLayout>
So for the parameter in
fragmentTransaction.add(R.id.edit_name_dialog, fragment, "tag");
this is supposed to reference the id of the fragment, correct?
It still gives me the same error, what am I missing?
There are basically two ways to add a fragment to an activity like the documentation say:
"statically": by declaring the fragment inside the activity's layout file.
"dynamically": adding the fragment programmatically. Like you tried to do.
Here is the documentation: http://developer.android.com/guide/components/fragments.html
If you wish to add it dynamically, here is the documentation part that you want to read:
At any time while your activity is running, you can add fragments to your activity layout. You simply need to specify a ViewGroup in which to place the fragment.
To make fragment transactions in your activity (such as add, remove, or replace a fragment), you must use APIs from FragmentTransaction. You can get an instance of FragmentTransaction from your Activity like this:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
You can then add a fragment using the add() method, specifying the fragment to add and the view in which to insert it. For example:
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
The first argument passed to add() is the ViewGroup in which the fragment should be placed, specified by resource ID, and the second parameter is the fragment to add.
Once you've made your changes with FragmentTransaction, you must call commit() for the changes to take effect.
And about why to use dynamic fragments instead of static fragments, it has been made for interactive UI allowing you to simply handle different fragments into one activity as you please.
really in need of some advice, dont know what is wrong here.
Context:
2 fragments with a Textview each and the main activity has 2 button and a edittext
Aim:
Type hello into the edittext box in the main activity and
When click on the button for fragment 1, the textview will change to hello.
Problem:
Face a runtime error when enter hello into edittext and click on button 1.
Logcat:
E/AndroidRuntime(1291): FATAL EXCEPTION: main
E/AndroidRuntime(1291): android.view.InflateException: Binary XML file line #29: Error inflating class fragment
E/AndroidRuntime(1291): android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
E/AndroidRuntime(1291):android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
E/AndroidRuntime(1291):android.view.LayoutInflater.inflate(LayoutInflater.java:489)
E/AndroidRuntime(1291): android.view.LayoutInflater.inflate(LayoutInflater.java:396)
E/AndroidRuntime(1291): com.example.FragmentOne.onCreateView(FragmentOne.java:19)
E/AndroidRuntime(1291):android.app.FragmentManagerImpl.moveToState(FragmentManager.java:829)
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="#00ffff">
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="This is fragment No.1"
android:textStyle="bold" />
</LinearLayout>
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="#+id/easy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="selectFrag"
android:text="Fragment No 1" />
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="selectFrag"
android:text="Fragment No 2" />
<fragment
android:name="com.example.FragmentTwo"
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void selectFrag(View view) {
Fragment fr;
if(view == findViewById(R.id.button2)) {
fr = new FragmentTwo();
}else {
fr = new FragmentOne();
}
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.commit();
}
}
FragmentOne.java
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_one, container, false);
TextView monthlypayment= (TextView) view.findViewById(R.id.textView1);
EditText easy = (EditText) inflater.inflate(R.layout.activity_main, container, false).findViewById(R.id.easy);
monthlypayment.setText(easy.getText().toString());
return view;
}
}
There are two ways you can add a fragment to the activity layout:
Declare the fragment inside the activity's layout file.
Programmatically add the fragment to an existing ViewGroup.
Both methods are mentioned in the docs
http://developer.android.com/guide/components/fragments.html
If you want add the fragment to a container you need to use a ViewGroup in xml. Generally FrameLayout is used. So have the below in xml
<FrameLayout
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
The Activity code is fine. On Button click you replace the appropriate fragment in the container.
In your Fragment onCreateView you inflate the fragment layout and use the view object to initialize views of that layout. But you inflate activity_main.xml which is not required.
Quoting docs
Specifically, the fragment can access the Activity instance with
getActivity() and easily perform tasks such as find a view in the
activity layout
So for EditText you can use
EditText easy = (EditText)getActivity().findViewById(R.id.easy);
Or Initialize EditText in Activity on Button click get the value from EditTextand then you can pass the value of EditText from Activity to Fragment
Send data from activity to fragment in android
show me the onclick method, and the container u have fragment one in... its one of two things,
either you are programmatically adding a view which already exists, or you are tryin to update the ui without a handler.... handlers can be worked around in fragments, so im assuming its the first one....
I have a ListView in one side and a fragment on the other side. I am trying to make a simple app to figure out how fragments works.
Here is my code:
Main Activity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// storing string resources into Array
//
setContentView(R.layout.activity_main);
String[] adobe_products = getResources().getStringArray(R.array.adobe_products);
//List view
final ListView list = (ListView)findViewById(R.id.questionsList);
ArrayAdapter<String> adapter;
adapter = new ArrayAdapter<String>(this, R.layout.list_item, adobe_products);
//final TextView text = (TextView)findViewById(R.id.textView1);
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
//String selectedFromList =(String) (list.getItemAtPosition(position));
//text.setText(selectedFromList);
}
});
list.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#SuppressLint("ValidFragment")
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.activity_fragment, container, false);
}
}
}
Main Activity XML Layout
<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="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"
android:orientation="vertical"
tools:context=".MainActivity" >
<ListView
android:id="#+id/questionsList"
android:layout_width="144dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_weight="0.07" >
</ListView>
<fragment android:name="com.example.Layout.MyFragment"
android:id="#+id/article_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
UPDATE: Thanks for your help, I noticed that the fragment is a subclass so I included it inside my activity. But still getting the same result. it stops and doesn't even open. Anyway I updated the whole code that logCat.
LogCat:
02-22 00:06:50.944: E/AndroidRuntime(2886): FATAL EXCEPTION: main
02-22 00:06:50.944: E/AndroidRuntime(2886): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.layout/com.example.layout.MainActivity}: android.view.InflateException: Binary XML file line #21: Error inflating class fragment
02-22 00:06:50.944: E/AndroidRuntime(2886): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
02-22 00:06:50.944: E/AndroidRuntime(2886): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
02-22 00:06:50.944: E/AndroidRuntime(2886): at android.app.ActivityThread.access$600(ActivityThread.java:141)
Any idea to make it working?
I would recommend you to go through http://developer.android.com/guide/components/fragments.html and http://developer.android.com/training/basics/fragments/creating.html
I found many structural and Design problem in your Code , once you go through the above link you will understand it , also download the sample app available on above link page , if still you are not able to do I will surely try to give explanation with sample code. Good luck
Make the following changes in your code
1.add the fragment in activity layout like below and don't forget to replace YOUR PACKAGE NAME specified in class attribute
<fragment
android:id="#+id/article_fragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
class="YOUR PACKAGE NAME.MyFragment" />
2. Create MyFragment as a separate Class (Should not be inside the Main Activity):
3. Main Activity must extends FragmentAcivity instead of Actvity
4. if you need Listview and fragment side by side change LinearLayout Orientation to android:orientation="horizontal"
It will work
Hey u forgot to set the orientation for linear layout. By default its horizontal so just add the orientation attribute .
<LinearLayout
android:orientation="vertical" >
</LinearLayout>
in ur linear layout tag.
for the error inflating class fragment just change
import android.app.Fragment;
to: import android.support.v4.app.Fragment;
use onCreateView() to set layout for fragment -
The system calls this when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View from this method that is the root of your fragment's layout. You can return null if the fragment does not provide a UI.