Fragments won't change on Android application - android

Respected programmers of stack overflow,
I am very new to the world of programming and am actually trying to build an app to help my fellow medical students.
In my app I can't seem to be able to change fragments after pressing buttons on the navigation bar. Only a single fragment loads at first (home fragment) and the rest do not change at all.
Since I am new to the programming world it may just be a small mistake on my part, but I do hope you all can guide me.
Here is my MainActivity java file
public class MainActivity extends AppCompatActivity {
BottomNavigationView bnView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bnView=findViewById(R.id.bnView);
bnView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id=item.getItemId();
if (id==R.id.home) {
loadfrag(new Homefragment(), true);
}else if(id==R.id.subject_based) {
loadfrag(new subjectfragment(), false);
}else if(id==R.id.about) {
loadfrag(new aboutfragment(), false);
}else if(id==R.id.exam) {
loadfrag(new examfragment(), false);
}else {
loadfrag(new paperfragment(), false);
}
return true;
}
});
bnView.setSelectedItemId(R.id.home);
}
public void loadfrag(Fragment fragment, boolean flag){
FragmentManager fm=getSupportFragmentManager();
FragmentTransaction ft= fm.beginTransaction();
if (flag)
ft.add(R.id.container,fragment);
else
ft.replace(R.id.container,fragment);
ft.commit();
}
}
My main activity xml file is as follows;
<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/goojasto"
tools:context="com.cringyprithak.mcqrunch_3.MainActivity">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bnView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#EFD115"
app:menu="#menu/nav_items" />
</RelativeLayout>
My menu is as follows
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/subject_based"
android:icon="#drawable/ic_sub"
android:title="Subject-wise"/>
<item
android:id="#+id/paper"
android:icon="#drawable/ic_paper"
android:title="Paper-wise"/>
<item
android:id="#+id/home"
android:icon="#drawable/ic_home"
android:title="Home"/>
<item
android:id="#+id/exam"
android:icon="#drawable/ic_exam"
android:title="Exam Practice"/>
<item
android:id="#+id/about"
android:icon="#drawable/ic_action_name"
android:title="About Me"/>
</menu>
and an example of the coding in my fragments would be
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class aboutfragment extends Fragment {
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view= inflater.inflate(R.layout.fragment_homefragment, container, false);
return view;
}
}
I have been trying all day to make a bottom navigation bar and have fragments switch according to the buttons in the navigation bar but I haven't been able to.
I've watched countless videos and tried anything I could find. Please help me.

Your code is fine in general. It is the proper way to switch between Fragment by using BottomNavigationBar.
Just a small change for following function. You can directly use replace() when switching between Fragment:
// Removed the boolean flag and use replace() directly
public void loadfrag(Fragment fragment) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
// Can remove the add() function and just use replace()
ft.replace(R.id.container, fragment);
ft.commit();
}
So I guess the problem you encounter is when you try to load the view to your Fragment.
For your aboutfragment, you are trying to load R.layout.fragment_homefragment. And from the naming seems that it is a HomeFragment layout rather than your aboutfragment layout. You should have a your aboutfragment layout there:
public class aboutfragment extends Fragment {
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Should replace R.layout.fragment_homefragment with your aboutfragment layout
view = inflater.inflate(R.layout.fragment_homefragment, container, false);
return view;
}
}
And for better practice, please follow Java Naming Convention when you are creating functions or classes.
For example:
Homefragment should be in HomeFragment
aboutfragment should be in AboutFragment

Related

My app stops unexpectedly when I switch to another fragment through bottom navigation

