Getting System.InvalidCastException in c# - c#

I'm trying to access global activity variables (which I can't make as static) from a BroadcastReceiver . For that, I create a instance of the activity this way:
class wifiReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
MainActivity activity = (MainActivity)context.ApplicationContext;
...
But i get System.InvalidCastException: Specified cast is not valid. in instance creation line. What am i doing wrong?
EDIT: Some code of my activity
public class MainActivity : Activity
{
private WifiManager _manager;
private List<string> _wifiSignals;
private wifiReceiver _wifiReceiver;
private TextView _Text;
protected override void OnCreate(Bundle bundle)
{
...
_wifiReceiver = new wifiReceiver();
_manager = (WifiManager)GetSystemService(Context.WifiService);
_wifiSignals = new List<string>();
if (_manager.IsWifiEnabled)
{
_manager.StartScan();
}
...
}
And more extensive code from BroadcastReceiver:
public override void OnReceive(Context context, Intent intent)
{
MainActivity activity = (MainActivity)context.ApplicationContext;
activity._wifiSignals.Clear();
activity._wifiSignals.Add("Lista de wifi:\n");
IList<ScanResult> wifiScanList = activity._manager.ScanResults;
foreach (ScanResult wifiNetwork in wifiScanList)
{
activity._wifiSignals.Add(wifiNetwork.Ssid + ": " + wifiNetwork.Level);
}
//activity.presentation(activity._wifiSignals, activity);
activity._manager.StartScan();
}

Although I remember to call MainActivity properties from another activities in previous apps I developed, I'm pretty sure you cant call a function like you try to do with the StartScan().
The option I use normally is to store the data serialized, and call it in Main.
I do a class with some methods like:
class persistence
{
ISharedPreferences prefs;
ISharedPreferencesEditor editor;
public persistence(Context cont)
{
prefs = PreferenceManager.GetDefaultSharedPreferences(cont);
editor = prefs.Edit();
}
public void store(List<articulo> articulos)
{
string raw = JsonConvert.SerializeObject(articulos);
editor.PutString("articulos", raw);
editor.Commit();
}
public List<articulo> recover()
{
string raw = prefs.GetString("articulos", null);
List<articulo> lista;
if (raw == null)
lista = new List<articulo>();
else
lista = JsonConvert.DeserializeObject<List<articulo>>(raw);
return lista;
}
}
In your OnReceive function I call to the store function
In your OnCreate function you can do directly
persistence datos;
protected override void OnCreate(Bundle bundle)
{
_wifiReceiver = new wifiReceiver();
_manager = (WifiManager)GetSystemService(Context.WifiService);
datos = new persistence (this);
_wifiSignals = datos.recover();
if(_wifiSignals.Count>0)
StartScan();
}
This will also keep data from one usage to another, if you don't want just clear the persistence data after call the BroadcastReceiver;

Related

Retrieve data from SQLite using xamarin Android & C#?

I have a class that gets longitude and latitude from user's device and and saves it to an SQLite database. Here's the code:
[Activity(Label = "GetLocation")]
public class GetLocation : Activity, ILocationListener
{
Button btncreate;
EditText txtlong;
EditText txtlat;
static readonly string TAG = "X:" + typeof(GetLocation).Name;
Location _currentLocation;
LocationManager _locationManager;
string _locationProvider;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.GetLocation);
txtlong = FindViewById<EditText>(Resource.Id.txtlong);
txtlat = FindViewById<EditText>(Resource.Id.txtlat);
btncreate = FindViewById<Button>(Resource.Id.btnvalidate);
btncreate.Click += Btncreate_Click;
InitializeLocationManager();
}
void InitializeLocationManager()
{
_locationManager = (LocationManager) GetSystemService(LocationService);
Criteria criteriaForLocationService = new Criteria
{
Accuracy = Accuracy.Fine
};
IList<string> acceptableLocationProviders = _locationManager.GetProviders(criteriaForLocationService, true);
if (acceptableLocationProviders.Any())
{
_locationProvider = acceptableLocationProviders.First();
}
else
{
_locationProvider = string.Empty;
}
Log.Debug(TAG, "Using " + _locationProvider + ".");
}
public void OnProviderDisabled(string provider) { }
public void OnProviderEnabled(string provider) { }
public void OnStatusChanged(string provider, Availability status, Bundle extras) { }
protected override void OnResume()
{
base.OnResume();
_locationManager.RequestLocationUpdates(_locationProvider, 0, 0, this);
}
protected override void OnPause()
{
base.OnPause();
_locationManager.RemoveUpdates(this);
}
public void OnLocationChanged(Location location)
{
_currentLocation = location;
if (_currentLocation == null)
{
txtlong.Text = "Unable to determine your location. Try again in a short while.";
txtlat.Text = "Unable to determine your location. Try again in a short while.";
}
else
{
txtlong.Text = _currentLocation.Longitude.ToString();
txtlat.Text = _currentLocation.Latitude.ToString();
}
}
private void Btncreate_Click(object sender, EventArgs e)
{
try
{
string dpPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Location.db3");
var db = new SQLiteConnection(dpPath);
db.CreateTable<DataTable>();
DataTable tbl = new DataTable();
tbl.Longitude = txtlong.Text;
tbl.Latitude = txtlat.Text;
db.Insert(tbl);
NextPage();
Toast.MakeText(this, "Data Store Successfully...,", ToastLength.Short).Show();
}
catch (Exception ex)
{
Toast.MakeText(this, ex.ToString(), ToastLength.Short).Show();
}
}
void NextPage()
{
//code to get next page
}
}
the DataTable class is as follows:
class DataTable
{
[PrimaryKey, AutoIncrement, Column("_Id")]
public int Id {get; set;}
public string Longitude { get; set; }
public string Latitude { get; set; }
}
once it has saved the data, I would like another class (activity) to be able to display it on a separate .axml page. my problem is I am a programmer in training (college) and have no clue what to do. Your help is greatly appreciated.
You need to start a new activity using
StartActivity(typeof(Activity2));
and in the OnCreate of your Activity2 set you new .axml layout:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.MyView);
}
Then to retrieve the data use Query:
string dpPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Location.db3");
var db = new SQLiteConnection(dpPath);
var dataTables = db.Query<DataTable>("select * from DataTable");
I'd recommend you to read SQLite: GettingStarted and if you want to improve that move all about SQLite to another class to reuse the code of openning an SQLiteConnection. Also if you can use asynchronous calls in order to prevent blocking the UI while persisting data in your database.
Also check Xamarin Android docs that is really helpful
HIH

