I am having a hard time figuring out why my FragmentManager isn't working.
I'm using an Android studio template for nav drawer activity. The most confusing thing is, I have the exact same code in another app and it works just fine.
Here is the code:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
Fragment fragment = null;
switch (id) {
case R.id.nav_camera:
fragment = new MyFragment();
Log.i("ID", String.valueOf(id));
break;
case R.id.nav_gallery:
break;
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_main, fragment)
.commit();
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Now, when I click on the nav_camera it logs the click just fine, but nothing else happens, the fragment doesn't get replaced. No errors, no exceptions, just the same screen over and over.
Fragment code, nothing here just testing:
public class MyFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_list, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
Fragment layout, just a blank:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
The rest of the code is auto generated by andorid studio.
Here is content_main, which I am trying to replace with fm:
<LinearLayout 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"
android:id="#+id/content_main"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.goran.mymoviedb.movies.MainActivity"
tools:showIn="#layout/app_bar_main">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
It should replace the layout with a blank one whan nav_camera is clicked but nothing happens, even though correct click is registered.
Actually your code is working but the issue is that you have blank layout and because background of fragment layout is by default transparent you can not see the change. Put background color on your root layout of fragment (LinearLayout) for example: android:background="#android:color/white"
and you will see fragement replacement.
Related
Yesterday, I came across a problem that concerns "propably" fragments overlapping. I have a fragment (A) with RecyclerView & FloatingActionButton. There is onClickListener set to that FAB, which should replace the whole fragment (A) view with fragment (B). Unfortunately FAB somehow stays on top, but RecyclerView is exchanged with fragment (B) view. I'm almost sure that I'm replacing container with both RV & FAB. Maybe any ideas where should I look for solution?
Navigation code:
private void onNavigate(int container,Fragment fragment, boolean backStack, Integer animIn, Integer animOut){
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.addOnBackStackChangedListener(this);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(animIn,animOut,animIn,animOut);
fragmentTransaction.replace(container,fragment);
if(backStack){
fragmentTransaction.addToBackStack(fragment.toString());
}
fragmentTransaction.commit();
}
Fragment Replacing:
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState){
View view = inflater.inflate(R.layout.tab1_fragment, container, false);
recyclerView = (RecyclerView)view.findViewById(R.id.recyclerView_id);
FB_addTask = view.findViewById(R.id.fb_addTask_id);
recyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
FB_addTask.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getNavigationListener().onNagivate(R.id.tab1_content,new Tab1_AddTask_Fragment(),true,R.anim.anim_from_left_to_right,R.anim.anim_from_center_to_left);
}
});
return view;
}
and Layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/tab1_content"
android:background="#color/Grey_300"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_id"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fb_addTask_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_margin="25dp"
android:elevation="5dp"
android:src="#drawable/plus_dark_blue"
app:backgroundTint="#color/SC_Gold"/>
</RelativeLayout>
I want to call a fragment on button click which is a fragment. I tried this code but it's not working. with this code when I click on the button it shows next fragment but not its designing. I see only a blank page.
This is my main xml :-
<LinearLayout
android:id="#+id/main_layout"
android:orientation="vertical"
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=".MainActivity">
<!-- our toolbar -->
<!-- our tablayout to display tabs -->
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:tabGravity="fill"
android:background="#fa4022"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<!-- View pager to swipe views -->
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"/>
I have an dashboard tab in this TabLayout. In this dashboard tab i have an button which id is userprofile. after click on this button i want to go on user_profile.xml
public class Dashboard extends Fragment implements View.OnClickListener {
Button userprofile;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.dashboard, container, false);
userprofile=(Button)rootView.findViewById(R.id.userprofile);
userprofile.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View view) {
Fragment fragment = null;
switch (view.getId()) {
case R.id.userprofile:
fragment = new User_Profile();
replaceFragment(fragment);
break;
}
}
private void replaceFragment(Fragment fragment) {
User_Profile user_profile = new User_Profile();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.pager, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
User_Profile class code is :-
public class User_Profile extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rooView=inflater.inflate(R.layout.user_profile, container, false);
return rooView;
}
}
user_profile.xml is :-
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="User Profile"
android:textSize="30dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"/>
If you can see fragment on button click but not designing then its may error in your fragment .xml file. By using proper view problem can be solve. If there is also a problem with same post their .xml file code.
Can you show us some more data please? What's the XML for the pager fragment you're trying to replace the current fragment with?
Could you check that you're referring to the layout of that XML file, and not the individual pager element too?
(Since transaction.replace requires a fragment container as it's first argument)
Hi I used android studio wizard to create a drawer activity. Inside MainnActivity I have put this code:
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_movies) {
Fragment newDetail = ListFragment.newInstance(LAUNCH_MOVIES);
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, newDetail)
.commit();
} else if (id == R.id.nav_tv) {
Fragment newDetail = ListFragment.newInstance(LAUNCH_TV);
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, newDetail)
.commit();
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Since I have 2 options I need to launch the same fragment with different arguments, and based on the different arguments the fragment shows different things. But when I click on a navigation drawer item nothing appears on screen nor on the stacktrace.
ListFragment:
public static ListFragment newInstance(int target) {
Bundle args = new Bundle();
args.putInt(ARG_SCOPE, target);
ListFragment fragment = new ListFragment();
fragment.setArguments(args);
return fragment;
}
public ListFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
scope = getArguments().getInt(ARG_SCOPE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.content_main, container, false);
switch (scope){
case 1:
//launch Movies
((TextView)rootView.findViewById(R.id.textView)).setText("" + MainActivity.LAUNCH_MOVIES);
break;
case 2:
//Launch tv
((TextView)rootView.findViewById(R.id.textView)).setText("" + MainActivity.LAUNCH_TV);
break;
default:
Log.w(LOG_TAG, "INVALID SCOPE");
}
return rootView;
}
Thank you I am going crazy.
XML files:
activity_main
<android.support.v4.widget.DrawerLayout
...>
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
.../>
</android.support.v4.widget.DrawerLayout>
app_bar_main
<android.support.design.widget.CoordinatorLayout
...>
<android.support.design.widget.AppBarLayout
...>
<android.support.v7.widget.Toolbar
.../>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/container"/>
</android.support.design.widget.CoordinatorLayout>
content_main
<RelativeLayout
...>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"/>
</RelativeLayout>
Did you try Debuger? You can see code flow using break-points.
I think if you used the Android Studio debugger stepping through line by line you will likely find your problem. Everything seems fine to me but I can't see all the code or XML.
What does MainActivity.LAUNCH_TV and MainActivity.LAUNCH_MOVIES return? They may be returning nothing and leaving you with an empty text view and therefore it may seem like the buttons are not working.
Another problem could be that R.id.nav_movies and R.id.nav_tv are not right but I can't tell as all your XML is not included.
Set the debugger to break on the first line of onNavigationItemSelected and just step one line at a time, the problem should become easier to solve once you know where it is.
Sounds like your navigationView setNavigationItemSelectedListener is not being called. Have you set the listener to your navigationView?
navigationView.setNavigationItemSelectedListener(listener);
I tried your approach.The problem you are facing is replace fragment id.You should use Relativelayout id from content_main.xml file, while replacing the fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_main, fragment).commit();
Also remove Framelayout from app_bar_main.xml file.
I was able to get it working. Apparenly it was some bug in the way the xml files are organized. The java code was left as it was. Instead in app_bar_main, inside the coordinator layout I put a FrameLayout with id #+id/fragment_container. Also I removed the self-generated <Include content_main.xml> tag.
In the onNavigationItemSelected method I updated every .replace() to target the new FrameLayout like this: .replace(R.id.fragment_container, newDetail).
Then in the fragment's onCreateView i inflated a new layout like this: View rootView = inflater.inflate(R.layout.fragment_list, container, false);, where fragment_list is the layout where I have the recycerView and all of the UI stuff.
The content_main.xml went unused.
I believe the bug was somehow related to the <include> tag and the messy over-complicated way of adding a Drawer. 2/10 never using Drawer again.
I wanna open fragment from my activity. The problem is that the fragment never appears.
This is the part of my activity:
btn_opciones.setOnValueChangedListener(new ToggleButton.OnValueChangedListener() {
#Override
public void onValueChanged(int position) {
if(position == 1){
OrdenarComplejosFragment ordenarComplejosFragment = new OrdenarComplejosFragment();
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
ft.add(ordenarComplejosFragment, null);
ft.commit();
}
}
});
And this is my fragment that I wanna open and show:
public class OrdenarComplejosFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_ordenar_complejos, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//do your stuff for your fragment here
}
}
The xml of the fragment above:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="HOLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
android:id="#+id/textView35"
android:layout_gravity="center_horizontal" />
</LinearLayout>
I don't know why the fragment never show. The button works fine.
Try using a different "add" method. Using the one which takes in a view id indicates where the fragment should show up within the existing Activity's layout.
ft.add(R.id.fragment_frame, ordenarComplejosFragment);
Fragments are always housed within an Activity. If your activity doesn't provide a container/location for the fragment to show up, you'll need to re-think the layout or consider opening this new view with a separate Activity.
I am trying to add to the navigation drawer using fragments as follows using the onNavigationDrawerItemSelected But the compiler is giving me a incomparable type I do not no how I am new to Andriod I used the NaviagationDrwaer Template app to give me heads start.
I am hopeing someone can point me in the right direction with this been driving me nuts. Also any ideas with this apporach how one would handle icons in the menu ?.
public void onNavigationDrawerItemSelected(int position) {
Fragment fragment;
switch(position){
case 0:
fragment = new HomeFragment(); --- This line is where the error comes
break;
}
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager()
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
My HomeFragment Class Conists Of
public class HomeFragment extends Fragment {
View rootview;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.home_layout, container, false);
return rootview;
}
}
And my home_layout file as follows
<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="com.example.davidbuckley.cautioapp.home">
<!-- TODO: Update blank fragment layout -->
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</RelativeLayout>
One of your fragments is probably a 'support' Fragment: http://developer.android.com/reference/android/support/v4/app/Fragment.html
While the other is probably a native Fragment: http://developer.android.com/reference/android/app/Fragment.html