Xamarin Android - Error inflating class fragment - Google Maps v2 - android

I've seen others with a similar issue, but none of their solutions seemed to work for me. The Exception being thrown is:
Android.Views.InflateException: Binary XML file line #1: Error inflating class fragment
map.axml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/top_map_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout...>
<CheckBox... />
</LinearLayout>
<LinearLayout...>
<CheckBox... />
</LinearLayout>
<EditText.../>
</LinearLayout>
<fragment
android:id="#+id/map"
android:layout_below="#+id/top_map_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
class="com.google.android.gms.maps.MapFragment" />
</RelativeLayout>
My Activity class is inheriting AppCompatActivity.
BaseActivity.cs:
public abstract class BaseActivity : AppCompatActivity
{
//...
}
MainActivity.cs:
[Activity(Label = "MyApp", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, Icon = "#drawable/Icon")]
public class MainActivity : BaseActivity
{
//...
}
My Fragment is inheriting Android.Support.V4.App.Fragment.
public abstract class BaseFragment : Android.Support.V4.App.Fragment
{
//...
}
And finally here is my map fragment where the exception is being thrown when trying to inflate:
public class LocationFragment : BaseFragment, IOnMapReadyCallback, GoogleMap.IOnMapLongClickListener
{
//...
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// exception thrown on following line
return inflater.Inflate(Resource.Layout.map, container, false);
}
}
I'm guessing this may have something to do with having a fragment within a fragment.
Edit 1:
Just to clarify that I do indeed have the correct information in my manifest, here is a snippet of it:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="com.myPackage" android:versionCode="11" android:versionName="2.0">
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="21" />
<application android:label="MyApp" android:icon="#drawable/Icon" android:theme="#style/MyTheme">
<uses-library android:name="com.google.android.maps" />
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="itsasecret" />
<meta-data android:name="com.google.android.geo.API_KEY" android:value="itsasecret" />
</application>
</manifest>
I also took steps to verify that my API key is valid.
My key matches what is in my manifest. The package name matches up as well. I also verified the SHA1 by running keytool -list -v -keystore "C:\Users\Jared\AppData\Local\Xamarin\Mono for Android\debug.keystore" -alias androiddebugkey -storepass android -keypass android.

So I figured it out... sort of. I am now getting the map fragment properly when I first go to it, but I get the same inflate exception if I go to a different fragment and come back.
The "solution" to get this far was to remove <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="itsasecret" /> from my manifest. Applying the API_KEY to two different values apparently causes problems. Although the error I was getting was not indicating this whatsoever.
So now I have only one line for the API_KEY:
<meta-data android:name="com.google.android.geo.API_KEY" android:value="itsasecret" />
I'll update my answer when I figure out why I'm getting the exception when coming back to the fragment a second time.
Edit: To fix the problem I was having, I ended up removing the fragment from the xml file entirely and adding it programmatically. No idea what was causing it in the first place, but this works.
xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/top_map_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout...>
<CheckBox... />
</LinearLayout>
<LinearLayout...>
<CheckBox... />
</LinearLayout>
<EditText.../>
</LinearLayout>
<LinearLayout
android:layout_below="#+id/top_map_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/map_placeholder"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</RelativeLayout>
LocationFragment.cs:
private MapFragment mapView;
public override void OnActivityCreated(Bundle savedInstanceState)
{
//...
mapView = MapFragment.NewInstance();
var ft = Activity.FragmentManager.BeginTransaction();
ft.Add(Resource.Id.map_placeholder, mapView).Commit();
}

Put your fragment inside LinearLayout.../LinearLayout and deploy your application
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.MapFragment" />
</LinearLayout>

Related

Unable to add xamarin.forms.map control to Xamarin Form

