replace the Fragment within the tab(Without viewpager) - android

I have 2 tabs in my app.Each have single fragment initially.
Scenario 1(Tab 1):
I 'm adding a second fragment in the tab on Button Click from the first fragment & again a third fragment on button click from second fragment.
Scenario 2(Tab 2):
Similar as tab1
Scenario 2(Switch between the Tab):
As I switch between the tab.I'm unable to get same tab fragment which I have added in the respective tab.
Below is my code:(First Fragment Tab1)
public class ArticleFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup view=(ViewGroup) inflater.inflate(R.layout.article_fragment, container,false);
fragmentTabHost.setup(getActivity(), getChildFragmentManager() , R.id.frag_container);
Button article_button = (Button) view.findViewById(R.id.article_btn);
article_button.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
article_txt.setText("Changed Value");
ArticleDetails articleFragment = new ArticleDetails();
fragmentTransaction.add(ScreenFragmentActivity.getContainertId(), articleFragment, AppConstants.ARTICLE_FRAGMENT_DETAILS);
fragmentTransaction.hide(ArticleFragment.this);
fragmentTransaction.addToBackStack(ArticleFragment.class.getName());
fragmentTransaction.commit();
}
});
return view;
}
}
Second Fragment Tab1:
public class ArticleDetails extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
ViewGroup view=(ViewGroup) inflater.inflate(R.layout.article_details, container,false);
Button article_button = (Button) view.findViewById(R.id.article_details_btn);
article_button.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
ArticleDetailsWithIn articleFragment = new ArticleDetailsWithIn();
fragmentTransaction.add(ScreenFragmentActivity.getContainertId(), articleFragment,
AppConstants.ARTICLE_FRAGMENT_DETAILS_WITHIN);
fragmentTransaction.hide(ArticleDetails.this);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return view;
}
My Layout:
<android.support.v4.app.FragmentTabHost
android:id="#+id/tabhost"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TabWidget
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal" />
<FrameLayout
android:id="#+id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
So Basically I'm trying to add the new Fragment within the tab .But on Switch I'm not able to retain my respective fragment

You can try this - tag your fragments with some name and store this in any static helper class using getter/setter method. Make your first fragment tag name as default (this is for first time launch). Then at place where you have logic to add new fragments, put the required if-else statements. Same goes for other tab also. (you can even use shared preferences, if you want to remember last seen fragment even when app is closed and restarted again.)
Create a static helper class.
public class HelperClass {
private static string TabOneFragmentOnScreen = "";
public static String getTabOneFragmentOnScreen () {
return TabOneFragmentOnScreen ;
}
public static void setTabOneFragmentOnScreen(
String TabOneFragmentOnScreen) {
HelperClass.TabOneFragmentOnScreen = TabOneFragmentOnScreen;
}
}
When you click one TabOne
if(HelperClass.getTabOneFragmentOnScreen.equals("")){
HelperClass.setTabOneFragmentOnScreen("FragmentOne");
//logic to add fragment one goes here
}
if(HelperClass.getTabOneFragmentOnScreen.equals("FragmentTwo")){
HelperClass.setTabOneFragmentOnScreen("FragmentTwo");
//logic to add fragment two goes here
}
This way it will always remember the last fragment on screen under tab one.
This code is not complete, but you can develop further on this logic.

Related

Fragment overlapping each other...and previous fragment is clicking