OnScrollChanged doesn't get the RecyclerView parameters

I'm trying to implement this code here in my project:
The differences are that instead of a ScrollView I'm using a RecyclerView and that instead of having my RecyclerView directly in the Activity I have inside a fragment that sets the listener I need.
The problem is that while the OnScrollChanged(int l, int t, int oldl, int oldt) gets actually called everytime I scroll, the parameters it obtains are always 0 and I don't understand why, so ScrollChangedTarget doesn't work as intended.
This is the custom RecyclerView:
public class NotifyingScrollRecyclerView : RecyclerView
{
private Activity activity;
private View headerView;
private View footerView;
public delegate void ScrollChangedHandler(int l, int t, int oldl, int oldt, EventArgs e);
public event ScrollChangedHandler scrollChanged;
public EventArgs e = null;
//Enabling all required constructors
public NotifyingScrollRecyclerView(Context context) : base(context)
{
}
public NotifyingScrollRecyclerView(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
public NotifyingScrollRecyclerView(IntPtr ptr, JniHandleOwnership ownership) : base(ptr, ownership)
{
}
public NotifyingScrollRecyclerView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
}
//This method attribute allows us to register the inbuilt OnScrollChanged event that fires when scrolling a ScrollView
[Android.Runtime.Register("onScrollChanged", "(IIII)V", "GetOnScrollChanged_IIIIHandler")]
protected override void OnScrollChanged(int l, int t, int oldl, int oldt)
{
base.OnScrollChanged(l, t, oldl, oldt);
scrollChanged(l, t, oldl, oldt, e);
}
}
//Set an event listener
public class ScrollViewChangedListener
{
private Activity activity;
private NotifyingScrollRecyclerView scrollView;
private Android.Support.V7.App.ActionBar actionBar;
private Drawable actionBarDrawable;
be changed
public ScrollViewChangedListener(Activity a, NotifyingScrollRecyclerView n)
{
n.scrollChanged += ScrollChangedTarget;
this.activity = a;
this.scrollView = n;
this.actionBar = ((UserPageActivity)a).SupportActionBar;
this.actionBarDrawable = a.GetDrawable(Resource.Drawable.actionbar_background);
this.actionBarDrawable.SetAlpha(0);
}
//Handle the changing of the scroll
public void ScrollChangedTarget(int l, int t, int oldl, int oldt, EventArgs e)
{
//You set the View you want to be your header as a header height, and then get it's height
int headerHeight = activity.FindViewById<ImageView>(Resource.Id.profilebanner).Height -
this.actionBar.Height;
float ratio = (float)Math.Min(Math.Max(t, 0), headerHeight) / headerHeight;
int newAlpha = (int)(ratio * 255);
this.actionBarDrawable.SetAlpha(newAlpha);
this.actionBar.SetBackgroundDrawable(this.actionBarDrawable);
}
}
This is the Activity which calls the fragment (it doesn't do anything in particular aside calling the fragment in this case):
[Activity(Label = "UserPageActivity")]
public class UserPageActivity : BaseActivity
{
protected override int LayoutResource => Resource.Layout.activity_user_page;
UserViewModel viewModel;
TextView username;
TextView usernameToolbar;
Button followButton;
ViewPager pager;
UserTabsAdapter adapter;
bool IsLoggedUser;
protected override void OnCreate(Bundle savedInstanceState)
{
IsLoggedUser = Intent.GetStringExtra("userId").Equals(LoginController.GetInstance().CurrentUser.Email);
base.OnCreate(savedInstanceState);
viewModel = new UserViewModel();
viewModel.UserLoaded += new UserViewModel.UserLoadedHandler(OnUserLoaded);
viewModel.LoadUserCommand.Execute(Intent.GetStringExtra("userId"));
username = FindViewById<TextView>(Resource.Id.profilename);
usernameToolbar = FindViewById<TextView>(Resource.Id.usernamePage);
followButton = FindViewById<Button>(Resource.Id.followButton);
username.Text = Intent.GetStringExtra("username");
usernameToolbar.Text = Intent.GetStringExtra("username");
adapter = new UserTabsAdapter(this, SupportFragmentManager);
pager = FindViewById<ViewPager>(Resource.Id.user_viewpager);
var tabs = FindViewById<TabLayout>(Resource.Id.tabs);
pager.Adapter = adapter;
tabs.SetupWithViewPager(pager);
pager.OffscreenPageLimit = 5;
pager.PageSelected += (sender, args) =>
{
var fragment = adapter.InstantiateItem(pager, args.Position) as IFragmentVisible;
fragment?.BecameVisible();
};
}
private void OnUserLoaded(bool loaded)
{
}
protected override void OnStart()
{
base.OnStart();
if (IsLoggedUser)
{
followButton.Visibility = ViewStates.Gone;
}
else
{
bool following;
if (LoginController.GetInstance().CurrentUser.FollowsUsers.ContainsKey(Intent.GetStringExtra("userId")))
{
followButton.Text = "Unfollow";
following = true;
}
else
{
followButton.Text = "Follow";
following = false;
}
followButton.Click += (object sender, EventArgs e) =>
{
followButton.Enabled = false;
if (following)
{
UserService service = ServiceLocator.Instance.Get<UserService>();
service.SetUser(LoginController.GetInstance().CurrentUser);
service.RemoveFollowsUserCommand.Execute(viewModel.LoadedUser.Email);
service.SetUser(viewModel.LoadedUser);
service.RemoveFollowedByUserCommand.Execute(LoginController.GetInstance().CurrentUser.Email);
followButton.Text = "Follow";
following = false;
}
else
{
UserService service = ServiceLocator.Instance.Get<UserService>();
service.SetUser(LoginController.GetInstance().CurrentUser);
service.AddFollowsUserCommand.Execute(viewModel.LoadedUser);
service.SetUser(viewModel.LoadedUser);
service.AddFollowedByUserCommand.Execute(LoginController.GetInstance().CurrentUser);
followButton.Text = "Unfollow";
following = true;
}
followButton.Enabled = true;
};
}
}
}
class UserTabsAdapter : FragmentStatePagerAdapter
{
string[] titles;
public override int Count => titles.Length;
public UserTabsAdapter(Context context, Android.Support.V4.App.FragmentManager fm) : base(fm)
{
titles = context.Resources.GetTextArray(Resource.Array.user_sections);
}
public override Java.Lang.ICharSequence GetPageTitleFormatted(int position) =>
new Java.Lang.String(titles[position]);
public override Android.Support.V4.App.Fragment GetItem(int position)
{
switch (position)
{
case 0: return UserContestsFragment.NewInstance();
case 1: return UserPartecipationsFragment.NewInstance();
case 2: return GlobalContestFragment.NewInstance();
case 3: return MessagesFragment.NewInstance();
}
return null;
}
public override int GetItemPosition(Java.Lang.Object frag) => PositionNone;
}
This is the fragment which setups the listener for the recyclerview:
public class UserContestsFragment : AbstractRefresherFadingToolbarFragment<Contest>
{
public static UserContestsFragment NewInstance() =>
new UserContestsFragment { Arguments = new Bundle() };
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
ContestViewModel viewModel = new ContestViewModel();
base.ViewModel = viewModel;
base.LoadItemsCommand = viewModel.LoadAllByCreatorUserCommand;
base.param = Activity.Intent.GetStringExtra("userId");
base.adapter = new ContestsAdapter(Activity, viewModel);
var view = base.OnCreateView(inflater, container, savedInstanceState);
ScrollViewChangedListener listener = new ScrollViewChangedListener(Activity, recyclerView);
return view;
}
And this is the abstract fragment needed by that fragment which is in charge of setting up the layout:
public abstract class AbstractRefresherFadingToolbarFragment<T> : Android.Support.V4.App.Fragment, IFragmentVisible
{
public ICollectionViewModel<T> ViewModel;
public ICommand LoadItemsCommand;
public object param; //parametro per il LoadItemsCommand
public ItemsAdapter<T> adapter;
public SwipeRefreshLayout refresher;
public ProgressBar progress;
public NotifyingScrollRecyclerView recyclerView;
//LruCache cache = new LruCache((int)(Runtime.GetRuntime().MaxMemory() / 4));
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.fragment_fading_toolbar, container, false);
recyclerView = view.FindViewById<NotifyingScrollRecyclerView>(Resource.Id.recyclerView);
//ScrollViewChangedListener listener = new ScrollViewChangedListener((UserPageActivity)Activity, recyclerView);
//adapter.cache = cache;
recyclerView.HasFixedSize = true;
recyclerView.SetAdapter(adapter);
recyclerView.SetItemViewCacheSize(4);
//recyclerView.ChildViewAttachedToWindow += new EventHandler<RecyclerView.ChildViewAttachedToWindowEventArgs>(OnChildViewAttached);
//recyclerView.ChildViewDetachedFromWindow += new EventHandler<RecyclerView.ChildViewDetachedFromWindowEventArgs>(OnChildViewDetached);
refresher = view.FindViewById<SwipeRefreshLayout>(Resource.Id.refresher);
refresher.SetColorSchemeColors(Resource.Color.accent);
progress = view.FindViewById<ProgressBar>(Resource.Id.progressbar_loading);
progress.Visibility = ViewStates.Gone;
return view;
}
}
I didn't read your entire code but I looked at the site you linked in your question. The functionality of the hidden action bar you want to use is handled by CollapsingToolbarLayout in the support library. To know how to use it, go to Cheesesquare. It is a complete example of the support library widgets and can be built and run without any changes.
Edit:
RecyclerView has a method named AddOnScrollListener. Use it instead of the OnScrollChanged. If you use an inherited class from RecyclerView, you can call it in all of the constructors of that class.

