I'm trying to implement supportmapfragment on my fragment but for some reason it gives me error. What I'm doing wrong?
Error I'm getting: java.lang.IllegalStateException: Fragment SupportMapFragment{67446a6} (09078183-572b-41c6-8795-7441157371d5) has not been attached yet.
supportMapFragment.getMapAsync(this). Is never called it crash before that
class MapFragment : Fragment(), OnMapReadyCallback {
private lateinit var googleMap: GoogleMap
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
val view = inflater.inflate(R.layout.fragment_map, container, false)
val supportMapFragment = SupportMapFragment()
supportMapFragment.childFragmentManager.findFragmentById(R.id.google_map)
supportMapFragment.getMapAsync(this)
return view
}
}
And fragment_map .xml file looks like:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:background="#color/primaryBackground"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.fragment.app.FragmentContainerView
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/google_map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Adding:
private lateinit var mapFragment: SupportMapFragment
removing
val supportMapFragment = SupportMapFragment()
and changing
supportMapFragment.childFragmentManager.findFragmentById(R.id.google_map)
to
mapFragment = childFragmentManager.findFragmentById(R.id.google_map) as SupportMapFragment
fixes this
Related
I have three tabs in xamarin android, I have used tab Host to create those tabs. Now, I want to change the text color in those tabs, and I want to use the swipe effect just like the Tabbed Page in Xamarin Forms. How can I achieve this? Please do tell me the library also ,if required?
I want to change the text color in those tabs, and I want to use the swipe effect just like the Tabbed Page in Xamarin Forms
You could use TabLayout, Usage like this :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.design.widget.TabLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/tablayout"
app:tabTextColor="#color/colorPrimary"
app:tabSelectedTextColor="#color/colorAccent"
app:tabIndicatorColor="#android:color/holo_orange_light">
<android.support.design.widget.TabItem
android:text="tab 1"/>
<android.support.design.widget.TabItem
android:text="tab 2"/>
<android.support.design.widget.TabItem
android:text="tab 3"/>
</android.support.design.widget.TabLayout>
</LinearLayout>
Attribute to change the text color :
app:tabTextColor --> The default text color to be applied to tabs.
app:tabSelectedTextColor --> The text color to be applied to the currently selected tab.
app:tabIndicatorColor --> Color of the indicator used to show the currently selected tab.
Effect like this.
use the swipe effect just like the Tabbed Page in Xamarin Forms
In Xamarin.Forms, tabs is associated with Page, actually when it render in native Android, it was associated with ViewPager. So if you want implement the swipe effect feature, you have to write the code by yourself. For more details, you could read the document.
EDIT :
To use TabLayout, you have to add Xamarin.Android.Support.v4 and Xamarin.Android.Support.Design nuget package.
EDIT 2 ;
Here is a simple demo about implement the swipe effect :
public class MainActivity : AppCompatActivity
{
private List<Android.Support.V4.App.Fragment> mFragments = new List<Android.Support.V4.App.Fragment>();
private List<string> mTabTitles = new List<string>();
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
TabLayout tabLayout = FindViewById<TabLayout>(Resource.Id.tablayout);
ViewPager viewPager = FindViewById<ViewPager>(Resource.Id.view_pager);
initTab();
mFragments.Add(new Fragment1());
mFragments.Add(new Fragment1());
mFragments.Add(new Fragment1());
mFragments.Add(new Fragment1());
viewPager.Adapter = new ViewPagerAdapter(SupportFragmentManager, mFragments,mTabTitles);
tabLayout.SetupWithViewPager(viewPager);
}
private void initTab()
{
for (int i = 1; i < 5; i++)
{
mTabTitles.Add("Tab" + i);
}
}
}
public class ViewPagerAdapter : FragmentPagerAdapter
{
private List<string> mTabTitles;
private static int FRAGMENT_COUNT = 4;
public ViewPagerAdapter(Android.Support.V4.App.FragmentManager fragmentManager, List<Android.Support.V4.App.Fragment> fragments, List<string> tabTitles):base(fragmentManager)
{
mTabTitles = tabTitles;
}
public override Android.Support.V4.App.Fragment GetItem(int position)
{
Fragment1 testFragment = new Fragment1();
return testFragment;
}
public override int Count => FRAGMENT_COUNT;
public override ICharSequence GetPageTitleFormatted(int position)
{
return new Java.Lang.String(mTabTitles[position]);
}
}
axml file :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/tablayout"
>
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</android.support.v4.view.ViewPager>
</LinearLayout>
Effect.
EDIT 3 :
In my demo, Fragment should use Android.Support.V4.App.Fragment, code like this :
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);
return base.OnCreateView(inflater, container, savedInstanceState);
}
}
I need to dynamically create MvxFrameControll, inflate it with content and add to another Layout (FrameLayout / LinearLayout).
My code is
HomeScreen.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<krista.fm.iMonitoring.Android.Native.TopBar
android:layout_width="match_parent"
android:layout_height="50dp"
local:MvxBind="DataContext TopBar"
local:MvxTemplate="#layout/topbar"
android:id="#+id/TopBar" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/SubjectBodyContainer" />
</LinearLayout>
public class SubjectBody : MvxFrameControl
{
public SubjectBody (Context context, IAttributeSet attrs) : base (context, attrs)
{
}
public SubjectBody (int templateId, Context context, IAttributeSet attrs) : base (context, attrs)
{
}
protected override void OnContentSet ()
{
base.OnContentSet ();
}
}
HomeScreenView
[Activity (Label = "HomeScreen")]
public class HomeScreenView : MvxActivity
{
public override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
}
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.HomeScreen);
AddSubjectBody();
}
protected override void OnStart()
{
base.OnStart();
}
protected virtual void AddSubjectBody()
{
var container = FindViewById<FrameLayout>(Resource.Id.SubjectBodyContainer);
var subjectBody = new SubjectBody(Resource.Layout.SubjectBody, this, null);
subjectBody.DataContext = new SubjectBodyViewModel();
container.AddView(subjectBody, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent));
}
}
Why this code doesn't add content on screen and how it rewrite rightly? When I use SubjectBody adding inside axml with templateId it works correctly. But what if i need adding this dynamically?
protected virtual void AddSubjectBody()
{
var container = FindViewById<FrameLayout>(Resource.Id.SubjectBodyContainer);
var subjectBody = new SubjectBody(Resource.Layout.SubjectBody, this, null);
subjectBody.DataContext = new SubjectBodyViewModel();
container.AddView(subjectBody, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent));
}
Are you sure your code is running on the UI thread? I'm using pretty a similar code in one app and the view gets added into the parent. What I suggest you to try is:
this.RunOnUiThread(() => container.AddView(this.subjectBody));
I am trying to set the Google Map in an Android Studio Project but facing incompatible types error even after applying different options couldn't get rid of it. Thanks for your time and guidance
Screenshot of error
Logcate report
Error:(454, 88) error: incompatible types: Fragment cannot be converted to SupportMapFragment
XML code
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map2"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Activity code
public class Search extends FragmentActivity implements OnMapReadyCallback
private void initializeMap()
{
SupportMapFragment map = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map2)).getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
}
try to change this line
SupportMapFragment map = ((SupportMapFragment)getFragmentManager().findFragmentById(R.id.map2)).getMapAsync(this);
to
SupportMapFragment map = ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map2)).getMapAsync(this);
For more information, check this SO question
I try to bind the selected item of a MvxListView to my property. This is my Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include
layout="#layout/toolbar_actionbar" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:paddingRight="6dp">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint_search_text"
local:MvxBind="Text SearchText" />
<MvxListView
android:id="#+id/category_list"
android:orientation="vertical"
android:choiceMode="singleChoice"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
local:MvxItemTemplate="#layout/listitem_category"
local:MvxBind="ItemsSource Categories; SelectedItem SelectedCategory" />
</LinearLayout>
</LinearLayout>
The ItemSource here is properly bound.
ViewModel:
[ImplementPropertyChanged]
public class SelectCategoryListViewModel : AbstractCategoryListViewModel
{
/// <summary>
/// Creates an CategoryListViewModel for the usage of providing a category selection.
/// </summary>
/// <param name="categoryRepository">An instance of <see cref="IRepository{T}" /> of type category.</param>
/// <param name="dialogService">An instance of <see cref="IDialogService" /></param>
public SelectCategoryListViewModel(IRepository<Category> categoryRepository,
IDialogService dialogService) : base(categoryRepository, dialogService)
{}
public Category SelectedCategory { get; set; }
public MvxCommand DoneCommand => new MvxCommand(Done);
public MvxCommand CancelCommand => new MvxCommand(Cancel);
private void Done()
{
MessageHub.Publish(new CategorySelectedMessage(this, SelectedCategory));
Close(this);
}
private void Cancel()
{
Close(this);
}
}
Not the notify PropertyChanged is done via Fody and Categories are in the parent VM.
public class SelectCategoryListActivity : MvxFragmentCompatActivity<SelectCategoryListViewModel>
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.fragment_category_list);
SetSupportActionBar(FindViewById<Toolbar>(Resource.Id.toolbar));
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
}
...
The Warning I get is:
[0:] MvxBind:Warning: 5.11 Failed to create target binding for binding SelectedItem for SelectedCategory
Ideas?
I just came across a similar issue with a SelectedItem binding failing. The solve was to update Mvx to version 4.1.6. The reason being is that you need to register MvxAppCompatSetupHelper.FillTargetFactories, with 4.1.6 this is now done automatically.
Alternatively, you can manually register it in you setup.cs by overriding FillTargetFactories:
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
MvxAppCompatSetupHelper.FillTargetFactories(registry);
base.FillTargetFactories(registry);
}
I have a slight problem figuring out a "bug" in my code. Im not sure if its a bug or not. However, as you can see in the picture 1, the fixed tabs' position is behind the curtain drawer. I cant find/understand why this is. Ive followed several tutorials and they dont seem to have the same problem.
Ive tried to google it up, but i cant find a similar problem. Anyone experienced something similar before?
In the android studio, the design layout seems to be on point, however, not when compiled.
Im using the neokree lib so i can use the icons and ripple effect when selecting tabs. I've tried to use the google's tab layout link here, but as soon as i tried to remove the actionbar and apply the icons, the same problem occurred.
Thanks!
activity_main
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<it.neokree.materialtabs.MaterialTabHost
android:id="#+id/materialTabHost"
android:layout_width="match_parent"
android:layout_height="48dp"
app:iconColor="#color/iconColor"
app:primaryColor="#color/primaryColor"
app:accentColor="#color/accentColor"
app:hasIcons="true"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"/>
</LinearLayout>
styles.xml
<resources>
<style name="AppTheme" parent="AppTheme.Base"></style>
<style name="AppTheme.Base" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">#color/primaryColor</item>
<item name="colorPrimaryDark">#color/primaryColorDark</item>
<item name="colorAccent">#color/accentColor</item>
<item name="colorControlHighlight">#color/colorHighlight</item>
</style>
</resources>
styles.xml v21
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Base application theme. -->
<!--Using same style as in default style.xml file-->
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:colorPrimary">#color/primaryColor</item>
<item name="android:colorPrimaryDark">#color/primaryColorDark</item>
<item name="android:colorAccent">#color/accentColor</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:colorControlHighlight">#color/colorHighlight</item>
</style>
</resources>
MainActivity
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ImageSpan;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import it.neokree.materialtabs.MaterialTab;
import it.neokree.materialtabs.MaterialTabHost;
import it.neokree.materialtabs.MaterialTabListener;
public class MainActivity extends ActionBarActivity implements MaterialTabListener
{
private Toolbar toolbar;
private ViewPager mPager;
private SlidingTabLayout mTabs;
private MaterialTabHost tabHost;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabHost = (MaterialTabHost) findViewById(R.id.materialTabHost);
viewPager = (ViewPager) findViewById(R.id.viewPager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
tabHost.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < adapter.getCount(); i++) {
tabHost.addTab(
tabHost.newTab()
.setIcon(adapter.getIcon(i))
.setTabListener(this));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings)
{
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onTabSelected(MaterialTab materialTab) {
viewPager.setCurrentItem(materialTab.getPosition());
}
#Override
public void onTabReselected(MaterialTab materialTab) {
}
#Override
public void onTabUnselected(MaterialTab materialTab) {
}
class ViewPagerAdapter extends FragmentStatePagerAdapter
{
int icons[] = {R.drawable.ic_home,
R.drawable.ic_graph,
R.drawable.ic_bell_mid,
R.drawable.ic_settings};
//String[] tabText = getResources().getStringArray(R.array.tabs);
public ViewPagerAdapter(FragmentManager fm)
{
super(fm);
//tabText = getResources().getStringArray(R.array.tabs);
}
#Override
public Fragment getItem(int position)
{
MyFragment myFragment = MyFragment.getInstance(position);
return myFragment;
}
//Attaching an image to a (spannable) string so we can show the image instead of text.
#Override
public CharSequence getPageTitle(int position){
/*Drawable drawable = getResources().getDrawable(icons[position]);
//icon bounds/size
drawable.setBounds(0,0,96,96);
ImageSpan imageSpan = new ImageSpan(drawable);
SpannableString spannableString = new SpannableString(" ");
spannableString.setSpan(imageSpan, 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannableString;*/
return getResources().getStringArray(R.array.tabs)[position];
}
#Override
public int getCount()
{
return 4;
}
private Drawable getIcon(int position)
{
return getResources().getDrawable(icons[position]);
}
}
}
After accidentally getting over a youtube tutorial about making simple material design tabs, I made a new project and started to combine the one I found in youtube with my old one. Eventually, I found out that the following code line in the styles file was the cause of the problem.
<item name="android:windowTranslucentStatus">true</item>
It seems like it was something I added for testing and forgot to remove later on.
Try adding a Toolbar with a no actionbar theme..
In order to do this you have to make a new xml file called tool_bar.xml and paste the following code into it:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="#color/ColorPrimary"
android:elevation="2dp"
android:theme="#style/Theme.AppCompat.NoActionBar"
xmlns:android="http://schemas.android.com/apk/res/android" />
You have then add this to your activity_main.xml file:
<include
android:id="#+id/tool_bar"
layout="#layout/tool_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>