fragment won't hide - java

I have a navbar which is supposed to be hidden when a button is pressed, but nothing happens.
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView mavisTxt;
private Button testBtn;
private Fragment navigationBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initVariables();
}
private void initVariables() {
navigationBar = new HeaderNav();
mavisTxt = (TextView)findViewById(R.id.mavisTxt);
testBtn = (Button)findViewById(R.id.testBtn);
testBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction()
.hide(navigationBar)
.commit();
mavisTxt.setText("navbar is hidden");
}
});
}
}
Here is the java file for the fragment
public class HeaderNav extends Fragment {
private static Button homeBtn, optionsBtn, connectionBtn, micBtn, aboutBtn;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,#Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.navbar, container, false);
homeBtn = (Button)view.findViewById(R.id.homeBtn);
optionsBtn = (Button)view.findViewById(R.id.optionsBtn);
connectionBtn = (Button)view.findViewById(R.id.micBtn);
micBtn = (Button)view.findViewById(R.id.homeBtn);
aboutBtn = (Button)view.findViewById(R.id.aboutBtn);
return view;
}
}
and the fragment tag in the main_activity xml :
<fragment
android:id="#+id/navigationBar"
android:name="com.example.egi.mavisme.HeaderNav"
android:layout_width="fill_parent"
android:layout_height="60dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout="#layout/navbar" />
what am I doing wrong? none of the solutions here in SO works for me. Someone help me.
EDIT:
I have edited my code and now it hides. I have another issue when adding a custom animation, I am getting a
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.ViewGroup.startViewTransition(android.view.View)' on a null object reference
Here is my code now :
public class MainActivity extends AppCompatActivity {
private TextView mavisTxt;
private Button testBtn;
private HeaderNav navigationBar;
private FragmentManager fm;
private FragmentTransaction ft;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initVariables();
}
private void initVariables() {
fm = getSupportFragmentManager();
ft = fm.beginTransaction();
navigationBar = (HeaderNav)fm.findFragmentById(R.id.navigationBar);
mavisTxt = (TextView)findViewById(R.id.mavisTxt);
testBtn = (Button)findViewById(R.id.testBtn);
testBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
ft.hide(navigationBar)
.commit();
if(navigationBar.isHidden()) {mavisTxt.setText("navbar is hidden");}
}
});
}
}

Here are some things to note-
Use the ActionBar/ToolBar, this isn't iOS
You have to add a fragment first
You are using the show call instead of hiding it
testBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction()
.**show**(navigationBar)
.commit();
mavisTxt.setText("navbar is hidden");
}
});

Related

Swiping through fragments then app crashed

