Click event in Fragment for MVVMCROSS - android

I have a fragment class, like this one:
public class TMSAccountFragment : MvxFragment
{
//some code
}
Button click event:
#region OnClick of account button
ImageView acc_Button = view.FindViewById<ImageView>(Resource.Id.accountbutton_orange);
acc_Button.Click += delegate
{
OnClick();
};
#endregion
public void OnClick()
{
FragmentTransaction ft;
Fragment frag;
frag = new TMSSlidingTabsFragment();
ft = FragmentManager.BeginTransaction();
ft.Replace(Resource.Id.sample_content_fragment, frag);
ft.AddToBackStack(null);
ft.Commit();
}
The following error happens in FragmentManager.BeingTransaction();.
cannot implicitly convert type 'android.support.v4.App.FragmentTransaction' to 'Android.App.FragmentTransaction'

use getSupportFragmentManager() instead getFragmentManager().you should change your onclick like as below
public void OnClick()
{
Fragment frag = null;
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
frag = new TMSSlidingTabsFragment();
fragmentTransaction .Replace(Resource.Id.sample_content_fragment, frag);
fragmentTransaction .AddToBackStack(null);
fragmentTransaction .Commit();
}

You need to use SupportFragmentManager instead of the regular FragmentManager.
public void OnClick()
{
var fragment = new TMSSlidingTabsFragment();
var transaction = SupportFragmentManager.BeginTransaction();
transaction.Replace(Resource.Id.sample_content_fragment, frag);
transaction.AddToBackStack(null);
transaction.Commit();
}
However, since you're using MVVMCross, I strongly advise you to use the MVVM Pattern. That is, bind this Click event to an IMvxCommand in your VM and use a proper presenter to handle the way your Fragments will be presented (some useful resources to get started can be found here and here)

Related

How to replace fragment by checking userinfo list

Currently I am in settingsfragment and i have another Fragment called ProfileFragment. Now the problem is, by userinfo list i need to replace fragmnet like. If userinfo==null i should be in settingFragment or i should be in ProfileFragment.
if(userinfolist == null ){
//login screen
FragmentTransaction ft= getFragmentManager().beginTransaction();
ft.replace(R.id.main_frame,settingsFragment);
ft.commit();
}else{
//setting screen
FragmentTransaction ft=getFragmentManager().beginTransaction();
ft.replace(R.id.main_frame,profileFragment);
ft.commit();
}
But when I execute the code I am getting stuck.
if your userinfo list is arraylist then used below code and also make sure your both fragment are define ..
then used below code like ..
List<User> userinfolist = new ArrayList<>();
SettingsFragment settingsFragment = new SettingsFragment();
ProfileFragment profileFragment = new ProfileFragment();
if (userinfolist.isEmpty()) {
//login screen
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.main_frame, settingsFragment);
ft.commit();
} else {
//setting screen
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.main_frame, profileFragment);
ft.commit();
}
You can typecast the layout in which the fragment is getting pushed and then clear the views of the layout using layout.removeAllViews();,and then do the rest for attaching a fragment,but by default you need to attach something i guess
You can create a common method to replace fragments which will be more efficient like below method
public void replaceFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.main_frame, fragment);
}
Depending upon your condition, you can call fragment. In your case if userinfolist is a List then you can use below code.
if(userinfolist!=null&&userinfolist.size()>0)
replaceFragment(new profileFragment(), false);
else
replaceFragment(new SettingFragment(),false);
Try using below code piece, as initializing FragmentManager & FragmentTransaction once is sufficient.
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
List<User> userinfolist = new ArrayList<>();
if (userinfolist == null) {
SettingsFragment settingsFragment = new SettingsFragment();
fragmentTransaction.replace(R.id.main_frame,settingsFragment);
} else {
ProfileFragment profileFragment = new ProfileFragment();
fragmentTransaction.replace(R.id.main_frame,profileFragment);
}
fragmentTransaction.commit();

invoke fragment from a fragment

