I am trying to create a tabbed Swipe navigation system in my xamarin android I am facing The name 'SupportFragmentManager' does not exist in the current context, error I have no idea how to clear this I am new to xamarin android please help me
MainActivity.cs
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.GalleryPage);
// Create your application here
txtView = FindViewById<TextView>(Resource.Id.txtView);
_imageView = FindViewById<ImageView>(Resource.Id.imageView1);
Button button = FindViewById<Button>(Resource.Id.MyButton);
TabLayout tabLayout = (TabLayout)FindViewById(Resource.Id.tablayout_navigation);
ViewPager viewPager = (ViewPager)FindViewById(Resource.Id.pager);
SetupviewPager(viewPager);
tabLayout.SetupWithViewPager(viewPager);
button.Click += delegate
{
Intent = new Intent();
Intent.SetType("image/*");
Intent.SetAction(Intent.ActionGetContent);
StartActivityForResult(Intent.CreateChooser(Intent, "Select Picture"), PickImageId);
};
}
private void SetupviewPager(ViewPager viewPager)
{
viewPager.OffscreenPageLimit = 3;
var adapter = new PageAdapter1(SupportFragmentManager);
adapter.AddFragment(new Fragment1(), "Title1");
adapter.AddFragment(new Fragment2(), "Title2");
adapter.AddFragment(new Fragment3(), "Title3");
viewPager.Adapter = adapter;
}
PageAdapter1.cs
using System.Collections.Generic;
using Android.Support.V4.App;
using Java.Lang;
using Fragment = Android.Support.V4.App.Fragment;
using FragmentManager = Android.Support.V4.App.FragmentManager;
namespace OCR_Pro
{
public class PageAdapter1: FragmentPagerAdapter
{
private readonly List<Fragment> _fragments;
private readonly List<string> _fragmentnames;
public PageAdapter1(FragmentManager fm) : base(fm)
{
_fragments = new List<Fragment>();
_fragmentnames = new List<string>();
}
public override int Count
{
get { return _fragments.Count; }
}
public override Fragment GetItem(int position)
{
return _fragments[position];
}
public void AddFragment(Fragment fragment, string name)
{
if (fragment == null) return;
_fragments.Add(fragment);
_fragmentnames.Add(name);
}
public override ICharSequence GetPageTitleFormatted(int position)
{
return new Java.Lang.String(_fragmentnames[position]);
}
}
}
Fragment1.cs
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
namespace OCR_Pro
{
public class Fragment1 : Android.Support.V4.App.Fragment
{
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
// return inflater.Inflate(Resource.Layout.YourFragment, container, false);
var v = inflater.Inflate(Resource.Layout.Fragment1, container, false);
return v;
}
}
}
Errror : The name 'SupportFragmentManager' does not exist in the current context
It looks like you are trying to pass in the class SupportFragmentManagerinstead of an instance of the class. Try instantiating an instance of SupportFragmentManager and then passing it in.
Please check if installing Xamarin.Android.Support.v4 by nuget package. SupportFragmentManager type is Android.Support.V4.App.FragmentManager.
If you want to get sample, please take a look:
https://learn.microsoft.com/en-us/xamarin/android/user-interface/controls/view-pager/viewpager-and-fragments
Related
I have an activity en I start the frist fragment from that activity:
var fragment1 = new Fragment1();
var fragmentManager = SupportFragmentManager;
var ft = fragmentManager.BeginTransaction()
.SetCustomAnimations(Resource.Animation.abc_fade_in, Resource.Animation.abc_fade_out)
.AddToBackStack(nameof(Fragment1))
.Add(Resource.Id.content_frame, fragment1)
.Commit();
In Fragment1 I have a listview and I'm using an adapter to populate the list view. At first time load it works perfectly. I start Fragment2 from Fragment1 in with this code:
var fragment2 = new Fragment2();
var fragmentManager = SupportFragmentManager;
var ft = fragmentManager.BeginTransaction()
.SetCustomAnimations(Resource.Animation.abc_fade_in, Resource.Animation.abc_fade_out)
.AddToBackStack(nameof(Fragment2))
.Add(Resource.Id.content_frame, fragment2)
.Commit();
But when I navigate from Fragment1 to Fragment2 and call PopBackStack from Fragment2 to go back to Fragment1, the list view is totally blanc.
Here is my Fragment1 code:
public class Fragment1 : Fragment
{
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override void OnViewCreated(View view, Bundle savedInstanceState)
{
base.OnViewCreated(view, savedInstanceState);
SetUpListView(view);
}
public void RefreshListView(List<Item> items)
{
if (View == null) return;
var listView = View.FindViewById<ListView>(Resource.Id.lv_items);
var adapter = listView.Adapter as ItemsListViewAdapter;
adapter.Items = items;
adapter.NotifyDataSetChanged();
}
private void SetUpListView(View view)
{
var adapter = new ItemsListViewAdapter(Activity);
var listView = view.FindViewById<ListView>(Resource.Id.lv_items);
listView.Adapter = adapter;
listView.ItemClick += ListView_ItemClick;
}
private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
var fragment2 = new Fragment2();
var fragmentManager = Activity.SupportFragmentManager;
var ft = fragmentManager.BeginTransaction();
ft.Replace(Resource.Id.content_frame, fragment2);
ft.AddToBackStack(null);
ft.Commit();
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
return inflater.Inflate(Resource.Layout.items, container, false);
}
}
Here is my Fragment 2:
public class Fragment2 : Fragment
{
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override void OnCreateOptionsMenu(IMenu menu, MenuInflater inflater)
{
inflater.Inflate(Resource.Menu.shipments_search_menu, menu);
var searchItem = menu.FindItem(Resource.Id.action_search);
var searchView = (SearchView)searchItem.ActionView;
var expandListener = new OnActionExpandListener();
expandListener.Collapse += (s, e) =>
{
Activity.SupportFragmentManager.PopBackStack();//here I must go back to Fragment1
};
searchItem.SetOnActionExpandListener(expandListener);
searchView.QueryTextChange += SearchView_QueryTextChange;
base.OnCreateOptionsMenu(menu, inflater);
}
private void SearchView_QueryTextChange(object sender, SearchView.QueryTextChangeEventArgs e)
{
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
HasOptionsMenu = true;
return inflater.Inflate(Resource.Layout.search_shipments, container, false);
}
}
Am i missing something? Any help would be apreciated.
I'm trying to display only a small part of a webpage in Xamarin Android Webkit WebView. I've seen a lot of answers how to do this in android studio but I've not seen many recent answers for how to do it in xamarin for android. What method would you recommend for this task? I could also settle for loading a WebView and then scrolling down to a certain section of a page.
Here's the code I'm using to generate tab and WebView
//Discover new content
[Activity]
//define class discover content
public class SessionsActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.discover);
//declare webview and tell our code where to find the XAML resource
WebView discoverWebView = FindViewById<WebView>(Resource.Id.webViewDiscover);
//set the webview client
discoverWebView.SetWebViewClient(new WebViewClient());
//load the subscription url
discoverWebView.LoadUrl("https://www.bitchute.com/");
//enable javascript in our webview
discoverWebView.Settings.JavaScriptEnabled = true;
//zoom control on? This should perhaps be disabled for consistency?
//we will leave it on for now
discoverWebView.Settings.BuiltInZoomControls = true;
discoverWebView.Settings.SetSupportZoom(true);
//scrollbarsdisabled
// subWebView.ScrollBarStyle = ScrollbarStyles.OutsideOverlay;
discoverWebView.ScrollbarFadingEnabled = false;
}
}
thanks, in advance! =]
if you look at the Xamarin docs for WebView, you'll see that it has a LoadURL method with the same signature as the Java method. The only difference is the casing of the method - Xamarin usually uses C# casing, but otherwise the method names are the same, and the argument you pass will also be identical
discoverWebView.LoadUrl("javascript:(function() { " +
"document.getElementsByTagName('header'[0].style.display="none"; " +
"})()");
Here's how I did it, #Jason was helpful but a more complete answer is as follows, this loads duckduckgo.com then hides the content_homepage, scroll to mid-bottom:
using Android.Graphics.Drawables;
using Android.OS;
using Android.Support.V4.App;
using Android.Views;
using Android.Webkit;
using Android.Widget;
namespace BottomNavigationViewPager.Fragments
{
public class TheFragment1 : Fragment
{
string _title;
string _icon;
protected static WebView _wv;
public static TheFragment1 NewInstance(string title, string icon) {
var fragment = new TheFragment1();
fragment.Arguments = new Bundle();
fragment.Arguments.PutString("title", title);
fragment.Arguments.PutString("icon", icon);
return fragment;
}
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
if (Arguments != null)
{
if(Arguments.ContainsKey("title"))
_title = (string)Arguments.Get("title");
if (Arguments.ContainsKey("icon"))
_icon = (string)Arguments.Get("icon");
}
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.TheFragmentLayout1, container, false);
_wv = view.FindViewById<WebView>(Resource.Id.webView1);
var _wvc = new MyWebViewClient();
_wv.SetWebViewClient(_wvc);
//string _wtf = "header";
_wv.Settings.JavaScriptEnabled = true;
_wv.Settings.AllowFileAccess = true;
_wv.Settings.AllowContentAccess = true;
//_wvc.OnPageFinished(_wv, _jsHideBannerC);
_wv.LoadUrl("https://www.duckduckgo.com/");
return view;
}
private class MyWebViewClient : WebViewClient
{
public override void OnPageStarted(WebView view, string url, Android.Graphics.Bitmap favicon)
{
base.OnPageStarted(view, url, favicon);
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
string _jsHideBanner = "javascript:(function() { " +
"document.getElementById('content_homepage').style.display='none'; " + "})()";
string _jsHideBannerC = "javascript:(function() { " +
"document.getElementsByClassName('logo-wrap--home').style.display='none'; " + "})()";
_wv.LoadUrl(_jsHideBanner);
}
}
}
}
ConnectivityManager connMgr = (ConnectivityManager)this.Activity.GetSystemService(Android.Content.Context.ConnectivityService);
NetworkInfo networkInfo = connMgr.ActiveNetworkInfo;
bool isConnected = networkInfo.IsConnected;
this code is in the onCreateView method in my fragment and when i run the app i get the error:
Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object. occurred
it would be great if someone would explain to me what "not set to an instance of an object means" as i dont quite understand. still a little new to xamarin and c# in general.
heres the fragament1.cs file:
using Android.OS;
using Android.Support.V4.App;
using Android.Views;
using Android.Webkit;
namespace TabsApp.Fragments
{
public class Fragment1 : Fragment
{
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public static Fragment1 NewInstance()
{
var frag1 = new Fragment1 { Arguments = new Bundle() };
return frag1;
}
WebView webView;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignored = base.OnCreateView(inflater, container, savedInstanceState);
View v = inflater.Inflate(Resource.Layout.fragment1, container, false);
webView = v.FindViewById<WebView>(Resource.Id.webView);
webView.LoadUrl("https://google.com");
webView.Settings.JavaScriptEnabled = true;
webView.SetWebViewClient(new WebViewClient());
return v;
}
public void OnBackPressed()
{
webView.GoBack();
}
}
}
and heres the MainActivity.cs file:
using Android.App;
using Android.OS;
using TabsApp.Fragments;
using Android.Content.PM;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
namespace TabsApp
{
[Activity(Label = "#string/app_name", MainLauncher = true, LaunchMode = Android.Content.PM.LaunchMode.SingleTop, Icon = "#drawable/icon",
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : AppCompatActivity
{
BottomNavigationView bottomNavigation;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.main);
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
if (toolbar != null)
{
SetSupportActionBar(toolbar);
SupportActionBar.SetDisplayHomeAsUpEnabled(false);
SupportActionBar.SetHomeButtonEnabled(false);
}
bottomNavigation = FindViewById<BottomNavigationView>(Resource.Id.bottom_navigation);
bottomNavigation.NavigationItemSelected += BottomNavigation_NavigationItemSelected;
LoadFragment(Resource.Id.menu_home);
}
private void BottomNavigation_NavigationItemSelected(object sender, BottomNavigationView.NavigationItemSelectedEventArgs e)
{
LoadFragment(e.Item.ItemId);
}
void LoadFragment(int id)
{
Android.Support.V4.App.Fragment fragment = null;
switch (id)
{
case Resource.Id.menu_home:
fragment = Fragment1.NewInstance();
break;
case Resource.Id.menu_audio:
fragment = Fragment2.NewInstance();
break;
case Resource.Id.menu_video:
fragment = Fragment3.NewInstance();
break;
}
if (fragment == null)
return;
SupportFragmentManager.BeginTransaction()
.Replace(Resource.Id.content_frame, fragment)
.Commit();
}
}
}
Well its pretty simple this looks to me like you do not have your activity context here and for that reason you are unable to get the connMgr
What you need to do is when you call your fragment from your activity pass the current activity to your ~Fragment~ something like this on your fragment call:
Fragment1 newInstance(this);
Receive it in your fragment with something like this in your constructor:
public static AppCompatActivity _activity
public static Fragment1 newInstance(AppCompatActivity activity )
{
_activity =activity ;
//Lines of code }
And in your onCreateView use it like this :
ConnectivityManager connMgr = (ConnectivityManager)_activity.GetSystemService(Android.Content.Context.ConnectivityService);
NetworkInfo networkInfo = connMgr.ActiveNetworkInfo;
bool isConnected = networkInfo.IsConnected;
If it doesn't work lemme know! Goodluck
I crated a dynamic GridView which having a custom Adapterclass. Now i try to get the position and position name of click at GridView.
For that i used ItemClick, Problem is that its not working.
Here is my code.
This is my custom Adapter
using System;
using Android.Widget;
using Android.App;
using System.Collections.Generic;
using Android.Views;
using Android.Graphics;
using System.Net;
using Square.Picasso;
using Android.Util;
namespace AMUSEAndroid
{
public class GridViewAdapter : BaseAdapter<ImageItem>
{
Activity context;
List<ImageItem> items;
public GridViewAdapter (Activity context, List<ImageItem> gridViewtems)
{
this.context = context;
this.items = gridViewtems;
}
public override int Count {
get { return items.Count; }
}
public override ImageItem this[int position]
{
get { return items[position]; }
}
public override long GetItemId (int position)
{
return position;
}
public override View GetView (int position, View convertView, ViewGroup parent)
{
View view = convertView;
var item = items[position];
if (view == null)
view = context.LayoutInflater.Inflate(Resource.Layout.player_grid_item, null);
ImageView imgIcon = view.FindViewById<ImageView> (Resource.Id.img_play_bg);//.SetImageBitmap (gridViewtems[position]);
view.FindViewById<TextView> (Resource.Id.music_text).Text = item.Heading;
/*imgIcon.Click += delegate(object sender, EventArgs e) {
Toast.MakeText (context, "Click"+position, ToastLength.Short).Show ();
Log.Info("BIKAHS","click at"+position);
};*/
/*var imageBitmap = GetImageBitmapFromUrl(item.ImageResourceId);
imgIcon.SetImageBitmap(imageBitmap);*/
Picasso.With(context)
.Load(item.ImageResourceId)
//.Placeholder(Resource.Drawable.place_holder)
.Into(imgIcon);
return view;
}
void ImgIcon_Click (object sender, EventArgs e)
{
//Toast.MakeText (context, "Click"+position, ToastLength.Short).Show ();
}
}
}
ItemCLick is working when i don't use the custom adapter clase.
What to do.. Any idea or reference. Please help.
Try this you need to register the click event
public override View GetView (int position, View convertView, ViewGroup parent)
{
View view = convertView;
var item = items[position];
if (view == null)
view = context.LayoutInflater.Inflate(Resource.Layout.player_grid_item, null);
ImageView imgIcon = view.FindViewById<ImageView> (Resource.Id.img_play_bg);//.SetImageBitmap (gridViewtems[position]);
view.FindViewById<TextView> (Resource.Id.music_text).Text = item.Heading;
//register the click event
imgIcon.Click+=ImgIcon_Click
Picasso.With(context)
.Load(item.ImageResourceId)
//.Placeholder(Resource.Drawable.place_holder)
.Into(imgIcon);
return view;
}
void ImgIcon_Click (object sender, EventArgs e)
{
var name=items[e.postion].heading;
}
From what I've been able to gather from google, calling RegisterForContextMenu on a view should be all I have to do if I want OnCreateContextMenu to be called when I long click on said view. This does not happen.
The funny thing is, if I pass in View instead of gameList in the code below, the context menu appears if I long click at an empty portion of the main view. Long clicking on the list (which is a subview) still has no result.
I also tried registering a ItemLongClick event listener on the ListView, this does not get called either :/
The GameList fragment is run inside a viewpager.
using Android.Views;
using Android.OS;
using Android.Runtime;
using Android.Widget;
using Android.Support.V4.App;
using Models = Boardwar.Common.Models;
using Boardwar.AndroidClient.Adapters;
namespace Boardwar.AndroidClient.Fragments {
public class GameList : Fragment {
GamesAdapter GamesAdapter;
public GameList () {
}
public GameList (IntPtr handle, JniHandleOwnership jni) : base(handle, jni) {
}
public override View OnCreateView (LayoutInflater inflater, ViewGroup parent, Bundle bundle) {
return inflater.Inflate(Resource.Layout.GameList, parent, false);
}
public override void OnActivityCreated (Bundle p0) {
base.OnActivityCreated(p0);
var mainActivity = Activity as MainActivity;
var gameList = View.FindViewById<ListView>(Resource.Id.game_list);
GamesAdapter = new GamesAdapter(mainActivity);
gameList.Adapter = GamesAdapter;
mainActivity.GamesAdapter = GamesAdapter;
RegisterForContextMenu(gameList);
View.FindViewById(Resource.Id.new_game_button).Click += (sender, e) => {
mainActivity.ReplaceChildFragments(typeof(NewGame));
};
}
public override void OnCreateContextMenu (IContextMenu menu, View view, IContextMenuContextMenuInfo menuInfo) {
base.OnCreateContextMenu(menu, view, menuInfo);
menu.Add(Resource.String.remove_finished_games);
}
public override bool OnContextItemSelected (IMenuItem item) {
MainActivity.Client.RemoveFinishedGames();
return true;
}
public override void OnResume () {
base.OnResume();
GamesAdapter.UpdateList();
}
public override void OnDestroyView () {
base.OnDestroyView();
(Activity as MainActivity).GamesAdapter = null;
}
}
}
My problem was that I was registering ClickHandlers on the actual list-items, instead of a global ClickHandler on the actual list-view. This would block the click event from propegating to the list-view, which is why the context menu wouldn't appear.