I want to add a map control to my android app.
To do this I have got the latest xamarin.forms and xamarin.forms.maps packages from Nuget.
My code behind logic does nothing at all, and my axml page looks like as below:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/optionsContainerLinearLayout">
//Other UI elements
<maps:Map>
</maps:Map>
</LinearLayout>
...
</LinearLayout>
Note I've but no tags within maps:Map so as to provide minimal chance for errors. Note that when I populate this map with more properties as directly below, the code still breaks in the same way:
<map:Map
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/mockMapView">
</map:Map>
When I run this application, it breaks on SetContentView() with the error:
Didn't find class "android.view.Map" on path: DexPathList
[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.geosolve.pavestate2-fJtHBLcT2gY6AlUrxcOOVg==/base.apk"],
nativeLibraryDirectories=[/data/app/com.geosolve.pavestate2-fJtHBLcT2gY6AlUrxcOOVg==/lib/x86, /data/app/com.geosolve.pavestate2-fJtHBLcT2gY6AlUrxcOOVg==/base.apk!/lib/x86, /system/lib]]
I've got another sample xamarin application I downloaded which runs fine on my emulator, so I don't think the emulator is the problem.
I have my API key being used by this other application as well, so I don't think the API key is the problem either.
My androidManifest.xml looks like so:
...
<application android:allowBackup="true" android:icon="#mipmap/icon" android:label="#string/app_name" android:roundIcon="#mipmap/icon" android:supportsRtl="true" android:theme="#style/GeosolveApp">
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="(My API Key)" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
...
Any help as to why this isn;'t just showing up like you would expect?
For Xamarin.Android,we usually install the Xamarin.GooglePlayServices.Maps package from NuGet.
And add the map in your xaml like:
Declaratively :
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment" />
Programmatically :
var mapFrag = MapFragment.NewInstance();
activity.FragmentManager.BeginTransaction()
.Add(Resource.Id.map_container, mapFrag, "map_fragment")
.Commit();
the more you could read Google Maps.

Error inflating class fragment. Must specify unique android:id, android:tag, or have a parent with an id

I am trying to run a fragment but my application keeps on crashing when i run it. I am trying to load the main activity so that i can display the webview in it but i am having no luck.
MainActivity
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Fragment code
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
public class WebViewFragment extends Fragment {
private WebView mWebView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
mWebView = (WebView) view.findViewById(R.id.webView);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.loadUrl("https://www.google.co.uk/");
return view;
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bashirsentongo.webviewapp">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.bashirsentongo.webviewapp.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
class="com.example.bashirsentongo.webviewapp.WebViewFragment"/>
</RelativeLayout>
fragment_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="layout.main">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/webView"/>
/>
</FrameLayout>
From the official documentation:
Note: Each fragment requires a unique identifier that the system can use to restore the fragment if the activity is restarted (and which you can use to capture the fragment to perform transactions, such as remove it). There are three ways to provide an ID for a fragment:
Supply the android:id attribute with a unique ID.
Supply the android:tag attribute with a unique string.
If you provide neither of the previous two, the system uses the ID of the container view.
https://developer.android.com/guide/components/fragments.html
Also you find an example here using an id for the fragment:
<fragment android:name="com.example.news.ArticleListFragment"
android:id="#+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
You seem to be confused with how to implement a Fragment.
The Fragment is loaded onto a viewgroup (typically FrameLayout) contained within the Activity, there isn't really a need for the Fragment to have a FrameLayout in your case. (Because the TextView and Webview will overlap)
That being said, once you have a FrameLayout in place of the use of the <fragment> tag, think about, how would you load the Fragment in the Activity? A FragmentTransaction. What does that need? An id for the view container to load the Fragment. And that's your error - you don't have one.
All of your <fragment> containers should have unique ID. Then just set ID for root RelativeLayout.

How to make application rotate in AVD

This is for a school project, but i didn't understand many parts of this.
I am leaving the handling of the rotation to the system, but after describing 2 layouts (standart and landscape mode)
But the landscape mode layout won't be taken into account when I rotate the screen.
(source: hostingpics.net)
(I have pressed the 4th button, in case it is the issue ...)
The mainactivity extends AppCompatActivity, (Because our teacher told us to), and all I do (for now) in the MainActivity is
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG,"Test");
}
then I described 2 LinearLayouts, one in layout/activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:baselineAligned="false"
android:divider="#drawable/empty_divider_tall"
android:showDividers="middle"
android:background="#color/fl_concrete"
>
<fragment
class="com.example.g20901528.androidproject.fragment.TopFragment"
android:id="#+id/fragment_top"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
<fragment
class="com.example.g20901528.androidproject.fragment.BottomFragment"
android:id="#+id/fragment_bottom"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
and another in layout-land/activity-main.xml which is almost the same :
edit : layout-land/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="false"
android:divider="#drawable/empty_divider_wide"
android:showDividers="middle"
android:background="#color/fl_concrete"
>
<fragment
class="com.example.g20901528.androidproject.fragment.TopFragment"
android:id="#+id/fragment_top"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
<fragment
class="com.example.g20901528.androidproject.fragment.BottomFragment"
android:id="#+id/fragment_bottom"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
I did not change my manifest aside describing the MainActivity :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.g20901528.androidproject">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
My question is : how to make it so the two fragments rotate when i rotate the phone ?
I'm ready to provide any information.
Github Link of the project, if you really need it.
dude your layout xml name is different please change that
layout/activity_main.xml
layout-land/activity-main.xml make it -->
layout-land/activity_main.xml
and run