I have just started learning layouts and basic UI elements of Android Studio as well as how it organizes the files which are drawable, layouts, strings, activities etc.
So, I have managed to add a basic navigation widget to one activity that has 5 navigation items by following some youtube tutorial. The only navigation item that responds to a tap is the first one which is the dashboard. The rest returns an "Unfortunately the app has stopped" dialog.
Here's the code on my Activity.java
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
public class StudentActivity extends AppCompatActivity {
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_dashboard: //this works
AlertDialog.Builder builder1 = new AlertDialog.Builder(StudentActivity.this);
builder1.setMessage("Dashboard To.");
builder1.setCancelable(true);
builder1.show(); // I'm able to see the dialog here
setTitle("Dashboard");
DashboardFragment dashboard_fragment = new DashboardFragment();
FragmentTransaction transaction1 = getFragmentManager().beginTransaction();
transaction1.replace(R.id.frameLayout,dashboard_fragment);
return true;
case R.id.navigation_learn: //this doesn't work
try {
AlertDialog.Builder builder2 = new AlertDialog.Builder(StudentActivity.this);
builder2.setMessage("Learn To.");
builder2.setCancelable(true);
builder2.show(); //dialog doesn't even show up
setTitle("Learn");
DashboardFragment learn_fragment = new DashboardFragment();
FragmentTransaction manager1 = getFragmentManager().beginTransaction();
manager1.replace(R.id.frameLayout, learn_fragment);
manager1.commit();
}catch(Exception e){
AlertDialog.Builder errorDialog = new AlertDialog.Builder(StudentActivity.this);
errorDialog.setMessage(e.getMessage());
errorDialog.setCancelable(true);
errorDialog.show();
}
return true;
}
return false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_student);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
}
And below is how my navigation.xml looks like
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/navigation_dashboard"
android:icon="#drawable/ic_dashboard"
android:title="Dashboard" />
<item
android:id="#+id/navigation_learn"
android:icon="#drawable/ic_openbook2"
android:title="Learn" />
<item
android:id="#+id/navigation_play"
android:icon="#drawable/ic_game2"
android:title="Play" />
<item
android:id="#+id/navigation_review"
android:icon="#drawable/ic_shapes"
android:title="Review" />
<item
android:id="#+id/navigation_profile"
android:icon="#drawable/ic_user2"
android:title="My Profile" />
</menu>
I have verified that all drawable icons are present and are in lower case names.
I made sure that correct import of import android.app.FragmentTransaction; is included. I did some research and found that there is also an android.support.v4.app.FragmentTransaction which is not the correct one.
Build was successful and I'm able to launch the app using Nox emulator.There are no messages in Message Gradle Build window.
What could be the cause? Any suggestions on how to go about fixing this?
Thanks in advance.
EDIT:
Here's the error I get when I tap on the 2nd navigation item.
java.lang.IllegalArgumentException: No view found for id 0x7f0a004b (com.example.peace:id/frameLayout) for fragment LearnFragment{4bbf1c20 #1 id=0x7f0a004b}
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:882)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
at android.app.BackStackRecord.run(BackStackRecord.java:684)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)
Here's the LearnFragment.java
package com.example.peace.cai;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {#link Fragment} subclass.
*/
public class LearnFragment extends Fragment {
public LearnFragment() {
// 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_learn, container, false);
}
}
And here the fragment_learn.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.example.peace.cai.LearnFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>
You are using same fragment for both of the bottom menu buttons. You are calling same fragment from both bottomNav buttons only reference is changed.
Change DashboardFragment learn_fragment = new DashboardFragment(); here, DashboardFragment() to LearnFragment learn_fragment = new LearnFragment (); or what you have.
Below is your Code :
case R.id.navigation_dashboard: //this works
AlertDialog.Builder builder1 = new AlertDialog.Builder(StudentActivity.this);
builder1.setMessage("Dashboard To.");
builder1.setCancelable(true);
builder1.show(); // I'm able to see the dialog here
setTitle("Dashboard");
DashboardFragment dashboard_fragment = new DashboardFragment();
FragmentTransaction transaction1 = getFragmentManager().beginTransaction();
transaction1.replace(R.id.frameLayout,dashboard_fragment);
return true;
case R.id.navigation_learn: //this doesn't work
try {
AlertDialog.Builder builder2 = new AlertDialog.Builder(StudentActivity.this);
builder2.setMessage("Learn To.");
builder2.setCancelable(true);
builder2.show(); //dialog doesn't even show up
setTitle("Learn");
DashboardFragment learn_fragment = new DashboardFragment(); // Here need to change LearnFragment()
FragmentTransaction manager1 = getFragmentManager().beginTransaction();
manager1.replace(R.id.frameLayout, learn_fragment);
manager1.commit();
Change your fragment fragment_learn.xml to LinearLayout or RelativeLayout.
<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"
tools:context="com.example.peace.cai.LearnFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</LinearLayout >
In your Activity.java class, in the first case R.id.navigation_dashboard you are replacing whatever was in the container R.id.frameLayout with dashboard_fragment but you are not committing that transaction. In the second case R.id.navigation_learn you are replacing whatever was in the same container R.id.frameLayout with another fragment LearnFragment and doing the commit, so at this time in the same transaction you are trying to push two fragments into same layout and probably this is causing the crash. Fix the issue by committing the first transaction like you do for the second one. See the code below.
case R.id.navigation_dashboard: //this works
AlertDialog.Builder builder1 = new AlertDialog.Builder(StudentActivity.this);
builder1.setMessage("Dashboard To.");
builder1.setCancelable(true);
builder1.show(); // I'm able to see the dialog here
setTitle("Dashboard");
DashboardFragment dashboard_fragment = new DashboardFragment();
FragmentTransaction transaction1 = getFragmentManager().beginTransaction();
transaction1.replace(R.id.frameLayout,dashboard_fragment).commit();
return true;
case R.id.navigation_learn: //this doesn't work
try {
AlertDialog.Builder builder2 = new AlertDialog.Builder(StudentActivity.this);
builder2.setMessage("Learn To.");
builder2.setCancelable(true);
builder2.show(); //dialog doesn't even show up
setTitle("Learn");
LearnFragment learn_fragment = new LearnFragment ();
FragmentTransaction manager1 = getFragmentManager().beginTransaction();
manager1.replace(R.id.frameLayout, learn_fragment);
manager1.commit();
}catch(Exception e){
AlertDialog.Builder errorDialog = new AlertDialog.Builder(StudentActivity.this);
errorDialog.setMessage(e.getMessage());
errorDialog.setCancelable(true);
errorDialog.show();
}
return true;
Add below line in your fragment.
if(getActivity() != null && isAdded) {
//do your operation
}

Adding FragmentTabHost from inside a Fragment created by an activity with NavigationDrawer

What I have been Trying to Do
What I have been aiming to do for several days is, using an Activity that implements NavigationView.OnNavigationItemSelectedListener. I want this to create two Tabs inside a android.support.v4.app.Fragment in the FrameLayout provided by the template for the Navigation Drawer on Android Studio 1.5.1.
- My Current Activity uses a toolbar not an ActionBar.
- I was hoping to use a ViewPager; hence needing to use Support Fragments.
- I have followed several code examples online and have looked at Android Developers Reference.
Other Linked Posts:
Unable to add Tabs inside Fragment of Navigation Drawer Android | This uses Fragments and the ActionBar
Android TabHost inside Fragment | Chosen Answer -> using FragmentActivity | Unfortunatly uses a new FragmentActivity but I need to keep my NavigationDrawer so am using one activity
Android TabHost only inside one Fragment (NavigationDrawer) | This didnt really provide me much help as I am very new to using tabs
Android Adding Tab inside Fragment | Chosen Answer -> using FragmentTabHost | I have taken FragmentTabHost XML and Java code from this example but It has not worked
Tabs in a class that extends fragment | The andswer refers to googles documentation which is not working for me.
Adding Tab inside Fragment In Android? | Uses android.app.Fragment and the suggested answer didnt work.
Using TabLayout inside a Fragment; tab text invisible | I am using Design Library v23.1.1 | Bugs reported in v22.2.1. The code here gave me no tabs either
Any Suggestion would be appreciated.
MY CODE
NavActivity Class
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
public class NavigationMenuActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
Toolbar toolbar;
DrawerLayout drawerLayout;
ActionBarDrawerToggle toggle;
NavigationView navigationView;
FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.navmenu_act);
//Setting up the Toolbar
toolbar = (Toolbar) findViewById(R.id.navmenu_appbar_tbar);
setSupportActionBar(toolbar);
//Set up the action bar toggle
drawerLayout = (DrawerLayout) findViewById(R.id.navmenu_act_drawerlay);
toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.setDrawerListener(toggle);
toggle.syncState();
//Set up the navigation View
navigationView = (NavigationView) findViewById(R.id.navmenu_nav_view);
navigationView.setNavigationItemSelectedListener(this);
//SET THE FRAGMENT
fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentById(R.id.navmenu_appbar_fl);
if(fragment==null) { //If no fragment exists relate the fragment
fragment = new TabLayoutFragmentExample();
fragmentManager.beginTransaction()
.add(R.id.navmenu_appbar_fl, fragment)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit();
}
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.navmenu_act_drawerlay);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_profile) {
fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentById(R.id.navmenu_appbar_fl);
if(fragment!=null) { //If a fragment exists replace the fragment
fragment = new TestFragmentNoTabs();
fragmentManager.beginTransaction()
.replace(R.id.navmenu_appbar_fl, fragment)
.commit();
}
} else if (id == R.id.nav_near_me) {
// Handle the near me action here
} else if (id == R.id.nav_proximity) {
// Handle the proximity action
fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentById(R.id.navmenu_appbar_fl);
if(fragment!=null) {//If A fragment exists replace the fragment
fragment = new TestFragmentNoTabsTWO();
fragmentManager.beginTransaction()
.replace(R.id.navmenu_appbar_fl, fragment)
.commit();
}
}
//Close the drawerLayout after it is clicked?
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.navmenu_act_drawerlay);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
//sync the toggle
toggle.syncState();
}
}
navmenu_appbar.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".NavigationMenuActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/navmenu_appbar_tbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/JethrosTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/navmenu_appbar_fl"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</android.support.design.widget.CoordinatorLayout>
TablayoutFragmentExample Class
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
public class TabLayoutFragmentExample extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View inflatedView = inflater.inflate(R.layout.tab_layout_frag, container, false);
TabLayout tabLayout = (TabLayout) inflatedView.findViewById(R.id.tab_layout_frag_tl);
tabLayout.addTab(tabLayout.newTab().setText("Tab1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab2"));
final ViewPager viewPager = (ViewPager) inflatedView.findViewById(R.id.tab_layout_frag_vp);
viewPager.setAdapter(new PagerAdapter //ChildFragManager; Tnx #Luksprog
(getChildFragmentManager(), tabLayout.getTabCount()));
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setupWithViewPager(viewPager); //Set Viewpager; Tnx #Luksprog
return inflatedView;
}
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
TestFragmentNoTabs tab1 = new TestFragmentNoTabs();
return tab1;
case 1:
TestFragmentNoTabsTWO tab2 = new TestFragmentNoTabsTWO();
return tab2;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
}
tab_layout_frag.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout_frag_tl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/tab_layout_frag_vp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"/>
</android.support.design.widget.AppBarLayout>
TestFragmentNoTabs & TestFragmentNoTabsTWO (Fragment 1 and fragment 2)
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
public class TestFragmentNoTabs extends Fragment {
public final String TAG = "TestFragmentNoTabs";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Inflate the fragment view
View view = inflater.inflate(R.layout.testfragnotabs, container, false);
return view; //Return the view to the activity
}
#Override
public void onPause() {
super.onPause();
}
}
testfragnotabs.xml (similar to testfragnotabstwo.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/nearme_frag_rlay"
android:clickable="false">
<TextView
android:id="#+id/nearme_frag_tv_seclab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" TestFragmentNoTabsOne -> testfragnotabs.xml" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/textView1"
android:layout_above="#+id/nearme_frag_tv_seclab" />
</RelativeLayout>
Current Situation with Above Code
The project builds fine and the navigation drawer is working fine as well. However the frame layout where the fragment and the TabLayout should appear is empty with a white background (Just like the Design preview in tab_layout_frag.xml; this could mean there is a problem with the ViewPager or the TabLayout?).

Android: trying to add a fragment to the backstack ("Blank activity" project)

I have just created a new "Blank activity" project. And now I would like to add a fragment to the backstack when pressing the button that the "Blank activity" shows. The problem: the applicaction closes unexpectedly when pressing the button.
Steps I have followed to create a fragment from an activity
Steps I have followed to add a fragment to the backstack
These are the only codes I added to the Blank Activity project:
//MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
context = this;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ExampleFragment ef = new ExampleFragment();
/////// This line closes the application /////////
getFragmentManager().beginTransaction()
.add(65, ef) //65 is random number
// Add this transaction to the back stack
.addToBackStack(null)
.commit();
setContentView(R.layout.news_articles);
}
});
}
This is the layout of the fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<fragment android:name="com.example.tirengarfio.myapplication.ExampleFragment"
android:id="#+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
ExampleFragment.java
package com.example.tirengarfio.myapplication;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ExampleFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
First understand difference between
1. Adding a fragment statically vs
2. Adding a fragment dynamically.
This tutorial will help you http://www.vogella.com/tutorials/AndroidFragments/article.html
( check section 5.1 and section 5.2 in the tutorial )
Also you are doing
getFragmentManager().beginTransaction()
.add(65, ef) //65 is random number
// Add this transaction to the back stack
.addToBackStack(null)
.commit();
verify the .add(65, ef) part. You cannot add a random int 65 it has to be resource id for the container view where you want do dynamically add a fragment.