Like a title , how can i fix it
Error
java.lang.RuntimeException:
com.example.doanlttbdd.MainActivity#28acf243 must implement
OnFragmentInteractionListener
There is MainActivity
public class MainActivity extends AppCompatActivity {
private Toolbar mToolbar;
private ViewPager viewPager;
private TabLayout tabLayout;
private TabsAccessorAdapter tabsAccessorAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar= findViewById(R.id.main_page_toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setTitle("F9");
viewPager= findViewById(R.id.main_tabs_paper);
tabsAccessorAdapter= new TabsAccessorAdapter(getSupportFragmentManager());
viewPager.setAdapter(tabsAccessorAdapter);
tabLayout= findViewById(R.id.main_tabs);
tabLayout.setupWithViewPager(viewPager);
}
Here is myAdapter
public TabsAccessorAdapter(#NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
#NonNull
#Override
public Fragment getItem(int i) {
switch (i){
case 0:
ChatsFragment chatsFragment=new ChatsFragment();
return chatsFragment;
case 1:
GroupsFragment groupsFragment=new GroupsFragment();
return groupsFragment;
case 2:
ContactsFragment contactsFragment=new ContactsFragment();
return contactsFragment;
default:
return null;
}
}
#Override
public int getCount() {
return 3;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0:
return "Chats";
case 1:
return "Groups";
case 2:
return "Contacts";
default:
return null;
}
}
My chatsfragment
public class ChatsFragment extends Fragment {
public ChatsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_chats, container, false);
}
the other fragment just like this
i think it is bacause i'm using androidx so i cannot find any solution to fix it in the internet
RedLine in this (getSupportFragmentManager())
The quick solution first then the explanation
public class MainActivity extends AppCompatActivity implements OnFragmentInteractionListener
It is gonna red lint the MainActivity, alt + enter and choose the solution it will add the missing methods.
The problem is one of your fragments need the parent activity implements that interface to be used as a callback. Probably the fragment is doing something like this
#Override
onAttach...
if context is casteable to the Interface then initialize a field, otherwise crash with the message
These are common patterns. The callback in the parent activity is used to coordinate with other fragments.It is a way to know when something happen on a fragment and then do something on other. The exception throwed is to make sure you implement the needed interface.
This also probably happen for using the fragment wizarf on Android Studio but not reading the checkbox Include callback...
Create a new project.
create a pager adapter TabsPagerAdapter.java
import info.androidhive.tabsswipe.GamesFragment;
import info.androidhive.tabsswipe.MoviesFragment;
import info.androidhive.tabsswipe.TopRatedFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#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;
}
}
Now create First Tab View fragment_top_rated.xml
<?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="match_parent"
android:orientation="vertical"
android:background="#fa6a6a" >
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Design Top Rated Screen"
android:textSize="20dp"
android:layout_centerInParent="true"/>
</RelativeLayout>
now create TopRatedFragment.java
import info.androidhive.tabsswipe.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class TopRatedFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);
return rootView;
}
}
similarly repeat step 3 and 4 to create GamesFragment and MoviesFragment and their XML
now create MainActivity.java
import info.androidhive.tabsswipe.adapter.TabsPagerAdapter;
import info.androidhive.tabsswipe.R;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.Menu;
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Top Rated", "Games", "Movies" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
}

How to start another fragment using button inside the fragment

i have android app which have main activity and three fragment 1-home 2-visa 3-trans,i want to click button in home fragment to start visa fragment ,I've tried more things in home fragment which have the button and
here is my code for Home after i tried to add onclicklistner in onCreatView :
package com.example.ghoniem.myfrag.Fragments;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.ghoniem.myfrag.R;
public class Home extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public Home() {
// Required empty public constructor
}
public static Home newInstance(String param1, String param2) {
Home fragment = new Home();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
Button button=rootView.findViewById(R.id.text_View88);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Visa visa = new Visa();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.visaaa, visa);
fragmentTransaction.commit();
}
});
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
code for visa fragment :
package com.example.ghoniem.mfrag.Fragments;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.ghoniem.myfrag.R;
public class Visa extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public Visa() {
}
public static Visa newInstance(String param1, String param2) {
Visa fragment = new Visa();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_visa, container, false);
}
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
and this xml for fragment_visa
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="#+id/visaaa"
android:layout_height="match_parent"
tools:context="com.example.ghoniem.myfuckenfrag.Fragments.Visa">
<TextView
android:textColor="#color/colorPrimary"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text 2"/>
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:alpha="0.3"
android:src="#drawable/ic_photo_library_black_24dp" />
</FrameLayout>
replace ur onCreateView() in Home Fragment from it
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
Button button=rootView.findViewById(R.id.text_View88);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Visa visa = new Visa();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.visaaa, visa);
fragmentTransaction.commit();
}
});
// Inflate the layout for this fragment
return rootView;
}
the best practice is to define a call back in the activity that is called from fragment 1 when the button is clicked, this call back should replace the fragment
Try This:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Visa fragment = new Visa();
replaceFragment(fragment);
}
});
public void replaceFragment(Fragment someFragment) {
FragmentTransaction transaction = getActivity().getFragmentManager().beginTransaction();
transaction.replace(R.id.visaaa, someFragment);
transaction.addToBackStack(null);
transaction.commit();
}
i tried this and worked for me
Button button=rootView.findViewById(R.id.text_View88);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager=getFragmentManager();
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
Visa visa=new Visa();
fragmentTransaction.replace(R.id.frame,visa);
fragmentTransaction.commit();}
});

When I call next fragment form current the tab selection will not change on Button click

