Adding a fragment inside another fragment dynamically - android

i want add a fragment inside another one dynamically .
the outer fragment is a DialogFragment :
public class MapFragmentDialog extends DialogFragment implements OnMapClickListener, OnMapLongClickListener,
OnMarkerDragListener {
FragmentManager fmanager;
Fragment fragment;
SupportMapFragment supportmapfragment;
public static MapFragmentDialog newInstance() {
MapFragmentDialog f = new MapFragmentDialog();
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View v = inflater.inflate(R.layout.map_fragment, container, false);
// *********** add myMapFragment
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// add a fragment
MyMapFragment myFragment = new MyMapFragment();
fragmentTransaction.add(R.id.myfragment, myFragment);
fragmentTransaction.commit();
myMap = ((SupportMapFragment)getActivity().getSupportFragmentManager().findFragmentById(R.id.myMap)).getMap();
return v;
}
the map_fragment layout is like this :
<TextView
android:id="#+id/txtHelp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingBottom="6dip"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="12sp" />
<FrameLayout
android:id="#+id/myfragment"
android:layout_width="0px"
android:layout_height="wrap_content" />
my inner fragment MyMapFragment :
public class MyMapFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.my_map_fragment, container, false);
return myFragmentView;
}}
the my_map_fragment layout contain :
<fragment
android:id="#+id/myMap"
android:layout_width="match_parent"
android:layout_height="300dp"
class="com.google.android.gms.maps.SupportMapFragment" />
i get an exception on getting the map fragment on my DialogFragment , a NullPointerException at this line
myMap = ((SupportMapFragment)getActivity().getSupportFragmentManager().findFragmentById(R.id.myMap)).getMap();

I remember seeing something about fragments in fragments working only dynamically and not by placing them XML. I think Abd El-Rahman El-Tama has the correct idea of using a frameLayout nstead of specifying a fragment directly

To change the Fragments dynamically all what you need is
1) A FrameLayout in your Layout as following:
<FrameLayout
android:id="#+id/fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
2) Initialize the FrameLayout into your activity as following:-
FrameLayout fragment = (FrameLayout) findViewById(R.id.fragment);
3) Start Fragment transaction as following:
getSupportFragmentManager().beginTransaction().replace(R.id.fragment, new MyFragment()).commit();
Or
FragmentManager fragMan = new FragmentManager();
fragMan.beginTransaction ();
fragMan.replace (R.id.fragment);
fragMan.commit ();

Related

How can i call a method in my fragment from my activity?

Theoretically, lets say i have two classes with corresponding XML files - Activity and Frag
Activity.java
public class Activity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fragment fragment = new Frag();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragmentArea, fragment);
ft.commit();
}
}
Frag.java
public class Frag extends Fragment {
private TextView txtView;
public Frag() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_, container, false);
txtView = view.findViewById(R.id.textView);
return view;
}
public void setTextView(String str) {
txtView.setText(str);
}
}
activity 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.eksamen.chris.eksempelfragment.Activity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/fragmentArea">
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Fragment xml
<FrameLayout 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"
tools:context="com.eksamen.chris.eksempelfragment.Frag">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Fragment"
android:id="#+id/textView"/>
</FrameLayout>
As you can see, i have the method setTextView() in my Frag class. Obviously enough, what i would like to do is to call that method from my Activity class.
I have tried grasping this for some hours now, and i really cannot figure out a way to do this. Every example/tutorial out there makes my app crash.
Could someone explain to me how this works, taken the example we have in hand into consideration? Or maybe there is a better way to provide the fragment with data from my activity?
I'd be grateful!
Edit: awful indentation, had some issues, trying to fix.
In order to pass data from Activity to Fragment , you have to use :
Bundle
which is a KEY VALUE data structure for passing values between fragments and activity so at your onCreate() in Activity class will be
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String str = "your_string_here";
// 1 -
Bundle bundle = new Bundle();
// 2 -
bundle.putString("KEY", str);
Fragment fragment = new Frag();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
// 3 -
fragment.setArguments(bundle);
ft.replace(R.id.fragmentArea, fragment);
ft.commit(); }
and at your fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_, container, false);
txtView = view.findViewById(R.id.textView);
// 4 - NOTE : Should hould the same key at the Activity class :
String str = getArguments().getString("KEY");
setTextView(str);
return view;
}