by pressing a button inside the main fragment, I wanna call the second fragment in that place
public void onViewClicked(View view) {
Fragment frag = null;
switch (view.getId()) {
case R.id.btn_login:
frag = new LoginFragment();
break;
case R.id.btn_offline:
frag = new OfflineFragment();
break;
}
MainActivity mainActivity = new MainActivity();
FragmentManager manager =
mainActivity.getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment, frag);
transaction.commit();
}
Never create an Activity instance . Its a Component and managed by system itself(Intent). Use getActivity() to get the Context of Activity.
FragmentManager manager =
getActivity().getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment, frag);
transaction.commit();
You should take a look at Android Application Fundamentals.
I would suggest to go with getChildFragmentManager(); of the fragment to get the fragment manager to perform all your fragment related operations instead of getting it from using the fragmentManager from the getActivity() method. It help you a lot on reloading the fragment on resume of it again at later point of time.

Android Fragment Back Stack

I have used multiple Fragments in my Project. I want to save a Fragment's state and restore this state when I come back to this. In this Fragment I show multiple images which change on button click. I use the following code for this:
String backStateName = fragment.getClass().getName();
FragmentManager fragmentManager = getSupportFragmentManager();
boolean fragmentPopped = fragmentManager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.addToBackStack(backStateName);
fragmentTransaction.commit();
}
It works fine & it saves state, but it does not show previous image's.
Any help, suggestion or tutorials would be highly appreciated. Thank you.
I am trying with the fragment list ....
Initilize the framents list
static List<String> fragments = new ArrayList<String>();
Code to fragment change and take in back stack
String backStateName = fragment.getClass().getName();
FragmentManager manager = getSupportFragmentManager();
//fragment not in back stack, create it.
FragmentTransaction ft = manager.beginTransaction();
if(!fragments.contains(backStateName)) {
// ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
// ft.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
ft.replace(R.id.frame, fragment);
ft.addToBackStack(backStateName);
ft.commit();
fragments.add(backStateName);
System.out.println("backStateName" + fragments);
}
else
{
ft.replace(R.id.frame, fragment);
ft.commit();
}
onBackpressed
#Override
public void onBackPressed() {
if(fragments.size()>0)
{
fragments.remove(fragments.size()-1);
}
super.onBackPressed();
}
for back remove stack
final android.app.FragmentManager fm = getFragmentManager();
fm.addOnBackStackChangedListener(new android.app.FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
if (getSupportFragmentManager().getBackStackEntryCount() ==0) {
// dLayout.closeDrawers();
finish();
}
else
{
// dLayout.closeDrawers();
}
}
});
You can use the following code.
It will not reload the fragment when you come back from previous fragment:
if (!fragmentPopped) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.hide(getFragmentManager().findFragmentById(R.id.container_body));
fragmentTransaction.add(R.id.container_body, fragment);
fragmentTransaction.addToBackStack(backStateName);
fragmentTransaction.commit();
}
You can use
fragmentTransaction.hide(getFragmentManager().findFragmentById(R.id.frame_container));
fragmentTransaction.add(R.id.frame_container, fragment);
fragmentTransaction.addToBackStack(null);
Instead of
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.addToBackStack(backStateName);
If you can save the images in the android disk cache when you open the fragment and display the images by reading from the disk cache it might resolve your problem. Follow the below link from google on how to save images in disk cache.
https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
Below are the steps i think you should follow.
Store your images in the disk cache.
onAttaching your ImagesFragment to the Activity read the images from the disk cache and show them
when the fragment is popped from the backstack your code will automatically read the images from the disk cache.
Hope this helps.
I used multiple fragments with this code.Put this code in your MainActivity where's your framelayout or fragment.
#Override
public void onBackPressed() {
/* Fragment fragment = new SettingActivity();
String title = getString(R.string.app_name);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.commit();
// set the toolbar title
getSupportActionBar().setTitle(title);*/
//Log.e("title:", getTitle().toString());
getSupportActionBar().setTitle("Home");
//Log.e("title:", getTitle().toString());
if (!getTitle().toString().equals("Home")) {
Fragment fragment = new Activity_category();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container_body, fragment).commit();
this.setTitle("Home");
} else {
super.onBackPressed();
}
}
May this will help you.
You taking your fragment in back stack so its didn't fault of your fragment you need to check in your image library. May i know which library are you using. I recommended to use picasso library. I am also using this and getting state saved image in my fragment.
http://square.github.io/picasso/
You can do circular navigation by using below code. You can visit even two fragments as vice-versa by endless.
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
hideLastFragment(fragmentTransaction);
fragmentTransaction.add(R.id.profile_fragmentContainer, youfFragment, fragmentTagName).addToBackStack(fragmentTagName);
fragmentTransaction.commitAllowingStateLoss();
/**
* To hide the last fragment
*
* #param fragmentTransaction FragmentTransaction
*/
public void hideLastFragment(FragmentTransaction fragmentTransaction) {
final int backStackCount = getSupportFragmentManager().getBackStackEntryCount() - 1;
if (backStackCount >= 0) {
String fragmentName = getSupportFragmentManager().getBackStackEntryAt(backStackCount).getName();
Fragment lastFragment = getSupportFragmentManager().findFragmentByTag(fragmentName);
fragmentTransaction.hide(lastFragment);
}
}