I created an application in which i had 1 ACTIVITY and 8 Fragment in which i am inflating every fragment into the activity. but my problem is that every fragment is overlapping each other. I change the background color of every fragment but when i am clicking the vacant spaces button of my previous fragment get clicked.
please suggest me some thing to get out of this situation.
Main_Activity.class
public class ActRegistration extends AppCompatActivity {
FragmentManager fm;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_registration);
fm = getSupportFragmentManager();
loadFragment(new FragmentRegLogSkip(), FragmentRegLogSkip.FRAGMENT_KEY);
}
public void loadFragment(Fragment fragmentName, String fragmentKey) {
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.add(R.id.id_registration_layout_frame, fragmentName);
fragmentTransaction.addToBackStack(fragmentKey);
fragmentTransaction.commit();
}
}
Frag_1.class
public class FragmentRegLogSkip extends Fragment implements View.OnClickListener {
private Activity activity;
private Context context;
public static final String FRAGMENT_KEY = "fragment_reg_log_skip";
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
context = getContext();
LanguageChanger.changeLanguage(context);
View view = inflater.inflate(R.layout.act_registration_screen_login, container, false);
return view;
}
}
Don't forget to add android:clickable="true" and android:focusable="true" to the parent view of your second fragment so it catches the clicks and they don't get propagated to the fragment below. Something like this:
<android.support.constraint.ConstraintLayout 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:clickable="true"
android:focusable="true">
You're using fragmentTransaction.add(), which won't remove the previous Fragment - use fragmentTransaction.replace() if you want the other Fragment's view to be removed.
Note FragmentManager automatically restores any previously added Fragments when your Activity is recreated (i.e., when savedInstanceState != null). Therefore you'll want to ensure that you only add your initial Fragment once - when the savedInstanceState is null.
if (savedInstanceState == null) {
loadFragment(new FragmentRegLogSkip(), FragmentRegLogSkip.FRAGMENT_KEY);
}
Inside your second fragment layout file's Parent Tag , add this :-
android:clickable="true"
android:focusable="true"
then when you click on any view , it will not click previous fragment.

Where do we get the transcation ID that we replace on the Fragment

I am new to this Fragment theory and I can't seem to understand where we get the R.id.container So I want to start a fragment once a button is clicked. Here is my method
My main Method, I have not added any code to start my Fragment class.
callCenter.setOnClickListener(view -> openCallCenter());
//on clicked open call center which should start a fragment
private void openCallCenter() {
}
My Fragment Class: empty for now;
public class CallCenterFragment extends Fragment {
public static final String TAG = CallCenterFragment.class.getSimpleName();
public CallCenterFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_call_center, container, false);
}
}
My Fragment Layout Empty for now:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:id="#+id/fragment_container"
tools:context=".fragment.CallCenterFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>
SO: my biggest question is on my mainActivity class what code should I add to start this fragment and can someone explain to me since I have seen several example where do we get transaction.replace(R.id.container)
Thanks in advance.
So I will refer you here for more details
On the container Purpose of Container in Fragments for Android
And if you want to display your fragment on the Main activity as your question says try this code.
Add the code on the method.
CallCenterFragment fragment = new
CallCenterFragment();
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.replace(R.id.container, fragment);
trans.commit();
Note. On your main xml you need to add the container id eg.
<FrameLayout
android:id="#+id/container"
Add width and height />
You will display the text given on your fragment which is string hello blank fragment.
Set the ViewPager in activity xml file where you want show fragment. Create a sub class PageAdapter for super class for super class FragmentPagerAdapter. Complete abstract methods in Subclass.
public class PageAdapter extends FragmentPagerAdapter {
public PageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getI tem(int position) {
Fragment fragment = null;
switch (position){
case 0:{
fragment = new ContactFragment();
break;
}
case 1:{
fragment = new RecentFragment();
break;
}
}
return fragment;
}
#Override
public int getCount() {
// 2 is no of fragments
return 2;
}
}
Then After
//--write this code in base activity of fragment
contactview_f = (ViewPager) findViewById(R.id.fragment_layout);
pageAdapter = new PageAdapter(getSupportFragmentManager());
contactview_f.setAdapter(pageAdapter);

How to start shared element transition using Fragments?