I am trying to develop an android app in which I am going to include tab with fragment. Please find below code for Activity :
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class EnterActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
tabLayout.getTabAt(3).select();
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new EnterCodeFragment(), "ENTER CODE");
adapter.addFragment(new HistoryFragment(), "HISTORY");
adapter.addFragment(new HelpFragment(), "HELP");
adapter.addFragment(new LogoutFragment(), "LOGOUT");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
Below logic I used to call other fragment on button click.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_main, container, false);
Button loginButton = (Button)v.findViewById(R.id.button);
loginButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
Fragment fragment = new EnterCodeFragment();
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.activity_main,fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
// ViewPagerAdapter.get
}
});
return v;
}
When I click on button it will move to the next fragment but tab selection will not change. I think it is creating a new fragment. Any help would be appreciated.
I think you not initialize fragment properly update like above code
Button loginButton = (Button)v.findViewById(R.id.button);
loginButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
EnterCodeFragment fragment = new EnterCodeFragment(); // check this
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.activity_main,fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
// ViewPagerAdapter.get
}
});

FragmentTransaction.add() : wrong Fragment type

I made a fragment to connect via Facebook, the code of which is here :
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.facebook.AccessToken;
import com.facebook.AccessTokenTracker;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.Profile;
import com.facebook.ProfileTracker;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
public class LoginFragment extends Fragment
{
private TextView mTextDetails;
private CallbackManager fbCallbackManager;
private AccessTokenTracker tTracker;
private ProfileTracker pTracker;
private FacebookCallback<LoginResult> fbCallback = new FacebookCallback<LoginResult>()
{
#Override
public void onSuccess(LoginResult loginResult)
{
AccessToken accessToken = loginResult.getAccessToken();
Profile profile = Profile.getCurrentProfile();
}
#Override
public void onCancel()
{
}
#Override
public void onError(FacebookException error)
{
}
};
public LoginFragment()
{
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(getActivity().getApplicationContext());
fbCallbackManager = CallbackManager.Factory.create();
setupTokenTracker();
setupProfileTracker();
tTracker.startTracking();
pTracker.startTracking();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_main, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
setTextDetails(view);
setupFBLoginButton(view);
}
#Override
public void onResume()
{
super.onResume();
Profile profile = Profile.getCurrentProfile();
}
#Override
public void onStop()
{
super.onStop();
tTracker.stopTracking();
pTracker.stopTracking();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
fbCallbackManager.onActivityResult(requestCode, resultCode, data);
}
private void setupFBLoginButton(View view)
{
LoginButton loginButton = (LoginButton) view.findViewById(R.id.login_button);
loginButton.setReadPermissions("user_friends");
loginButton.setFragment(this);
loginButton.registerCallback(fbCallbackManager, fbCallback);
}
private void setTextDetails(View view)
{
mTextDetails = (TextView) view.findViewById(R.id.text_details);
}
private void setupTokenTracker()
{
tTracker= new AccessTokenTracker()
{
#Override
protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken newAccessToken)
{
//TODO
}
};
}
private void setupProfileTracker()
{
pTracker = new ProfileTracker()
{
#Override
protected void onCurrentProfileChanged(Profile oldProfile, Profile newProfile)
{
//TODO
}
};
}
}
I am trying to "call" this fragment from my main activity using the following code :
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity
{
private boolean logged = false;
private LoginFragment loginFragment;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
FragmentManager fManager = getFragmentManager();
FragmentTransaction fTransaction = fManager.beginTransaction();
LoginFragment loginFragment = new LoginFragment();
fTransaction.add(R.id.fragment_container, loginFragment, "fragment_container");
fTransaction.commit();
setContentView(R.layout.activity_main);
}
}
Yet, I have an error on the 2nd argument of this line fTransaction.add(R.id.fragment_container, loginFragment, "fragment_container");.
My IDE tells me it's expecting an android.app.Fragment object, and mine is a my.package.LoginFragment.
I don't get it, my LoginFragment extends Fragment...
I also tried to pass everything in android.support.v4.*, but then I can't do loginButton.setFragment(this);, and then I have no idea on how to set the Fragment to the loggin button.
Use getSupportFragmentManager() when working with support fragments instead of getFragmentManager().
Also, adding the fragment should happen after setContentView() so the fragment_container can be found.
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loginFragment = new LoginFragment();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, loginFragment, "fragment_container")
.commit();
}
After doing this you will have to fix a couple imports too. Make sure you use the following in MainActivity.
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