Non-static field, method, or property

Looking at this How to show loading image or progress bar on WebView it clearly says that the following approach should work but I am having an issue as I cannot access my ProgressBar in public override void OnPageFinished(WebView view, string url)
My Code is the following
webView.Settings.JavaScriptEnabled = true;
webView.Settings.LoadWithOverviewMode = true;
webView.Settings.UseWideViewPort = true;
webView.SetWebViewClient(new WebViewClientClass());
webView.LoadDataWithBaseURL("file:///android_asset/", HTML_DATA, "text/html", "UTF-8", null);
Where my WebViewClientClass is the following
#region Webview URL handler
internal class WebViewClientClass : WebViewClient
{
public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request)
{
Android.Net.Uri url = request.Url;
view.LoadUrl(url.ToString());
return true;
}
public override void OnPageStarted(WebView view, string url, Bitmap favicon)
{
base.OnPageStarted(view, url, favicon);
Log.Info("101028", "loading started");
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
Log.Info("101028", "loading finised");
PB.Visibility = ViewState.Gone; ***<<<<<<<------ ERROR HERE***
}
}
#endregion
I can see the results in logcat but when I try to access my ProgressBar such as PB.Visibility = ViewState.Gone in OnPageFinished method - I get the following error
ERROR
An object reference is required for the non-static field, method, or property
PogressBar Code
private ProgressBar PB;
protected override async void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Read);
PB = FindViewById<ProgressBar>(Resource.Id.MyProgressBar);
}
Anyone knows what is the right approach for this? How do i make this work
Cheers
From your code it seems that your ProgressBar belongs to your Activity and you are trying to access it in WebViewClientClass that's why your object reference is missing.
So you should have a method inside your activity class which will hide/show ProgressBar and there must be some kind of call back mechanism to call this method
Define an interface like below
interface ProgressBarHandler{
public void hideProgress();
}
And in your activity class implement this interface
class MyActivity extends Activity implements ProgressBarHandler{
//other usual things in your activity
protected override async void OnCreate(Bundle savedInstanceState){
//here pass the activity instance to WebViewClientClass
webView.SetWebViewClient(new WebViewClientClass(this));
}
public void hideProgress(){
PB.Visibility = ViewState.Gone;
}
}
AND finally in your WebViewClientClass
class WebViewClientClass : WebViewClient
{
private ProgressBarHandler handler;
public WebViewClientClass(ProgressBarHandler handler){
this.handler = handler;
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
Log.Info("101028", "loading finised");
handler.hideProgress();
}
}