I am trying to implement transitions between fragments which have "shared elements" as described in the new material design specs.
The only method I can find is the ActivityOptionsCompat.makeSceneTransitionAnimation, which I believe works on Activity only.
I've been searching for this same functionality but with/for fragments.
I had the same problem but had it working by adding a new fragment from another fragment.
The following link is very helpful in getting started on this: https://developer.android.com/training/material/animations.html#Transitions
Following is my code that works. I'm animating an ImageView from one fragment to the other.
Make sure the View you want to animate has the same android:transitionName in both fragments.
The other content doesn't really matter.
As a test, you could copy this to both your layout xml files. Make sure the image exists.
<ImageView
android:transitionName="MyTransition"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/test_image" />
Then I have 1 file in my res/transition folder, named change_image_transform.xml.
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeImageTransform />
</transitionSet>
Now you can get started. Lets say you have Fragment A containing the image and want to add Fragment B.
Run this in Fragment A:
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.product_detail_image_click_area:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));
setExitTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode));
// Create new fragment to add (Fragment B)
Fragment fragment = new ImageFragment();
fragment.setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));
fragment.setEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.explode));
// Our shared element (in Fragment A)
mProductImage = (ImageView) mLayout.findViewById(R.id.product_detail_image);
// Add Fragment B
FragmentTransaction ft = getFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.addToBackStack("transaction")
.addSharedElement(mProductImage, "MyTransition");
ft.commit();
}
else {
// Code to run on older devices
}
break;
}
}
The shared element fragment transitions do work with ListViews, as long as the source and target views have the same (and unique) transitionName.
If you make your list view adapter to set unique transitionNames to the views you want (e.g. some constant + specific item id) and also change your detail fragment to set the same transitionNames to the target views at runtime (onCreateView), the transitions actually work!
Shared elements do work with Fragments but there are some things to keep in mind:
Don't try to set the sharedElementsTransition in the onCreateView of your Fragment. You have to define them when creating an instance of your Fragment or in onCreate.
Take note of the official documentation on the possible animations for enter/exit transitions & sharedElementTransition. They are not the same.
Trial and error :)
This should be a comment to the accepted answer, as I am unable to comment on it.
The accepted answer (by WindsurferOak and ar34z) works, except for a "minor" problem which caused a null pointer exception when navigating up with the backStack. It seems that setSharedElementReturnTransition() should be called on the target fragment instead of the original fragment.
So instead of:
setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));
it should be
fragment.setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_transform));
https://github.com/tevjef/Rutgers-Course-Tracker/issues/8
Following are some helpful resources:
https://github.com/lgvalle/Material-Animations
http://www.androiddesignpatterns.com/2014/12/activity-fragment-transitions-in-android-lollipop-part1.html
https://www.youtube.com/watch?v=5e1Yh0fSZhQ
The key is to use a custom transaction with
transaction.addSharedElement(sharedElement, "sharedImage");
Shared Element Transition Between Two Fragments
In this example, one of two different ImageViews should be translated from the ChooserFragment to the DetailFragment.
In the ChooserFragment layout we need the unique transitionName attributes:
<ImageView
android:id="#+id/image_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_first"
android:transitionName="fistImage" />
<ImageView
android:id="#+id/image_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_second"
android:transitionName="secondImage" />
In the ChooserFragments class, we need to pass the View which was clicked and an ID to the parent Activity wich is handling the replacement of the fragments (we need the ID to know which image resource to show in the DetailFragment). How to pass information to a parent activity in detail is surely covered in another documentation.
view.findViewById(R.id.image_first).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mCallback != null) {
mCallback.showDetailFragment(view, 1);
}
}
});
view.findViewById(R.id.image_second).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mCallback != null) {
mCallback.showDetailFragment(view, 2);
}
}
});
In the DetailFragment, the ImageView of the shared element also needs the unique transitionName attribute.
<ImageView
android:id="#+id/image_shared"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:transitionName="sharedImage" />
In the onCreateView() method of the DetailFragment, we have to decide which image resource should be shown (if we don't do that, the shared element will disappear after the transition).
public static DetailFragment newInstance(Bundle args) {
DetailFragment fragment = new DetailFragment();
fragment.setArguments(args);
return fragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_detail, container, false);
ImageView sharedImage = (ImageView) view.findViewById(R.id.image_shared);
// Check which resource should be shown.
int type = getArguments().getInt("type");
// Show image based on the type.
switch (type) {
case 1:
sharedImage.setBackgroundResource(R.drawable.ic_first);
break;
case 2:
sharedImage.setBackgroundResource(R.drawable.ic_second);
break;
}
return view;
}
The parent Activity is receiving the callbacks and handles the replacement of the fragments.
#Override
public void showDetailFragment(View sharedElement, int type) {
// Get the chooser fragment, which is shown in the moment.
Fragment chooserFragment = getFragmentManager().findFragmentById(R.id.fragment_container);
// Set up the DetailFragment and put the type as argument.
Bundle args = new Bundle();
args.putInt("type", type);
Fragment fragment = DetailFragment.newInstance(args);
// Set up the transaction.
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Define the shared element transition.
fragment.setSharedElementEnterTransition(new DetailsTransition());
fragment.setSharedElementReturnTransition(new DetailsTransition());
// The rest of the views are just fading in/out.
fragment.setEnterTransition(new Fade());
chooserFragment.setExitTransition(new Fade());
// Now use the image's view and the target transitionName to define the shared element.
transaction.addSharedElement(sharedElement, "sharedImage");
// Replace the fragment.
transaction.replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName());
// Enable back navigation with shared element transitions.
transaction.addToBackStack(fragment.getClass().getSimpleName());
// Finally press play.
transaction.commit();
}
Not to forget - the Transition itself. This example moves and scales the shared element.
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class DetailsTransition extends TransitionSet {
public DetailsTransition() {
setOrdering(ORDERING_TOGETHER);
addTransition(new ChangeBounds()).
addTransition(new ChangeTransform()).
addTransition(new ChangeImageTransform());
}
}
I searched for SharedElement in fragments and I find very useful source code on GitHub.
1.first you should define transitionName for your Objects(Like ImageView) in both Fragments layout(We add a button in fragment A for handling click event):
fragment A:
<ImageView
android:id="#+id/fragment_a_imageView"
android:layout_width="128dp"
android:layout_height="96dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="80dp"
android:scaleType="centerCrop"
android:src="#drawable/gorilla"
android:transitionName="#string/simple_fragment_transition />
<Button
android:id="#+id/fragment_a_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="24dp"
android:text="#string/gorilla" />
fragment B:
<ImageView
android:id="#+id/fragment_b_image"
android:layout_width="match_parent"
android:layout_height="250dp"
android:scaleType="centerCrop"
android:src="#drawable/gorilla"
android:transitionName="#string/simple_fragment_transition" />
Then you should write this code in your transition file in transition Directory(if you haven't this Directory so create One: res > new > Android Resource Directory > Resource Type = transition > name = change_image_transform ):
change_image_transform.xml:
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds/>
<changeTransform/>
<changeClipBounds/>
<changeImageTransform/>
</transitionSet>
In the last step you should complete codes in java:
fragment A:
public class FragmentA extends Fragment {
public static final String TAG = FragmentA.class.getSimpleName();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_a, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final ImageView imageView = (ImageView) view.findViewById(R.id.fragment_a_imageView);
Button button = (Button) view.findViewById(R.id.fragment_a_btn);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getFragmentManager()
.beginTransaction()
.addSharedElement(imageView, ViewCompat.getTransitionName(imageView))
.addToBackStack(TAG)
.replace(R.id.content, new FragmentB())
.commit();
}
});
}
}
fragment B:
public class FragmentB extends Fragment {
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setSharedElementEnterTransition(TransitionInflater.from(getContext()).inflateTransition(android.R.transition.move));
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_b, container, false);
}
}
don't forget to show your "A" fragment in your activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.content, new SimpleFragmentA())
.commit();
}
source : https://github.com/mikescamell/shared-element-transitions
How to start shared element transition using Fragments?
I assume you want to transition of your Image using Fragment (instead of Activity)
it wont work perfectly if you have already set AppTheme
keep the transition name of source and destination same
You have to do three things for transition:
1.Set transitionName to the source View(xml or programatically) -> before calling makeFragmentTransition
private void setImageZoom(boolean isImageZoom) {
ImageView imageView = this.findViewById(R.id.image);
if (isImageZoom) {
imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ViewCompat.setTransitionName(imageView, "imageTransition");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
makeFragmentTransition(imageView);
}
}
});
}
}
2.Fragment Transition
Set TransitionSet for the specicific Transition animation
apply them on Fragment
call addSharedElement(View, transitionName) while fragmentTransition
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
public void makeFragmentTransition(ImageView sourceTransitionView) {
//transtionName for sourceView
//MUST set transitionName before calling this method(programattically or give ->transitionName to the view in xml)
String sourceTransitionName = ViewCompat.getTransitionName(sourceTransitionView);
TransitionSet transitionSet = new TransitionSet();
transitionSet.setDuration(500);
transitionSet.addTransition(new ChangeBounds()); //to expand boundaries
transitionSet.addTransition(new ChangeTransform()); //for transtion vertically
transitionSet.addTransition(new ChangeImageTransform()); // image transform work
transitionSet.setOrdering(TransitionSet.ORDERING_TOGETHER);
ImageTransitionFragment fragment = new ImageTransitionFragment();
fragment.setSharedElementEnterTransition(transitionSet);
fragment.setSharedElementReturnTransition(transitionSet);
fragment.setAllowReturnTransitionOverlap(false);
try {
getHostActivity().getSupportFragmentManager()
.beginTransaction()
//sharedElement is set here for fragment
//it will throw exception if transitionName is not same for source and destionationView
.addSharedElement(sourceTransitionView, sourceTransitionName)
//R.id.fragmentView is the View in activity on which fragment will load...
.replace(R.id.fragmentView, fragment)
.addToBackStack(null)
.commit();
} catch (Exception e) {
//
String string = e.toString();
}
}
3.set desitionNation transitionName in ImageView
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/destionationTransitionPage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionName="#string/pageTransition"
android:background="#color/black_color">
<com.android.foundation.ui.component.FNImageView
android:id="#+id/destinationImageView"
android:layout_width="#dimen/_400dp"
android:layout_gravity="center"
android:transitionName="imageTransition"
android:layout_height="#dimen/_400dp" />
</FrameLayout>
Please respond if anything is not clear or it need more improvement