Android ActionBarSherlock tabbed action bar with a mapview

I have 4 views, two of which contain mapviews. What I really want in the end is a tabbed navigation between these 4 views.
After some research, it seams like the best idea would be to use ActionBarSherlock and make each one of these views a "Fragment" inside a master "Main" Activity. This seams like a very easy to do thing but is causing me massive amounts of trouble (indeed, seams to be a pain for everyone from what I can find online).
First, my code.
ActivityMain.java
public class ActivityMain extends SherlockFragmentActivity
{
static String CLASS_NAME = "ActivityMain";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
Log.v(CLASS_NAME, "here");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.createMenu();
}
public void createMenu()
{
this.getSupportActionBar().setDisplayShowHomeEnabled(false);
this.getSupportActionBar().setDisplayShowTitleEnabled(false);
this.getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
Tab tab1 = getSupportActionBar()
.newTab()
.setText("First tab")
.setTabListener(new MyTabListener<FragmentOne>(this, FragmentOne.class));
getSupportActionBar().addTab(tab1);
Tab tab2 = getSupportActionBar()
.newTab()
.setText("Second tab")
.setTabListener(new MyTabListener<FragmentTwo>(this, FragmentTwo.class));
getSupportActionBar().addTab(tab2);
}
public class MyTabListener<T extends Fragment> implements TabListener
{
private ActivityMain mActivity;
private Fragment mFragment;
private Class<T> mClass;
public MyTabListener(ActivityMain activity, Class<T> fragmentClass)
{
mActivity = activity;
mClass = fragmentClass;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
{
if (mFragment == null)
{
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.add(android.R.id.content, mFragment, null);
}
else
{
//ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.animationtest);
ft.attach(mFragment);
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft)
{
if (mFragment != null)
{
ft.detach(mFragment);
}
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft)
{
}
}
}
FragmentOne loads just fine, no problems on that one. FragmentTwo is where the trouble begins. Here is the files:
FragmentTwo.java
package com.test;
import com.actionbarsherlock.app.SherlockFragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentTwo extends SherlockFragment
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.v("Test", "Two!");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.two, container, false);
return view;
}
}
and the corresponding layout looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.google.android.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapMapView"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="0.40"
android:clickable="true"
android:apiKey="MY_KEY"
/>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="#android:style/ButtonBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/refreshButton"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:onClick="refreshSightings"
android:text="#string/A_MAP_REFRESH_BUTTON" />
</LinearLayout>
</LinearLayout>
Now of course this is giving me the error Binary XML file line #7: Error inflating class com.google.android.maps.MapView
I have tried importing the https://github.com/petedoyle/android-support-v4-googlemaps package and replacing the already existing android-support-v4 package but when I try to run my app, it dies with the error that it can't find the ActivityMain class.
First question, am I even going about this in the right way? Should I be using this 1 main activity and loading all the other things in Fragments?
Next, if I am doing this in a correct way, is there a good tutorial for how to get this to work in a decent way? I can't find anything online except for other people asking the same questions and a few tutorials that haven't worked for me.
Basically, how can I have tabbed navigation with 2 maps in 2 different tabs?

