what do i use instead of findViewById in onCreateView using fragment - findviewbyid

I'm new to Android developing and of course on Fragments.
i have the code below and i want to use findViewById in fragment but because it's on onCreateView it has error
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_main,null);
x2=(Button)getView().findViewById (R.id.btnX2);
x2.setText(Html.fromHtml(getResources().getString(R.string.X2)));
showResult = (EditText)getView().findViewById(R.id.display);
}

You may try this.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.activity_main,container,false);
x2=(Button)v.findViewById (R.id.btnX2);
x2.setText(Html.fromHtml(getResources().getString(R.string.X2)));
showResult = (EditText)v.findViewById(R.id.display);
return v;
}

Try this it will be help you
View view=inflater.inflate(R.layout.activity_main,null);
x2=(Button)view.findViewById (R.id.btnX2);
x2.setText(Html.fromHtml(getResources().getString(R.string.X2)));
showResult = (EditText)view.findViewById(R.id.display);
return view;

Related

Xamarin.Android , OnBackPressed() method handling

I have main_activity and dashboard_activity, on dashboard_activity I added fragment using code in OnBackPressed() method
public override void OnBackPressed()
{
//base.OnBackPressed();
FragmentTransaction transaction =FragmentManager.BeginTransaction();
Dialog dialog = new Dialog();
dialog.Show(transaction,"dialog_fragment");
}
My fragment code is here
class Dialog:DialogFragment
{
private Button btnExitapp;
private Button btnLogOut;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
var view = inflater.Inflate(Resource.Layout.dialog, container,false);
btnExitapp=view.FindViewById<Button>(Resource.Id.btnExitapp);
btnExitapp.Click += BtnExitapp_Click;
btnLogOut = view.FindViewById<Button>(Resource.Id.btnLogOut);
btnLogOut.Click += BtnLogOut_Click;
return view;
}
private void BtnLogOut1_Click(object sender, EventArgs e)
{
}
private void BtnExitapp1_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
}
Note:My code for btnExitapp work fine only once after deployment and if I reopen the app in emulator and press btnExit it close app and reopen with Dashboard_Activity instead of closing app.
Please guide me to achieve
that when BtnLogout pressed, should go back to Main_Activity as it work on backpress button and when BtnExitapp pressed should close the app
At first, if you want to go back to the previous activity in your dialogframent, you can try to call the base.OnBackPressed(); in the private void BtnLogOut1_Click(object sender, EventArgs e). In addition, maybe you need to call it twice, from dialog to dashborad activity and then the main activity.
Then if you want to exit the app, you can use the following code:
private void BtnExitapp1_Click(object sender, EventArgs e)
{
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
}

show a login page before moving to main app in xamarin.android

so I'm trying to make an android app that starts with a login page (that I thought could be a dialog fragment) and if the user's credentials are correct, then he'll be directed to the main app that is supposed to be a navigation drawer app. I tried to use the dialog fragment but I didn't know how to set it to appear at the very beginning. what should I do?
You should create a Activity as a MainLauncher, Activity you can use a blank Layout.xml like following code, then pop a DialogFragment like following code. Note: you should add MainLauncher = true,NoHistory =true in your Activity attribute. NoHistory =true will make the back button navigate to the desktop.
namespace App2
{
[Activity(Label = "LoginActivity", Theme = "#style/AppTheme.NoActionBar",MainLauncher = true,NoHistory =true)]
public class LoginActivity : AppCompatActivity, OnLoginInforCompleted
{
public void inputLoginInforCompleted(string userName, string passWord)
{
//You can get the username and password here
StartActivity(new Intent(this,typeof(MainActivity)));
}
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.LoginLayout);
MyDialogFragment dialogFragment = new MyDialogFragment();
dialogFragment.setOnLoginInforCompleted(this);
dialogFragment.Cancelable = false;
var SupportFragmentManager = this.FragmentManager;
dialogFragment.Show(SupportFragmentManager, "dialog");
}
}
}
I achieve the a callback interface OnLoginInforCompleted, If User click the Login Button, will navigate to the navigation drawer page.
public interface OnLoginInforCompleted
{
void inputLoginInforCompleted(String userName, String passWord);
}
Here is code about MyDialogFragment .
public class MyDialogFragment : DialogFragment
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.layout3, container, false);
Button button = view.FindViewById<Button>(Resource.Id.button1);
EditText MyeditText1 = view.FindViewById<EditText>(Resource.Id.editText1);
EditText MyeditText2 = view.FindViewById<EditText>(Resource.Id.editText2);
button.Click += delegate {
//set the data to the loginpage
mOnLoginInforCompleted.inputLoginInforCompleted(MyeditText1.Text.ToString(), MyeditText2.Text.ToString());
Dismiss();
};
return view;
}
//set for Callback
private OnLoginInforCompleted mOnLoginInforCompleted;
public void setOnLoginInforCompleted(OnLoginInforCompleted onLoginInforCompleted)
{
mOnLoginInforCompleted = onLoginInforCompleted;
}
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
return base.OnCreateDialog(savedInstanceState);
}
}
Here is running GIF.
Here is my demo, you can refer to it.
https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/App2.zip