Add Android Fragments dynamically

I created a new fragment that holds two other fragments a right and a left fragment. I called this fragment GridFragment. When i dynamically add GridFragments only the last added fragment is shown. It looks like my GridFragment instance is reused every time I add it. Any ideas why this happens?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1.0"><FrameLayout
android:id="#+id/left_fragment"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:layout_width="0dip">
</FrameLayout>
<FrameLayout
android:id="#+id/right_fragment"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:layout_width="0dip"
>
</FrameLayout>
public class GridFragment extends Fragment {
private FragmentManager fm;
private FragmentTransaction ft;
private Fragment leftFragment;
private Fragment rightFragment;
private boolean isLeftFragmentSet = false;
private boolean isRightFragmentSet = false;
public GridFragment(Fragment leftFragment, Fragment rightFragment) {
this.leftFragment = leftFragment;
this.rightFragment = rightFragment;
}
public Fragment getLeftFragment() {
return leftFragment;
}
public Fragment getRightFragment() {
return rightFragment;
}
public boolean isLeftFragmentSet() {
return isLeftFragmentSet;
}
public boolean isRightFragmentSet() {
return isRightFragmentSet;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.grid_fragment, container, false);
fm = getFragmentManager();
fm.beginTransaction().add(R.id.left_fragment, leftFragment, leftFragment.toString()).commit();
fm.beginTransaction().add(R.id.right_fragment, rightFragment, rightFragment.toString()).commit();
return rootView;
}
public void setLeftFragment(Fragment fragment){
leftFragment = fragment;
isLeftFragmentSet = true;
}
public void setRightFragment(Fragment fragment){
rightFragment = fragment;
isRightFragmentSet = true;
}
}
I want to use this to get a screen filled with wide fragments and two smaller fragments alternately.
Here is an example of what I want to achieve:
I see in your code fundamental mistakes.
First of all rootView is not part of your Activity layout at the time when you request left and right fragments to be added by FragmentManager which is looking for R.id.left_fragment inside Activity layout.
Secondly, if you want nest fragments within fragment you have to use getChildFragmentManager() instead getFragmentManager(). Also make use of FragmentTransaction chain builder, so instead:
fm.beginTransaction().add(R.id.left_fragment, leftFragment, leftFragment.toString()).commit();
fm.beginTransaction().add(R.id.right_fragment, rightFragment, rightFragment.toString()).commit();
call:
fm.beginTransaction().add(R.id.left_fragment, leftFragment, leftFragment.toString())
.add(R.id.right_fragment, rightFragment, rightFragment.toString())
.commit();
Maybe you should consider placing your fragments directly inside Activity layout and replace your GridFragment with GridLayout.