Fragment is not showing up in activity

Trying to add Fragment to my Activity, but it isn't showing up.
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WeatherFragment mainFragment = new WeatherFragment();
getFragmentManager()
.beginTransaction()
.add(R.id.main_weather_container, mainFragment)
.commit();
}
}
And there is my fragment:
public class WeatherFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
boolean isAttachedToParent = false;
View inflatedView = inflater.inflate(R.layout.main_weather_fragment, container, isAttachedToParent);
return inflatedView;
}
}
R.id.main_weather_container - FrameLayout in my MainActivity.
R.layout.main_weather_fragment - Fragment's layout
What am i doing wrong?
I've tried to use FragmentActivity + v4 support fragment and fragmentSupportManager, but it didn't make any difference.
MainActivity xml:
<?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="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="#+id/main_weather_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="#dimen/padding_16_dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/words_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3" />
</LinearLayout>
UPDATED: The problem wasn't in fragment transaction or whatever, i've used tools: namespace that's why fragment wasn't displayed. Sorry about that :(
try this way .in your activity call fragment
Fragment fragment = Video_fragment.newInstance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.framecontainer, fragment).commit();
in fragment class.
public class Video_fragment extends Fragment{
View view;
public static Fragment newInstance() {
Video_fragment fragment = new Video_fragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view= inflater.inflate(R.layout.video_frag, container, false);
return view;
}
}
Create a instance of Fragment in WeatherFragment:
public static WeatherFragment newInstance() {
Bundle args = new Bundle();
WeatherFragment weatherFragment = new WeatherFragment();
weatherFragment.setArguments(args);
return weatherFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout, container, false);
}
Inside your Activity in MainActivity :
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WeatherFragment weatherFragment = WeatherFragment.newInstance();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.flContainerId, weatherFragment)
.commit();
}
Your layout file will be:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/flContainerId"/>
public class WeatherFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View inflatedView = inflater.inflate(R.layout.main_weather_fragment, null, false);
return inflatedView;
}
}
As I can see, you are using AppCompatActivity but using getFragmentManager.
With AppCompatActivity you will need to use getSupportFragmentManager() rather than getFragmentManager()
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WeatherFragment mainFragment = new WeatherFragment();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.main_weather_container, mainFragment)
.commit();
}
}
Your WeatherFragment should be extend android.support.v4.app.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="match_parent"
android:weightSum="4"
android:orientation="vertical">
<FrameLayout
android:id="#+id/main_weather_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="#dimen/padding_16_dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/words_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3" />
</LinearLayout>
Added WeightSum in the parent Layout.

activity send data to fragment but what fragment received is null

There is an activity containing a Button and a LinerLayout which is the container of Fragment. The layout of Fragment only contains a TextView. I want to send a string to fragment from activity, but what fragment received is null. Why?
xml of Activity:
<Button
android:id="#+id/load"
android:layout_width="match_parent"
android:layout_height="80dp"
android:text="load" />
<!--the container of fragment-->
<LinearLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" />
xml of Fragment:
<TextView
android:id="#+id/fragment_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Java code of Activity:
public class DynamicFragmentActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_fragment);
findViewById(R.id.load).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//create fragment and set data
MyFragment myFragment = new MyFragment();
Bundle bundle = new Bundle();
bundle.putString("text", "demo");
myFragment.setArguments(bundle);
//commit
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container, myFragment);
fragmentTransaction.commit();
}
});
}
}
Java code of Fragment:
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.myfragment, container, false);
TextView textView = (TextView) view.findViewById(R.id.fragment_text);
//receive data
String text = getArguments().getBundle("text")+"";
textView.setText(text);
return view;
}
}
Try this , Hope it helps ...........
public class MyFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.myfragment, container, false);
TextView textView = (TextView) view.findViewById(R.id.fragment_text);
//change getBundle() to getString()
String text = getArguments().getString("text")+"";
textView.setText(text);
return view;
}
}
What you are doing now is get a Bundle called text and what you really want is get a string in the bundle:
Bundle arg = getArguments();
String txt = arg.getString("text");