FragmentManager is already executing transactions when returning to view

I have a view that has a tablayout that activates a viewpager, when viewing the page it works fine, but if I click on an item on that view and then go back to the past screen I get:
Java.Lang.IllegalStateException: FragmentManager is already executing transactions
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
CurrentActivity = Activity;
var view = inflater.Inflate(Resource.Layout.fragment_directory, null);
_tabLayout = view.FindViewById<TabLayout>(Resource.Id.directory_tabs);
_viewPager = view.FindViewById<ViewPager>(Resource.Id.directory_pager);
SetTabLayout();
SetViewPager();
return view;
}
private void SetTabLayout()
{
var userTab = _tabLayout.NewTab();
userTab.SetText("Users");
var orgUnitsTab = _tabLayout.NewTab();
orgUnitsTab.SetText("Organizations");
_tabLayout.AddTab(userTab);
_tabLayout.AddTab(orgUnitsTab);
_tabLayout.TabGravity = TabLayout.GravityFill;
}
private void SetViewPager()
{
var pagerAdapter = new DirectoryPagerAdapter(FragmentManager, _tabLayout.TabCount);
_viewPager.Adapter = pagerAdapter;
_viewPager.AddOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(_tabLayout));
}
not sure if it makes a difference but when I leave this view I go from a fragment to an activity.
If you come across this question, I found a SO Answer that answered it well.
the highlight, I should have used ChildFragmentManager instead of FragmentManager.

How to bind Toolbar MenuItem.IsEnabled with MvvmCross and Xamarin.Android

Using MvvmCross and Xamarin.Android is it possible to bind the IsEnabled property of a Toolbar MenuItem to a boolean value in a viewmodel? If so, how is it done?
I believe it's impossible at this time to bind Android IMenuItem.IsEnabled to a boolean value on a viewmodel due to the fact that IsEnabled is readonly and changed the enabled state of a menu item requires a call to SetIsEnabled(bool).
I worked around this limitation by adding an event handler for MvxViewModel.PropertyChanged in the Activity/Fragment. All my viewmodels inherit from MvxViewModel so I'll share a way this can be accomplished. Most of my app is implemented with Fragments, so my example reflects that, (in my actual code I've put most of this in a base Fragment class, but I wanted to keep it simple):
public class MyViewModel : MvxViewModel
{
public bool MenuItemIsEnabled {
get{return _menuItemIsEnabled;}
set{SetProperty(ref _menuItemIsEnabled, value);
}
}
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
[Register(nameof(MyFragment))]
public class MyFragment : MvxFragment
{
private Toolbar Toolbar;
//menuitem whose enabled state should change with viewmodel property
private IMenuItem MyMenuItem;
public new MyViewModel ViewModel
{
get { return (MyViewModel)base.ViewModel; }
set { base.ViewModel = value; }
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = base.OnCreateView(inflater, container, savedInstanceState);
//we'll need the Toolbar later when we set up the IsEnabled "binding"
Toolbar = view.FindViewById<Toolbar>(Resource.Id.toolbar);
return view;
}
public override void OnViewModelSet()
{
base.OnViewModelSet();
ViewModel.PropertyChanged += ViewModel_PropertyChanged;
}
public override void OnCreateOptionsMenu(IMenu menu, MenuInflater inflater)
{
base.OnCreateOptionsMenu(menu, inflater);
//create the menu based on a menu resource
inflater.Inflate(Resource.Menu.my_menu, menu);
//save a reference to the menu item so we can update it when the viewmodel changes
MyMenuItem = menu.FindItem(Resource.Id.my_menu_item);
//set the initial enabled state based on the viewmodel
MyMenuItem.SetEnabled(ViewModel.MenuItemIsEnabled);
}
private void ViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
//when ViewModel.MenuItemIsEnabled is updated, update the menuitem enabled state as well
if (e.PropertyName == nameof(ViewModel.MenuItemIsEnabled ))
BinContentsMenuItem?.SetEnabled(ViewModel.MenuItemIsEnabled);
}
}
This should be considered pseudocode, since it's trying to demonstrate the general concepts I used to work around my original problem.

MvvmCross ViewModel transition from the left