replace() doesn't work properly with multi-fragments

MainActivity
package example.antonio.activitydemo;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.support.v4.app.*;
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final FragmentManager fragmentManager = getSupportFragmentManager();
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FirstFragment fragment = new FirstFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container, fragment);
fragmentTransaction.commit();
}
});
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SecondFragment fragment = new SecondFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.commit();
}
});
}
}
FirstFragment
package example.antonio.activitydemo;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.View;
public class FirstFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInsanceState) {
return inflater.inflate(R.layout.first_fragment, container, false);
}
}
SecondFragment
package example.antonio.activitydemo;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.View;
public class SecondFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInsanceState) {
return inflater.inflate(R.layout.second_fragment, container, false);
}
}
Their XML files:
main_activity.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:id="#+id/container"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start1"
android:id="#+id/button"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start2"
android:id="#+id/button2"/>
</LinearLayout>
first_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="First!"
android:textColor="#ffffff"/>
</FrameLayout>
second_fragment.xml just like the previous one, only with android:text="Second!"
Here is the strange thing, when I click for 4 times the Start1 button then I get 4 times the word First!, until here all normal. Following if I click Start2 button what I would expect is the erase of the 4 previous fragments and the add of just a new one, with appearance of Second!. This is what I understood from the docs:
Replace an existing fragment that was added to a container. This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.
But here is what I get:
I tried to read the source code, maybe I found where is the "problem", I would like to know what you think and if it's me that I'm making a mistake somewhere.
Here is the snippet from BackStackRecord.java, run() method:
case OP_REPLACE: {
Fragment f = op.fragment;
int containerId = f.mContainerId;
if (mManager.mAdded != null) {
for (int i = 0; i < mManager.mAdded.size(); i++) {
Fragment old = mManager.mAdded.get(i);
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG,
"OP_REPLACE: adding=" + f + " old=" + old);
}
if (old.mContainerId == containerId) {
if (old == f) {
op.fragment = f = null;
} else {
if (op.removed == null) {
op.removed = new ArrayList<Fragment>();
}
op.removed.add(old);
old.mNextAnim = op.exitAnim;
if (mAddToBackStack) {
old.mBackStackNesting += 1;
if (FragmentManagerImpl.DEBUG) {
Log.v(TAG, "Bump nesting of "
+ old + " to " + old.mBackStackNesting);
}
}
mManager.removeFragment(old, mTransition, mTransitionStyle);
}
}
}
}
and here is the snippet from FragmentManager.java:
public void removeFragment(Fragment fragment, int transition, int transitionStyle) {
if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting);
final boolean inactive = !fragment.isInBackStack();
if (!fragment.mDetached || inactive) {
if (false) {
// Would be nice to catch a bad remove here, but we need
// time to test this to make sure we aren't crashes cases
// where it is not a problem.
if (!mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment not added: " + fragment);
}
}
**if (mAdded != null) {
mAdded.remove(fragment);
}**
if (fragment.mHasMenu && fragment.mMenuVisible) {
mNeedMenuInvalidate = true;
}
fragment.mAdded = false;
fragment.mRemoving = true;
moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED,
transition, transitionStyle, false);
}
}
As you can see, the removeFragment method removes a frament from mAdded but after in the run() method, the i index isn't modified, it restart from where it left, in such way it can lose some elements...
you cannot achieve this scenario with the linearlayout as a container.
If you try using the fragment as a container in linearlayout you can achieve this. please refer this link for further clarifications
Android - fragment .replace() doesn't replace content - puts it on top
Otherwise use the below code for button click actions,
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FirstFragment fragment = new FirstFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.container, fragment).addToBackStack(null);
fragmentTransaction.commit();
}
});
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SecondFragment fragment = new SecondFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
for(int i=0; i < getSupportFragmentManager().getBackStackEntryCount(); i++)
getSupportFragmentManager().popBackStack();
fragmentTransaction.replace(R.id.container, fragment);
fragmentTransaction.commit();
}
});
Hope this will help you.. Thanks

Categories