Redirect the fragment when click on button

I am using this code for replacing the fragment but there is a problem, it's not replacing the old fragment it just override on old fragment so please tell me what is the problem here.
public void selectFrag1(View rootView) {
Fragment frag;
if (rootView == findViewById(R.id.startup1)) {
frag = new S_SignupFragment();
} else {
frag = new F_SignupFragment();
}
FragmentManager fragManager = getSupportFragmentManager();
FragmentTransaction fragTransaction = fragManager.beginTransaction();
fragTransaction.replace(R.id.fragment_signup,frag);
fragTransaction.commit();
}
Are you sure that you pass the parent view, that is going to hold your fragment on the line fragTransaction.replace(R.id.fragment_signup,frag); ?
For fragmentTransaction.replace(...,...) you need to specify a container for your fragment and the fragment itself. Check where does your R.id.fragment_signup directs. More information you could find in this SO question: Unable to replace fragment on button click
fr = new FragmentOne();
fm = getSupportFragmentManager();
fragmentTransaction = fm.beginTransaction();
fragmentTransaction.add(R.id.fragment_place,fr);
fragmentTransaction.commit();
if you use same code then add this before call first button setonclicklistner

Trying to remove a fragment from the screen Android

I'm within an activity and I launch a fragment from there, and it appears on the screen fine, but I want to use the button to then remove the same fragment. I can't see what's wrong with the code, I know it's going in to the code that should remove it because the toast says "remove fragment". Any ideas? Thanks
public class ButtonClickHandler implements View.OnClickListener {
public void onClick(View view) {
if (showFrag == true){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MyFragment myFragment = new MyFragment();
fragmentTransaction.add(R.id.myfragment, myFragment);
fragmentTransaction.commit();
showFrag = false;
Toast.makeText(getBaseContext(), "Show Fragment", Toast.LENGTH_SHORT).show();
}
else if (showFrag == false){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
getSupportFragmentManager().popBackStack();
fragmentTransaction.commit();
Toast.makeText(getBaseContext(), "Remove Fragment", Toast.LENGTH_SHORT).show();
showFrag = true;
}
}
}
To pop a fragment of backstack you need to add it to backstack first.
You can do that by calling fragmentTransaction.addToBackStack(null) after you call fragmentTransaction.add(R.id.myfragment, myFragment);
Also including #coelho 's comment - You dont have to start a FragmentTransaction to call popBackStack().
You're not calling addToBackStack before :)
fragmentTransaction.add(R.id.myfragment, myFragment);
fragmentTransaction.addToBackStack(null);
The the remove should simply be:
getSupportFragmentManager().popBackStack();
No need to create a local variable and no need to create a transaction.

Categories

Resources