Changing fragments

I am trying to show different fragments depending on whether GPS is enabled or not. But I am getting this error :-
Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f0e00a1
Please advise me how to do this:
Here is my MainActivity class:
public class MainActivity extends Activity {
Fragment fr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final LocationManager mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
fr = new FragmentTwo();
getFragment();
} else {
fr = new FragmentOne();
getFragment();
}
}
public void getFragment() {
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.commit();
}
}
FragmentOne:-
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_one, container, false);
}
}
FragmentTwo:-
public class FragmentTwo extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_two, container, false);
}
}
My activity_main:-
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="#+id/fragment_place"
android:name="com.test.FragmentTwo"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
And the fragment_one.xml and fragment_two.xml are same just the different text:-
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="GPS IS ENABLE"/>
</RelativeLayout>
Thanks in advance.
Replace
<fragment
android:id="#+id/fragment_place"
android:name="com.test.FragmentTwo"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
With
<FrameLayout
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
As static Fragment can not be replace at run time. But you can add or replace fragment in FrameLayout.
You can remove this line
android:name="com.test.FragmentTwo"
<fragment
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

Creating a side tab

I was able to create a tab layout using the tutorial in androidhive. I was wondering if I can put a side tab on it. . When you click an Item on the left side, an activity will be displayed on the right side.
I was wondering If I can do it. Thank you very much.
Try to design your layout as below:
Here its fragment_top_rated.xml file code:
<RelativeLayout 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"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/passenger"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="2dp"
android:orientation="horizontal"
android:weightSum="1">
<FrameLayout
android:id="#+id/frameLayout1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight=".4"
android:background="#android:color/background_dark" >
</FrameLayout>
<FrameLayout
android:id="#+id/frameLayout2"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight=".6"
android:background="#android:color/darker_gray" >
</FrameLayout>
</LinearLayout>
</RelativeLayout>
You can load this screen on tabs click with the fragments into it.
EDITED:
Supposing that you have developed your project exactly same as the defined demo of you question link.
In your Tabactivity as you select places tab load the Fragment of places in the left side.
It defined in link on tab selected you just have to load fragments.
PlacesFragment
In your PlacesFragment write code as below:
public class PlacesFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated,
container, false);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft1 = fm.beginTransaction();
Fragment m_fragSet = new GamesFragment();
ft1.replace(R.id.frameLayout2, m_fragSet);
ft1.commit();
FragmentManager fmg = getFragmentManager();
FragmentTransaction ftrans = fmg.beginTransaction();
Fragment m_frag = new MoviesFragment();
ftrans.replace(R.id.frameLayout1, m_frag);
ftrans.commit();
return rootView;
}
}
Create right side fragment Games
public class GamesFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_games, container, false);
return rootView;
}
}
Here is MoviesFragment.java
public class MoviesFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movies, container, false);
return rootView;
}
}
In your TabsAdapter define as below:
public class TabsPagerAdapter extends FragmentPagerAdapter {
FragmentActivity context;
public TabsPagerAdapter(FragmentManager fm,FragmentActivity act) {
super(fm);
context=act;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new TopRatedFragment();
case 1:
// Games fragment activity
return new GamesFragment();
case 2:
// Movies fragment activity
return new MoviesFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
Here is the Output

Categories

Resources