Android Fragments make duplicate TextView on orientation change

I am trying to make a very simple App, but there's an error I can't get rid of it. Maybe someone can help me.
I'm making an Activity with an ActionBar and 3 Tabs. Beneath the Tabs is a FrameLayout, where I put Fragments with a TextView in it. So when clicking on a tab the content of the TextView shoud change.
This works fine until I change the orientation. After the change there is a duplicate TextView and I have no idea where it cames from. Here's a picture for better understanding:
Overlapping TextViews
Here's my Activity:
package com.test;
import android.app.ActionBar;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.app.ActionBar.Tab;
import android.os.Bundle;
import android.widget.Toast;
public class ProblemActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
String tab1 = "First Tab";
bar.addTab(bar
.newTab()
.setText(tab1)
.setTabListener(
new TabListener(new First())));
String tab2 = "Second Tab";
bar.addTab(bar
.newTab()
.setText(tab2)
.setTabListener(
new TabListener(new Second())));
String tab3 = "Third Tab";
bar.addTab(bar
.newTab()
.setText(tab3)
.setTabListener(
new TabListener(new Third())));
}
private class TabListener implements ActionBar.TabListener {
private MyFragment mFragment;
public TabListener(MyFragment fragment) {
this.mFragment = fragment;
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add(R.id.fragment_content, mFragment, null);
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(mFragment);
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(ProblemActivity.this, "Reselected!", Toast.LENGTH_SHORT)
.show();
}
}
}
The Fragment's:
public class First extends MyFragment {
public First() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View fragView = inflater.inflate(R.layout.tab1, container, false);
TextView tv = (TextView) fragView.findViewById(R.id.textView1);
tv.setText("First Tab");
return fragView;
}
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
and the content of the Fragment's.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="TextView"
android:textSize="35dp" />
</LinearLayout>
It would be amazing if some could show me what I'm making wrong.
Thank's in advance!
Edit: I tried already this proposed solution but I would like to work with class Objects, so that I can use their Methods.
Edit2: Solved the problem now. It was sufficient to add android:configChanges="keyboardHidden|orientation|screenSize" to my Activity.
Since the OP already solved his problem, but hasn't been active on SO for almost a year, here is an answer containing the solution:
Adding the following to the Activity solved the problem:
android:configChanges="keyboardHidden|orientation|screenSize"
You can get overlapping views if there is something wrong with one of your layouts. This seems to happen in particular if you have a fragment. For example, a View in the Fragment can overlap a View in the containing layout.
Sometimes this can be fixed by Cleaning your project (if you are using Eclipse).

Categories

Resources