How to create and use Android Library project on other projects

What I want to accomplish is the following:
Create a custom component with it's own interface and interaction
Create a .jar with that custom component
Consume that .jar in another Android project and be able to edit some of it's values
I've done since now:
1. Create a custom component and extract it's jar following this link
The content of the custom component looks like this:
The main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Yes!! I'm a custom component!"
/>
</LinearLayout>
With it's MainActivity:
public class MainActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
And it's own AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test_uc"
android:versionCode="1"
android:versionName="1.0">
<application android:label="#string/app_name">
<activity android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
2. Add it on my main project.
3. Use it in my main xml project like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, MyActivity"
/>
<test_uc android:layout_height="fill_parent" /> // SEE THE ITEM HERE
</LinearLayout>
But if I go to check the interface, I can't see the test_uc content, or modify anything of it.
So, my question is:
How to build a custom component, build it as a jar file, add it on a main project and be able to use it's properties or even see it in my interface?
Please, I'm a bit lost on this. Any idea will be really thankful!!!!
What I ended up doing in my case, was:
Create an Activity.
Give that activity to the user.
Use it as a library.
As a .jar is only a compressed acivity, that was enought for my purpose.
I did this because in my case, I had to make some event subscriptions, and this way was easier for the user.

SurfaceView: ClassCastException, unable to start activity

Trying to get an Android 2.2 application to start up with a SurfaceView as the base view with a button placed atop it located near the bottom of the screen. So far, no luck. It crashes every time it attempts to launch. I've checked to make sure that the activity is registered in the manifest.
Here's my java code:
public class Dragable extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
and here's my main.xml:
<?xml version="1.0" encoding="utf-8"?>
<SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/surface_home"
>
<Button
android:id="#+id/add_new"
android:text="#string/add_new"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
/>
</SurfaceView>
and my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".Dragable"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
and here's my error:
11-29 11:58:52.620: ERROR/AndroidRuntime(512): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.Dragable}: java.lang.ClassCastException: android.view.SurfaceView
Can't seem to find anything related doing searches on SO. My appologies if this has been asked before.
Now I see the problem. SurfaceView is not a container, I mean it does not extends ViewGroup, so you can't put a Button inside a SurfaceView. What you can do is wrapping the SurfaceView and the Button within a RelativeLayout.
You are not using any container to place components. Use this and make changes
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SurfaceView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/surface_home"
>
<Button
android:id="#+id/add_new"
android:text="#string/add_new"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
/>
</SurfaceView>
</FrameLayout>

Categories

Resources