Android. Close Fragment by calling Method in the Fragment from a Button in the Fragment?

Im new to Android and so far everything went fine. Until i entered the Fragment Terrain.
In my Application I want a user to click a button in a activity. With that Button pressed so far i´m opening a fragment in which the user can change Settings.
Then i want to close, delete, whatever as long as i dont see the fragment anymore, from within the fragment.
So: Activity "A", opens Fragment "a".
- do stuff in the Fragment -
User, calls Method in "a" by Button, to close "a" .
here is my xml file to the fragment "a":
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="145dp"
android:orientation="vertical"
android:background="#EBDDE2" >
//took out a seekbar textview and checkbox for now.
<Button
android:id="#+id/buttonLeaveFragment"
style="#style/buttonredblack"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_below="#+id/seekBar_Radius"
android:onClick="closeFragment" <--- this i want to call in the fragment.
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:text="#string/button_ok" />
</RelativeLayout>
here is the java file of my fragment "a" activity:
public class SearchingRadiusFragment extends Fragment implements OnSeekBarChangeListener{
public static String username;
public void onAttach(Activity activity){
super.onAttach(activity);
}
public void onCeate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setUpLayout();
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view= inflater.inflate(R.layout.fragment_radius_searching,container, false);
return view;
}
#SuppressLint("NewApi")
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
Bundle bundle = this.getArguments();
if(bundle != null){
username = bundle.getString("username", null);
}
}
public void closeFragment(View v){
((UserProfileActivity)getActivity()).closeSearchingRadiusFragment();
}
}
now the necessary method in the activity "A":
public void closeSearchingRadiusFragment(){
SearchingRadiusFragment frag = new SearchingRadiusFragment();
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.setCustomAnimations(android.R.animator.fade_in,android.R.animator.fade_out);
transaction.remove(frag);
transaction.addToBackStack(null);
transaction.commit();
}
what am i missing?
eclipse gives me a Illegal.State.Expression. Saying the method closeFragment() could not be found in activity "A". Even though i want to use the one in the fragment "a".
If i change the name of the Method buttonLeaveFragment is calling to: closeSearchingFragment
Nothing happens, but the app doesn´t crash either.
You need to replace your visible fragment "A" with a new fragment (for example "B") using:
transaction.replace(R.id.framelayout, fragmentB);
On click button try this:
FragmentTransaction transaction=fragmentManager.beginTransaction();
transaction.setCustomAnimations(android.R.animator.fade_in,android.R.animator.fade_out);
transaction.replace(R.id.framelayout, fragmentB);
transaction.commit();
Your visible fragmentA will be replace from fragmentB

Categories

Resources