in my navigation drawer there are 5 menu items.one of them is about us item.when I click on this item, I call AboutUsFragment and show it(its content is just a text).but when I click onBackPress, fragment is gone but its texts remains on my activity.how can I solve this problem?what`s it related to?!
select item of navigation drawer in my activity:
public void selectItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
if (!Constants.login_state) {
fragment = new LoginFragment();
} else {
Logout();
}
break;
case 1:
Constants.filter = false;
Constants.gender = "-1";
fragment = new HomeFragment();
break;
case 2:
Constants.filter = false;
Constants.gender = "2";
StyleFragment.SortingMode = 1;
fragment = new StyleFragment();
break;
case 3:
Constants.filter = false;
Constants.gender = "1";
StyleFragment.SortingMode = 1;
fragment = new StyleFragment();
break;
case 4:
fragment = new AboutUsFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentTransaction fragmentManager = getSupportFragmentManager().beginTransaction();
fragmentManager.replace(R.id.rl_container, fragment);
fragmentManager.addToBackStack(null);
fragmentManager.commit();
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(mNavigationDrawerItemTitles[position]);
mDrawerLayout.closeDrawer(Gravity.END);
} else {
Log.e("HomeActivity", "Error in creating fragment");
}
}
and AboutUsFragment:
public class AboutUsFragment extends android.support.v4.app.Fragment{
private View view;
private TextView about_us_fragment_text_view;
public static AboutUsFragment newInstance() {
AboutUsFragment fragment = new AboutUsFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view=inflater.inflate(R.layout.fragment_about_us, container, false);
Casting(view);
about_us_fragment_text_view.setText(getResources().getString(R.string.about_us));
ChangeUIFont.ChangeFont((ViewGroup) view, getContext());
return view;
}
//casting parameters
public void Casting(View v){
about_us_fragment_text_view= (TextView) v.findViewById(R.id.about_us_fragment_text_view);
}}
onBackPress in my activity:
#Override
public void onBackPressed() {
if (SearchOpened) {
lv_searchResult.setVisibility(View.GONE);
SearchOpened = false;
} else
super.onBackPressed();
}
---------------------------------------AfterSearching-------------------------------------------
Finally I found the solution!
in my fragment I added below code:
public static final String FRAGMENT_NAME = AboutUsFragment.class.getName();
and in my activity,I set the tag of fragment when I call it,instead of null!
fragmentManager.replace(R.id.rl_container, fragment,fragmentName);
used this method instead of onBackPressed
if you have toolbar then here is my solution,
type under the oncreate method below toolbar,
assert getSupportActionBar() != null;
// getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
and set this code in your manifest file for your fragment
<activity android:name=".yourCurrentFragment">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".whichActivityYouWantToGo" />
</activity>
Try this:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
} else {
getFragmentManager().popBackStack();
}
Related
I will try to explain at best, adding references and images in which
I think it is difficult to explain in words the error I encountered.
Working with the fragments and the Navigation Drawer I've faced this
bug:
From time to time, when I open the navigation menu, the previous
fragment is duplicated or loaded again. This thing is completely
random, without a precise scheme. The only thing that seems
connected is the RecyclerView and the Navigation Drawer.
Just because I do not know where I'm wrong, write in the comments if you
need something, code or other information and from time to time I'll add it
to the original question.
I am not receiving any errors and to help both me and you add some code and
images of how that fragment is loaded without bugs:
#Override
public boolean onNavigationItemSelected(MenuItem item) {
Fragment fragment = null;
Class aclass = null;
Bundle args = new Bundle();
Intent intentOperatore = getIntent();
String mParamOperatore = intentOperatore.getStringExtra(ARG_PARAM_OPERATORE);
boolean navigation = Boolean.FALSE;
boolean intent = Boolean.FALSE;
boolean scan = Boolean.FALSE;
boolean exit = Boolean.FALSE;
try{
switch (item.getItemId()){
case R.id.nav_home:
aclass = HomeFragment.class;
fragment = (Fragment) aclass.newInstance();
args.putString(ARG_PARAM_OPERATORE,mParamOperatore);
fragment.setArguments(args);
navigation = Boolean.TRUE;
break;
case R.id.nav_procedura_immobiliare:
aclass = FiltroFragment.class;
fragment = (Fragment) aclass.newInstance();
args.putString(ARG_CHECK_CLASS,"immobiliari");
fragment.setArguments(args);
navigation = Boolean.TRUE;
break;
case R.id.nav_procedura_mobiliare:
aclass = FiltroFragment.class;
fragment = (Fragment) aclass.newInstance();
args.putString(ARG_CHECK_CLASS,"mobiliari");
fragment.setArguments(args);
navigation = Boolean.TRUE;
break;
case R.id.nav_localizza_procedura:
aclass = LocalizzaActivity.class;
intent = Boolean.TRUE;
break;
case R.id.nav_ricognizione:
aclass = RicognizioneFragment.class;
fragment = (Fragment) aclass.newInstance();
args.putString(ARG_PARAM_RICOGNIZIONE,""); //TODO: Add param here.
fragment.setArguments(args);
navigation = Boolean.TRUE;
break;
case R.id.nav_qrcode:
scan = Boolean.TRUE;
break;
case R.id.nav_exit:
exit = Boolean.TRUE;
break;
}
if(navigation) { // Navigazione per i fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
} if(intent) { // Navigazione per le activity
Intent myIntent = new Intent(getApplicationContext(),aclass);
myIntent.putExtra(ARG_PARAM_OPERATORE,mParamOperatore);
startActivity(myIntent);
finish();
} if(scan) {
new MVBarcodeScanner.Builder()
.setScanningMode(MVBarcodeScanner.ScanningMode.SINGLE_AUTO)
.setFormats(Barcode.QR_CODE)
.build()
.launchScanner(MainActivity.this,REQ_CODE);
} if(exit) { // Navigazione per l'uscita
MaterialDialog dialog = new MaterialDialog.Builder(this)
.title(R.string.title_exit)
.content(R.string.summary_exit)
.positiveText(R.string.action_exit)
.onPositive(new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(MaterialDialog dialog, DialogAction which) {
finish();
}
})
.negativeText(R.string.action_no)
.show();
}
} catch (Exception e) {
Log.e(this.getClass().getName(), e.getMessage(), e);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Edit:
I also notice another thing that recycling is not the only thing to
duplicate. There is also the toolbar item that is duplicated:
Edit 2:
- I've added the onCreateOptionsMenu and some code that i run in the
onCreateView:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
//inflater.inflate(R.menu.procedura_menu_action, menu);
inflater.inflate(R.menu.procedura_menu_list, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_procedure_list, container, false);
Context context = view.getContext();
setHasOptionsMenu(true);
recyclerView = (RecyclerView) view.findViewById(R.id.rvProcedure);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
mAdapter = new ProcedureAdapter(context,procedure,this);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new DividerItemDecoration(context,LinearLayoutManager.VERTICAL));
recyclerView.setAdapter(mAdapter);
actionModeCallback = new ActionModeCallback();
Toolbar toolbar = view.findViewById(R.id.toolbar);
toolbar.setTitle(getString(R.string.title_lista_procedure) + " " + mCheckClass);
toolbar.setNavigationIcon(R.drawable.ic_menu_navigator);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener( new View.OnClickListener() {
public void onClick(View v) {
DrawerLayout drawerLayout = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
if(drawerLayout.isDrawerOpen(GravityCompat.START)){
drawerLayout.closeDrawer(GravityCompat.START);
} else {
drawerLayout.openDrawer(GravityCompat.START);
}
}
});
floatingActionButton = (FloatingActionButton) view.findViewById(R.id.fab_new);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
args.putString(ARG_PARAM_TIPOLOGIA,mParamTipologia); //Passa la procedura selezionata se siamo in modifica
args.putString(ARG_PARAM_PROCEDURA,new Gson().toJson(procedure.get(lastPosition)));
if(actionMode != null) //Leva la selezione se è presente, prima di passare ad un'altro fragment.
enableActionMode(lastPosition);
try {
if ((getActivity()) != null) {
FragmentManager fragmentManager = ((AppCompatActivity)getActivity()).getSupportFragmentManager();
Class fragmentClass = ProceduraFragment.class;
Fragment fragment = (Fragment) fragmentClass.newInstance();
fragment.setArguments(args);
fragmentManager.beginTransaction().replace(R.id.flContent, fragment).addToBackStack(null).commit();
}
} catch (java.lang.InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
});
//TODO: Implements here the load logic for procedure.
if(mParamProcedura != null && !(procedure.size() > 0)) {
procedure.add(mParamProcedura);
} else if(!(procedure.size() > 0)) {
refreshList(AlphaMAS.getData());
}
return view;
}
Why create a new fragment instance everytime? Try something like this:
if (fragment == null)
fragment = (Fragment) aclass.newInstance();
Inside your layout in both Fragments use this :
android:clickable="true"
android:focusable="true"
Solution
Set background to both of your xml file's parent layout.
android:background="#color/background_color_which_you_want"
Edit 1:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.procedura_menu_list, menu);
return super.onCreateOptionsMenu(menu);
}
I'm using HashMap of fragment's backstack. To save backstack and current fragment I use the code below:
public class MainActivity extends AppCompatActivity {
private HashMap<String, Stack<Fragment>> mStacks;
public static final String TAB_PROFILE = "tab_profile";
public static final String TAB_DASHBOARD = "tab_dashboard";
public static final String TAB_CHATS = "tab_chats";
public static final String TAB_SETTINGS = "tab_settings";
private String mCurrentTab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupViews();
if (savedInstanceState != null) {
mCurrentTab = savedInstanceState.getString("currentTab");
mStacks = (HashMap<String, Stack<Fragment>>) savedInstanceState.getSerializable("stacks");
} else
selectedTab(TAB_DASHBOARD);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("stacks", mStacks);
outState.putString("currentTab", mCurrentTab);
}
private void setupViews() {
mStacks = new HashMap<>();
mStacks.put(TAB_PROFILE, new Stack<>());
mStacks.put(TAB_DASHBOARD, new Stack<>());
mStacks.put(TAB_CHATS, new Stack<>());
mStacks.put(TAB_SETTINGS, new Stack<>());
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
bottomNavigationView.setSelectedItemId(R.id.action_dashboard);
BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(item -> {
switch (item.getItemId()) {
case R.id.action_profile:
selectedTab(TAB_PROFILE);
return true;
case R.id.action_dashboard:
selectedTab(TAB_DASHBOARD);
return true;
case R.id.action_chats:
selectedTab(TAB_CHATS);
return true;
case R.id.action_settings:
selectedTab(TAB_SETTINGS);
return true;
}
return true;
});
bottomNavigationView.setOnNavigationItemReselectedListener(item -> {
if (mStacks.get(mCurrentTab).size() != 1) {
mStacks.get(mCurrentTab).clear();
switch (item.getItemId()) {
case R.id.action_profile:
selectedTab(TAB_PROFILE);
break;
case R.id.action_dashboard:
selectedTab(TAB_DASHBOARD);
break;
case R.id.action_chats:
selectedTab(TAB_CHATS);
break;
case R.id.action_settings:
selectedTab(TAB_SETTINGS);
break;
}
}
});
}
private void selectedTab(String tabId) {
mCurrentTab = tabId;
if(mStacks.get(tabId).size() == 0){
if(tabId.equals(TAB_PROFILE)){
Fragment fragment = new ProfileFragment();
Bundle args = new Bundle();
args.putSerializable("user", Globals.getCurrentUser());
fragment.setArguments(args);
pushFragments(tabId, fragment,true);
} else if(tabId.equals(TAB_DASHBOARD)){
pushFragments(tabId, new DashboardFragment(),true);
}else if(tabId.equals(TAB_CHATS)){
pushFragments(tabId, new GroupsFragment(),true);
}else if(tabId.equals(TAB_SETTINGS)){
pushFragments(tabId, new SettingsFragment(),true);
}
}else {
pushFragments(tabId, mStacks.get(tabId).lastElement(),false);
}
}
public void pushFragments(String tag, Fragment fragment, boolean shouldAdd){
if(shouldAdd)
mStacks.get(tag).push(fragment);
FragmentManager manager = getFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content, fragment);
ft.commit();
}
public void popFragments(){
Fragment fragment = mStacks.get(mCurrentTab).elementAt(mStacks.get(mCurrentTab).size() - 2);
mStacks.get(mCurrentTab).pop();
FragmentManager manager = getFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content, fragment);
ft.commit();
}
#Override
public void onBackPressed() {
if(mStacks.get(mCurrentTab).size() == 1){
finish();
return;
}
popFragments();
}
}
Set new fragments using
((MainActivity)context).pushFragments(MainActivity.TAB_CHATS, fragment,true);
Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:background="#color/background_material_light"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/bottom_navigation"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="#color/waPrimary"
app:itemIconTint="#color/white"
app:itemTextColor="#color/white"
app:menu="#menu/menu_bottom_navigation" />
Everything works fine on screen rotation, but application crashes with exception on application hide.
java.lang.RuntimeException: Parcel: unable to marshal value %FragmentName%{c985244 #2 id=0x7f090051}
As I read, it happens when one of the objects I'm trying to pass is not Parceable, but have no idea how to fix this. Any thoughts?
UPD
After I made all of my fragments Serializable, new exception throws
java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = %FragmentName%)
...
Caused by: java.io.NotSerializableException: android.support.v7.widget.RecyclerView
UPD2
Seems like a found a solution - transient property. Now I'm trying to make all non-serializeable objects transient.
UPD3
It helped, but I don't know is it efficient enough.
Here's my suggestion:
Your activity maintains a reference to the four fragments it wants for the bottom navigation toggling.
On toggling bottom navigation, you replace the current fragment in the activity fragment manager.
While on a given fragment, as you interact with the UI, you push things on to the fragment child fragment manager.
This way, each fragment maintains its own backstack automatically, you don't have to save any state, and it all Just Works™.
Some sample code that might help.
public class MainActivity extends AppCompatActivity {
private Fragment mProfileFragment;
private Fragment mDashboardFragment;
private Fragment mChatsFragment;
private Fragment mSettingsFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
// Init fragments
}
else {
// Find last active fragments in fragment manager
}
setupViews();
}
private void setupViews() {
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
bottomNavigationView.setSelectedItemId(R.id.action_dashboard);
BottomNavigationViewHelper.removeShiftMode(bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(item -> {
Fragment fragment;
switch (item.getItemId()) {
case R.id.action_profile:
fragment = mProfileFragment;
break;
case R.id.action_dashboard:
fragment = mDashboardFragment;
break;
case R.id.action_chats:
fragment = mChatsFragment;
break;
case R.id.action_settings:
fragment = mSettingsFragment;
break;
}
// Replace the currently active fragment which will be
// managing its own backstack
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frament_container, fragment)
.commit();
});
}
}
And one of your fragments would push stuff on its own stack like this:
public class ProfileFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.id.fragment_layout, container, false);
Button button = view.findViewById(R.id.some_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment someFragmentToPush = new SomeFragmentToPush();
// Use the child fragment manager to keep UI
// local to this fragment instance, adding to backstack
// for automatic popping on pressing back
getChildFragmentManager().beginTransaction()
.add(R.id.fragment_layout, someFragmentToPush)
.addToBackStack(null)
.commit();
}
});
return view;
}
}
Hope that helps!
So my problem is that the buttons that are contained within my fragments throw up an error "Unhandled Exception - Object reference not set to an instance of an object"
I thought because I had referenced the layout that contains the button that this would not cause an error. If anyone could shed some light to what I am doing wrong that would be great. I think I am either missing some vital code or have completely messed it up as I am new to using fragments and understand that they work differently from activities.
This is my MainActivity:
public class MainActivity : ActionBarActivity
{
private SupportToolbar mToolbar;
private MyActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private ListView mLeftDrawer;
private HomeFragment mHomeFragment;
private LogInFragment mLogInFragment;
private MatchCentreFragment mMatchCentreFragment;
private PrevCompFragment mPrevCompFragment;
private PrevFixFragment mPrevFixFragment;
private SettingsFragment mSettingsFragment;
private SocialFragment mSocialFragment;
private UpcomCompFragment mUpcomCompFragment;
private UpcomFixFragment mUpcomFixFragment;
private SupportFragment mCurrentFragment = new SupportFragment();
private Stack<SupportFragment> mStackFragments;
private ArrayAdapter mLeftAdapter;
private List<string> mLeftDataItems;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
mToolbar = FindViewById<SupportToolbar>(Resource.Id.toolbar);
mDrawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
mLeftDrawer = FindViewById<ListView>(Resource.Id.left_drawer);
mHomeFragment = new HomeFragment();
mLogInFragment = new LogInFragment();
mMatchCentreFragment = new MatchCentreFragment();
mPrevCompFragment = new PrevCompFragment();
mPrevFixFragment = new PrevFixFragment();
mSettingsFragment = new SettingsFragment();
mSocialFragment = new SocialFragment();
mUpcomCompFragment = new UpcomCompFragment();
mUpcomFixFragment = new UpcomFixFragment();
mStackFragments = new Stack<SupportFragment>();
mLeftDrawer.Tag = 0;
SetSupportActionBar(mToolbar);
mLeftDataItems = new List<string>();
mLeftDataItems.Add("Home");
mLeftDataItems.Add("Log In");
mLeftDataItems.Add("Match Centre");
mLeftDataItems.Add("Previous Fixtures");
mLeftDataItems.Add("Upcoming Fixtures");
mLeftDataItems.Add("Previous Competitions");
mLeftDataItems.Add("Upcoming Competitions");
mLeftDataItems.Add("Settings");
mLeftDataItems.Add("Social");
mLeftAdapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, mLeftDataItems);
mLeftDrawer.Adapter = mLeftAdapter;
mLeftDrawer.ItemClick += MenuListView_ItemClick;
mDrawerToggle = new MyActionBarDrawerToggle(this, mDrawerLayout, Resource.String.openDrawer, Resource.String.closeDrawer);
if (bundle != null)
{
if (bundle.GetString("DrawerState") == "Opened")
{
SupportActionBar.SetTitle(Resource.String.openDrawer);
}
else
{
SupportActionBar.SetTitle(Resource.String.closeDrawer);
}
}
else
{
SupportActionBar.SetTitle(Resource.String.closeDrawer);
}
Android.Support.V4.App.FragmentTransaction trans = SupportFragmentManager.BeginTransaction();
trans.Add(Resource.Id.fragmentContainer, mHomeFragment);
trans.Add(Resource.Id.fragmentContainer, mLogInFragment);
trans.Hide(mLogInFragment);
trans.Add(Resource.Id.fragmentContainer, mMatchCentreFragment);
trans.Hide(mMatchCentreFragment);
trans.Add(Resource.Id.fragmentContainer, mPrevFixFragment);
trans.Hide(mPrevFixFragment);
trans.Add(Resource.Id.fragmentContainer, mUpcomFixFragment);
trans.Hide(mUpcomFixFragment);
trans.Add(Resource.Id.fragmentContainer, mPrevCompFragment);
trans.Hide(mPrevCompFragment);
trans.Add(Resource.Id.fragmentContainer, mUpcomCompFragment);
trans.Hide(mUpcomCompFragment);
trans.Add(Resource.Id.fragmentContainer, mSettingsFragment);
trans.Hide(mSettingsFragment);
trans.Add(Resource.Id.fragmentContainer, mSocialFragment);
trans.Hide(mSocialFragment);
mCurrentFragment = mHomeFragment;
trans.Commit();
}
void MenuListView_ItemClick (object sender, AdapterView.ItemClickEventArgs e)
{
Android.Support.V4.App.Fragment fragment = null;
switch (e.Id)
{
case 0:
ShowFragment(mHomeFragment);
break;
case 1:
ShowFragment(mLogInFragment);
break;
case 2:
ShowFragment(mMatchCentreFragment);
break;
case 3:
ShowFragment(mPrevFixFragment);
break;
case 4:
ShowFragment(mUpcomFixFragment);
break;
case 5:
ShowFragment(mPrevCompFragment);
break;
case 6:
ShowFragment(mUpcomCompFragment);
break;
case 7:
ShowFragment(mSettingsFragment);
break;
case 8:
ShowFragment(mSocialFragment);
break;
}
mDrawerLayout.CloseDrawers();
mDrawerToggle.SyncState();
}
private void ShowFragment (SupportFragment fragment)
{
if (fragment.IsVisible)
{
return;
}
var trans = SupportFragmentManager.BeginTransaction();
fragment.View.BringToFront();
mCurrentFragment.View.BringToFront();
trans.Hide(mCurrentFragment);
trans.Show(fragment);
trans.AddToBackStack(null);
mStackFragments.Push(mCurrentFragment);
trans.Commit();
mCurrentFragment = fragment;
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Android.Resource.Id.Home:
//The hamburger icon was clicked which means the drawer toggle will handle the event
mDrawerToggle.OnOptionsItemSelected(item);
return true;
case Resource.Id.action_refresh:
//Refresh
return true;
case Resource.Id.action_help:
return true;
default:
return base.OnOptionsItemSelected(item);
}
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.drawer_menu, menu);
return base.OnCreateOptionsMenu(menu);
}
protected override void OnSaveInstanceState(Bundle outState)
{
if(mDrawerLayout.IsDrawerOpen((int)GravityFlags.Left))
{
outState.PutString("DrawerState", "Opened");
}
else
{
outState.PutString("DrawerState", "Closed");
}
base.OnSaveInstanceState(outState);
}
protected override void OnPostCreate(Bundle savedInstanceState)
{
base.OnPostCreate(savedInstanceState);
mDrawerToggle.SyncState();
}
public override void OnConfigurationChanged(Android.Content.Res.Configuration newConfig)
{
base.OnConfigurationChanged(newConfig);
mDrawerToggle.OnConfigurationChanged(newConfig);
}
}
}
This is one of my fragments (there are several but they all contain basically the same code so far)
public class PrevFixFragment : Android.Support.V4.App.Fragment
{
Button button;
public PrevFixFragment()
{
}
public static Android.Support.V4.App.Fragment newInstance(Context context)
{
PrevFixFragment fragment = new PrevFixFragment();
return fragment;
}
public override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.PreviousFixtures, null);
button = View.FindViewById<Button>(Resource.Id.upcombutton);
button.Click += StartNewActivity;
return view;
}
void StartNewActivity(object sender, EventArgs e)
{
Intent intent = new Intent(Activity, typeof(UpcomFixActivity));
StartActivity(intent);
}
}
}
Try moving the following lines to override void OnViewCreated or override void onActivityCreated
button = View.FindViewById<Button>(Resource.Id.upcombutton);
button.Click += StartNewActivity;
You must write View with lowercase view in statement below:
button = View.FindViewById<Button>(Resource.Id.upcombutton);
I have a Navigation Drawer (so I use Fragments):
MainActivity (FragmentActivity)
Fragment A (Fragment with pictures links for Fragment B, C & D)
Fragment B (Fragment)
Fragment C (Fragment)
Fragment D (Fragment)
My navigation drawer works correctely, but I want to my Fragment A to do links like the menu. Right now, in Fragment A, I call the other Fragments like this:
ImageView contact = (ImageView) getView().findViewById(R.id.secondBlock);
contact.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Fragment fragment = new ContactezNous();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.accueil, fragment);
fragmentTransaction.commit();
}
});
But I don't want to use this way, because I have problems finding tags and ids of other Fragments.
I want to know how to change Fragments frome Fragment A by clicking on the link like if I was clicking on the Navigation Drawer links of the Main Activity.
Main Activity:
public class MainActivity extends AppCompatActivity implements FragmentDrawer.FragmentDrawerListener {
private static String TAG = MainActivity.class.getSimpleName();
private Toolbar mToolbar;
private FragmentDrawer drawerFragment;
//Initialisation de l activite avec les donnees necessaires
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
drawerFragment = (FragmentDrawer) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), mToolbar);
drawerFragment.setDrawerListener(this);
// Affichage de la navigation
displayView(0);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//Ajout des items
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onDrawerItemSelected(View view, int position) {
displayView(position);
}
private void displayView(int position) {
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (position) {
case 0:
fragment = new Accueil();
title = getString(R.string.title_accueil);
break;
case 1:
fragment = new NosOffres();
title = getString(R.string.title_nosoffres);
break;
case 2:
fragment = new DemandeGratuite();
title = getString(R.string.title_demandegratuite);
break;
case 3:
fragment = new ContactezNous();
title = getString(R.string.title_contact);
break;
case 4:
fragment = new Actualites();
title = getString(R.string.title_actu);
break;
case 5:
fragment = new MentionsLegales();
title = getString(R.string.title_mentions);
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
//fragmentTransaction.addToBackStack("name");
fragmentTransaction.commit();
// libelle du toolbar
TextView titlet;
titlet = (TextView) findViewById(R.id.main_toolbar_title);
titlet.setText(title);
titlet.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/GothamBook.ttf"));
}
}
}
You should use the following common Android fragment pattern:
public class Accueil extends Fragment {
// Your code here...
public interface OnFragmentInteractionListener {
void onInteraction(int id);
}
private OnFragmentInteractionListener mListener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
// ...more code...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// ...initialize your View...
ImageView contact = (ImageView) getView().findViewById(R.id.secondBlock);
contact.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// This is how you use the listener
mListener.onInteraction(3);
}
});
// ...more initialization...
}
}
MainActivity.java
public class MainActivity AppCompatActivity
implements FragmentDrawer.FragmentDrawerListener, OnFragmentInteractionListener {
// Your code here...
// Implement OnFragmentInteractionListener
#Override
public void onInteraction(int id) {
// 'id' would be '3' for your 'ContactezNous' fragment
displayView(id);
}
}
I'm using NavigationDrawer with some fragments, the problem is when I'm in a fragment and hit the back button, it makes the app close, then I have to open it again, put my username and password all over again to use the app, how can I prevent that from happen?
public class NavigationMain extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//...
}
public void setFragmentList(int posicao) {
Fragment fragment = null;
switch (posicao) {
case 0:
fragment = new MainFragment();
break;
case 1:
fragment = new MensagensFragment();
break;
case 2:
fragment = new EscolasFragment();
break;
case 3:
fragment = new AutorizadasFragment();
break;
case 4:
fragment = new CadastroFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer
navigationAdapter.resetarCheck();
navigationAdapter.setChecked(posicao, true);
layoutDrawer.closeDrawer(linearDrawer);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
}
#Override
public void onBackPressed() {
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
//additional code
} else {
getFragmentManager().popBackStack();
}
}
I think you missed to add the fragment transaction in your back stack. Try the following:
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).addToBackStack(null).commit();