OnClickListeners for Recyclerviews -Xamarin.Droid

I have tried to look out for an answer to the behavior of my views but I seem not find any question or solution related to it. My recycler views seemed to be set up well. I just realized that my app is not responding in the right way to the OnClickListeners.
I have set up toasts in my adapter for the recycler view click events. When i have 10 views. When i click on a view, it gives a text of another view. It seems it randomly gives me the text of another view amongst the 9 remaining views. What could be the cause of this?
Activity
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
FrameLayout content = (FrameLayout)FindViewById(Resource.Id.content_frame);
LayoutInflater.Inflate(Resource.Layout.Main, content);
setUpRecyclerView();
}
public void setUpRecyclerView(){
rv = FindViewById<RecyclerView>(Resource.Id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.Orientation = LinearLayoutManager.Vertical;
layoutManager.ReverseLayout = true;
layoutManager.StackFromEnd = true;
rv.HasFixedSize = true;
rv.SetLayoutManager(layoutManager);
}
Adapter
public class FeedViewHolder : RecyclerView.ViewHolder, View.IOnClickListener, View.IOnLongClickListener
{
public FeedViewHolder(View itemView):base(itemView)
{
//binding of variables here
itemView.SetOnClickListener(this);
itemView.SetOnLongClickListener(this);
}
public void OnClick(View v)
{
itemClickListener.OnClick(v, AdapterPosition, false);
}
public bool OnLongClick(View v)
{
itemClickListener.OnClick(v, AdapterPosition, true);
return true;
}
public class FeedAdapter : RecyclerView.Adapter, ItemClickListener
{
public FeedAdapter(RssObject rssObject, Context mContext)
{
this.mContext = mContext;
this.inflater = LayoutInflater.From(mContext);
activity = (MainActivity)mContext;
}
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
hold = holder as FeedViewHolder;
//binding
hold.itemClickListener = this;
}
public void OnClick(View view, int position, bool isLongClick)
{
Toast.MakeText(activity, "Main text : " + hold.txtContent.Text, ToastLength.Long).Show();
}
public override int ItemCount
{
get { return rssObject.items.Count; }
}
}
}
}