I am developing an app for iOS using MvvmCross. On one of my Views I have some basic report data that is displayed in a tableview.
When the table row is touched a new view containing a detail report is displayed by making the call to ShowViewModel passing some parameters in a Dictionary. This works fine.
When the user swipes left or right the app needs to show the detail report for the next or previous item in the original list. I am doing this by updating some parameters and calling ShowViewModel again. The logic behind this is all working fine.
My problem; ShowViewModel animates the new view coming in from the right. This is perfect when the user has swiped left. However when swiping right it seems counter intuitive. How can I make ShowViewModel animate or transition in from the left side?
if you look to the MvvmCross source code here you see how the default behavior is showing the ViewControllers
You need to change that by doing something like the following:
How to change the Push and Pop animations in a navigation based app
for that, one idea is to have a custom view presenter and catch navigation to that particular view-model (override Show(IMvxTouchView view) )
or, maybe derive from UINavigationController, set it to MvvmCross to use it (look to the MvxSetup), and on some events change transition to that particular view
similar to this question
How to specify view transitions on iPhone
This is the solution I was able to come up with following the helpful pointers in the answer from Andrei N. In the end I opted for a TransitionFlipFromRight and TransitionFlipFromLeft when scrolling between detail reports. Hopefully it is useful to somebody else.
I already had a presenter class that was inherited from MvxModalSupportTouchViewPresenter
public class BedfordViewPresenter : MvxModalSupportTouchViewPresenter
Within this class I added a property of MvxPresentationHint.
private MvxPresentationHint _presentationHint;
In the override of method ChangePresentation the above property is used to store the passed in parameter
public override void ChangePresentation (MvxPresentationHint hint)
{
_presentationHint = hint;
base.ChangePresentation (hint);
}
Two new MvxPresentationHint class were declared (see later)
In the presenter class the Show method was overridden
public override void Show(IMvxTouchView view)
{
if (_presentationHint is FlipFromRightPresentationHint) {
var viewController = view as UIViewController;
MasterNavigationController.PushControllerWithTransition (viewController, UIViewAnimationOptions.TransitionFlipFromRight);
}
else
if (_presentationHint is FlipFromLeftPresentationHint) {
var viewController = view as UIViewController;
MasterNavigationController.PushControllerWithTransition (viewController, UIViewAnimationOptions.TransitionFlipFromLeft);
}
else {
base.Show (view);
}
_presentationHint = null;
}
A new class that provides extensions to a UINavigationController was created with the method PushControllerWithTransition
public static class UINavigationControllerExtensions
{
public static void PushControllerWithTransition(this UINavigationController
target, UIViewController controllerToPush,
UIViewAnimationOptions transition)
{
UIView.Transition(target.View, 0.75d, transition, delegate() {
target.PushViewController(controllerToPush, false);
}, null);
}
}
All that needs to be defined now are the two new MvxPresentationHint class derivations. These belong in your Core class library project rather than the iOS application project.
public class FlipFromLeftPresentationHint : MvxPresentationHint
{
public FlipFromLeftPresentationHint ()
{
}
}
and
public class FlipFromRightPresentationHint: MvxPresentationHint
{
public FlipFromRightPresentationHint ()
{
}
}
I hope this is a help to someone else trying to do something similar
Share my solution for android:
On view:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = base.OnCreateView(inflater, container, savedInstanceState);
var layout = view.FindViewById<LinearLayout>(Resource.Id.swippeable);
var swipeListener = new SwipeListener(this.Activity);
swipeListener.OnSwipeLeft += (sender, e) => this.ViewModel.LeftCommand?.Execute(); //Here use command into view model
swipeListener.OnSwipeRight += (sender, e) => this.ViewModel.RightCommand?.Execute();
layout.SetOnTouchListener(swipeListener);
return view;
}
Gesture listener:
public class SwipeListener : SimpleOnGestureListener, View.IOnTouchListener
{
private const int SWIPE_THRESHOLD = 100;
private const int SWIPE_VELOCITY_THRESHOLD = 100;
private readonly GestureDetector gestureDetector;
public SwipeListener(Context ctx)
{
this.gestureDetector = new GestureDetector(ctx, this);
}
public Boolean OnTouch(View v, MotionEvent e)
{
return this.gestureDetector.OnTouchEvent(e);
}
public event EventHandler OnSwipeRight;
public event EventHandler OnSwipeLeft;
public event EventHandler OnSwipeTop;
public event EventHandler OnSwipeBottom;
public override Boolean OnDown(MotionEvent e)
{
return true;
}
public override Boolean OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
Boolean result = false;
float diffY = e2.GetY() - e1.GetY();
float diffX = e2.GetX() - e1.GetX();
if (Math.Abs(diffX) > Math.Abs(diffY))
{
if (Math.Abs(diffX) > SWIPE_THRESHOLD && Math.Abs(velocityX) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffX > 0)
{
SwipeRight();
}
else
{
SwipeLeft();
}
result = true;
}
}
else if (Math.Abs(diffY) > SWIPE_THRESHOLD && Math.Abs(velocityY) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffY > 0)
{
SwipeBottom();
}
else
{
SwipeTop();
}
result = true;
}
return result;
}
public void SwipeRight()
{
this.OnSwipeRight?.Invoke(this, EventArgs.Empty);
}
public void SwipeLeft()
{
this.OnSwipeLeft?.Invoke(this, EventArgs.Empty);
}
public void SwipeTop()
{
this.OnSwipeTop?.Invoke(this, EventArgs.Empty);
}
public void SwipeBottom()
{
this.OnSwipeBottom?.Invoke(this, EventArgs.Empty);
}
}

Resources