MVVMCross - BaseActivity and OnViewModelSet()

I have a little problem, which I can't solve..
Well, I built a BaseActivity.cs Class:
public class BaseActivity<T> : MvxBindingTabActivityView<T> where T : class, IMvxViewModel
{
protected override void OnViewModelSet()
{ }
public override bool OnCreateOptionsMenu(IMenu menu)
{
// GroupId, ItemId, OrderId
menu.Add(0, 0, 0, "Einstellungen").SetIcon(Android.Resource.Drawable.IcMenuManage);
menu.Add(0, 1, 1, "Info").SetIcon(Android.Resource.Drawable.IcMenuInfoDetails);
return true;
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
var id = item.ItemId + 1; // (Id is zero-based :)
if (id == 1) // First Item
{
StartActivity(typeof(SettingsShowActivity));
}
else if (id == 2) // Second Item
{
Android.App.AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog ad = builder.Create();
ad.SetTitle("Information");
ad.SetIcon(Android.Resource.Drawable.IcDialogAlert);
ad.SetMessage("Version: 0.1");
ad.SetButton("OK", (s, e) => { Console.WriteLine("OK Button clicked, alert dismissed"); });
ad.Show();
}
return true;
}
}
The goal of this class is, that I can put things in that I will use in every other Activity, just like here, the OptionsMenu, which is more or less on all Activities..
Then my other two Activities which are inheriting from BaseActivity.cs:
the MainScreenActivity.cs:
[Activity]
public class MainScreenActivity : BaseActivity<MainScreenViewModel>
{
protected override void OnViewModelSet()
{
SetContentView(Resource.Layout.MainScreenLayout);
TabHost.TabSpec spec;
Intent intent;
intent = base.CreateIntentFor<AddressesSearchViewModel>();
intent.AddFlags(ActivityFlags.NewTask);
spec = TabHost.NewTabSpec("adressen");
spec.SetIndicator("Adressen");
spec.SetContent(intent);
TabHost.AddTab(spec);
intent = base.CreateIntentFor<ContactsSearchViewModel>();
intent.AddFlags(ActivityFlags.NewTask);
spec = TabHost.NewTabSpec("kontaktpersonen");
spec.SetIndicator("Kontaktpersonen");
spec.SetContent(intent);
TabHost.AddTab(spec);
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
}
}
and the LoginActivity.cs:
[Activity]
public class LoginActivity : BaseActivity<LoginViewModel>
{
protected override void OnResume()
{
base.OnResume();
App.IsLoggedIn = false;
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
}
protected override void OnViewModelSet()
{
SetContentView(Resource.Layout.Login);
//App.MessageHub.Subscribe<ErrorMessage>((m) => { ErrorMessageAlert(m.Message, m.Title); });
}
}
Its compiling fine, but the app crashes when I start it, and thats the errormessage I get: Your content must have a TabHost whose id attribute is 'android.R.id.tabhost' . I suggest, that it is because I "needed" to implement the abstract interface into the BaseActivity.cs :
protected override void OnViewModelSet()
{ }
So maybe he walks into the 'false' OnViewModelSet(), (In the empty one instead of the one which is building the Tabhost).. but I'm actually not sure.. btw this comes from: MvxBindingTabActivityView..
Hmm any help would be appreciated
I think this is a quite simple problem...
MvxBindingTabActivityView inherits from TabActivity (see source) and it's this class that requires the content - Your content must have a TabHost whose id attribute is 'android.R.id.tabhost'
If you don't want to use Tabs, then just inherit from MvxBindingActivityView instead - this is what the conference sample does - https://github.com/slodge/MvvmCross/blob/vnext/Sample%20-%20CirriousConference/Cirrious.Conference.UI.Droid/Views/BaseView.cs
If one of your activities needs to do tabs, but the other doesn't then they need to inherit using different inheritance trees. If you want to share code between the two base classes, then the best way to do this in C# seems to be using extension methods - e.g. see BaseViewExtensionMethods.cs shared between BaseView.cs, BaseTabbedView.cs and BaseMapView.cs in the conference sample.

Categories