Xamarin forms: hiding blue line from selected tab with a CustomTabRenderer for android - xamarin

I made a customrenderer for showing images in the tabs for the Android platform.
Now i'd like to know how i can remove the bottom line that shows which tab is selected.
Also, where can i get info about creating custom renderers? i looked on youtube but the example with the rounded corners doesn't show much...
namespace Plopsa.Android
{
public class CustomTabRenderer: TabbedRenderer
{
private Activity _activity;
protected override void OnModelChanged(VisualElement oldModel, VisualElement newModel)
{
base.OnModelChanged(oldModel, newModel);
_activity = this.Context as Activity;
}
// May put this code in a different method - was just for testing
public override void OnWindowFocusChanged(bool hasWindowFocus)
{
// Here the magic happens: get your ActionBar and select the tab you want to add an image
ActionBar actionBar = _activity.ActionBar;
if (actionBar.TabCount > 0)
{
ActionBar.Tab tabOne = actionBar.GetTabAt(0);
tabOne.SetIcon(Resource.Drawable.icon_tab1);
ActionBar.Tab tabTwo = actionBar.GetTabAt(1);
tabTwo.SetIcon (Resource.Drawable.icon_tab2);
ActionBar.Tab tabThree = actionBar.GetTabAt(2);
tabThree.SetIcon(Resource.Drawable.icon_tab3);
ActionBar.Tab tabFour = actionBar.GetTabAt(3);
tabFour.SetIcon(Resource.Drawable.icon_tab4);
}
base.OnWindowFocusChanged(hasWindowFocus);
}
}

You can achieve the desired result by setting the Tabbar.axml class 'android:tabIndicatorColor' to the same value as the 'android:background'.
Below is the code showing the desired result with a tab indicator matching the tab background color. This is all contained in the Tabbar.axml file. You can register the tabs in the MainActivitiy.cs.
Tabbar.axml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TabLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:tabTextAppearance="#style/MyCustomTabText"
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Light"
app:tabTextColor="#color/primaryOrange"
app:tabIndicatorColor="?attr/colorPrimary"
app:tabIndicatorHeight="0dp"
app:tabSelectedTextColor="#color/primaryOrange"
app:tabGravity="fill"
app:tabMode="fixed" />
MainActivity.cs
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.
base.OnCreate(bundle);
Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
Example Result

Related

Editing the NavigationPage back button size in xamarin forms

My aim is to change increase the size of the back arrow button that comes with the NavigationPage class. I have found out that we are able to change its color, but not it's size. Is it possible to do that in xamarin forms or can i atleast use a custom icon there that will suit my UI requirements.
<Style TargetType="NavigationPage">
<Setter Property="BarTextColor" Value="Red" />
<Setter Property="BarBackgroundColor" Value="Black" />
</Style>
Here i am able to set color for the "BarTextColor" but not it's size. Any help is appreciated.
NavigationPage back button is icon, so you can replace this icon using another bigger icon.
For Android platform, if your MainActivity type is FormsAppCompatActivity, you could custom a PageRenderer and change the Toolbar's NavigationIcon.
[assembly: ExportRenderer(typeof(ContentPage), typeof(NavigationPageRendererDroid))]
namespace FormsSample.Droid
{
public class NavigationPageRendererDroid : PageRenderer
{
public NavigationPageRendererDroid(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Page> e)
{
base.OnElementChanged(e);
var context = (Activity)this.Context;
var toolbar = context.FindViewById<AndroidX.AppCompat.Widget.Toolbar>(Droid.Resource.Id.toolbar);
toolbar.NavigationIcon = AndroidX.Core.Content.ContextCompat.GetDrawable(context, Resource.Drawable.c1);
}
}
}
Please note: ToolBar in Android platform> Resource folder> Layout type is androidx.appcompat.widget.Toolbar
If your ToolBar is other type, you can take a look:
How to change navigation page back button in xamarin forms
Update:
I also reproduce the same problem as you, from I provide the thread , you can follow the last solution, custom a NavigationPageRenderer, override the OnPushAsync method to set the Toolbar's icon.
Firstly, create a class named CustomNavigationPage in the .NET Standard project, and this class inherits from NavigationPage to make our custom renderer applied to that class.
public class CustomNavigationPage : NavigationPage
{
public CustomNavigationPage(Page startupPage) : base(startupPage)
{
}
}
Secondly, in Android project, create class named NavigationPageRenderer, override the OnPushAsync method.
[assembly: ExportRenderer(typeof(CustomNavigationPage), typeof(NavigationPageRenderer))]
namespace FormsSample.Droid
{
public class NavigationPageRenderer : Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer
{
public Activity context;
public NavigationPageRenderer(Context context) : base(context)
{
}
protected override Task<bool> OnPushAsync(Page view, bool animated)
{
var retVal = base.OnPushAsync(view, animated);
var context = (Activity)this.Context;
var toolbar = context.FindViewById<AndroidX.AppCompat.Widget.Toolbar>(Droid.Resource.Id.toolbar);
if (toolbar != null)
{
if (toolbar.NavigationIcon != null)
{
toolbar.NavigationIcon = AndroidX.Core.Content.ContextCompat.GetDrawable(context, Resource.Drawable.c1);
toolbar.Title = "back";
}
}
return retVal;
}
}
}
Finally, in App.xaml.csfile, set the MainPage to NavigtaionPage,
MainPage = new CustomNavigationPage(new simplecontrol.Page41());

How to open content pages through navigation menu in Xamarin native sample project

I am new to Xamarin and building a native app.
I saw many sites explaining the left side navigation menu
but they do not explain how to open other pages.
I wanted to show different content pages on the navigation click.
On one button click show only text.
Other button show gallery.
Please tell me how can I do this.
Thank you in advance!!!
In Xamarin.Android, when you want to navigate to a new layout, you could follow the steps below.
Create the layout in Resource/Layout folder and create acticity.cs in app project
TextLayout.xml
<TextView
android:id="#+id/tv_Text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
GralleryLayout.xml
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Add the control in main layout.
<Button
android:id="#+id/btn_TextLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Text Layout"/>
<Button
android:id="#+id/btn_GralleryLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/btn_TextLayout"
android:text="Grallery Layout"/>
Add the code below to navigate to the activity you want.
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
var btn_TextLayout = FindViewById<Button>(Resource.Id.btn_TextLayout);
btn_TextLayout.Click += Btn_TextLayout_Click;
var btn_GralleryLayout = FindViewById<Button>(Resource.Id.btn_GralleryLayout);
btn_GralleryLayout.Click += Btn_GralleryLayout_Click;
}
private void Btn_GralleryLayout_Click(object sender, System.EventArgs e)
{
var intent = new Intent(this, typeof(GralleryActivity));
StartActivity(intent);
}
private void Btn_TextLayout_Click(object sender, System.EventArgs e)
{
var intent = new Intent(this, typeof(TextActivity));
StartActivity(intent);
}
Open the view of TextLayout and GralleryLayout.
TextActivity.cs
SetContentView(Resource.Layout.TextLayout);
var tv_Text = FindViewById<TextView>(Resource.Id.tv_Text);
tv_Text.Text = "Only the text";
GralleryActvity.cs
var ImageView = FindViewById<ImageView>(Resource.Id.imageView1);
ImageView.SetImageResource(Resource.Drawable.pig);
Result:
You could download from the Android/App1 folder on GitHub for reference.
https://github.com/WendyZang/Test.git

VS Android App (Xamarin) Navigation Drawer App - Add Activity

I have used VS 2017 to create an Android App (Xamarin) Navigation Drawer App. I have searched the internet for an example of how to add a new activity to the app that uses the already created Navigation Drawer but have been unsuccessful. Any idea's on how to add an activity?
Thanks
Paul.
public bool OnNavigationItemSelected(IMenuItem item)
{
int id = item.ItemId;
if (id == Resource.Id.nav_camera)
{
// Run a new activity here!
}
else if (id == Resource.Id.nav_gallery)
{
}
else if (id == Resource.Id.nav_slideshow)
{
}
else if (id == Resource.Id.nav_manage)
{
}
else if (id == Resource.Id.nav_share)
{
}
else if (id == Resource.Id.nav_send)
{
}
DrawerLayout drawer = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
drawer.CloseDrawer(GravityCompat.Start);
return true;
}
From here, you can see this:
If your app switches out content based on which navigation menu item the user selects, you should consider using fragments in the main content area. Swapping fragments when you navigate from the navigation drawer allows for a seamless drawer animation, because the same base layout stays in place.
Official suggest us use fragment in the main content area.
If you want to start a new Activity, you need create a Activity and create a layout for it, like Activity1 :
[Activity(Label = "Activity1")]
public class Activity1 : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
SetContentView(Resource.Layout.layout1);
}
}
layout1:
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="new Activity" />
</LinearLayout>
And then start it:
if (id == Resource.Id.nav_camera)
{
Intent intent = new Intent(this, typeof(Activity1));
StartActivity(intent);
}
This will open a new Activity, and in the new Activity, there is no DrawerLayout.

How to change MvxDialogFragment layout

I want to change the default AlertDialog layout size.
I created class:
public class SampleDialog : MvxDialogFragment
{
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
var dialog = new AlertDialog.Builder(Context);
dialog.SetView(View.Inflate(Context,Resource.Layout.SampleDialog,null));
return dialog.Create();
}
public override void OnStart()
{
if (Dialog == null) { return; }
Dialog.Window.SetLayout(200,460);
base.OnStart();
}
}
and it's layout:
<?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="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/text1" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/text2" />
</LinearLayout>
And i'm creating dialog from fragment view:
var dialog = new SampleDialog
{
ViewModel = ViewModel,
Cancelable = true
};
dialog.Show(FragmentManager, "");
Tryed to set layout width in OnCreateDialog method,OnStart, or directly by setting LinearLayout.layout_width property, but the result is the same.
How this can be configured?
Inflating the layout
When inflating the layout you can make use of either the default inflator or Mvvmcross BindingInflate which will apply any xml bindings you require.
Default inflator:
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
base.EnsureBindingContextSet(savedInstanceState);
var dialog = new AlertDialog.Builder(Context);
dialog.SetView(Activity.LayoutInflater.Inflate(Resource.Layout.SampleDialog, null));
return dialog.Create();
}
Mvvmcross xml binding inflator:
public override Dialog OnCreateDialog(Bundle savedInstanceState)
{
base.EnsureBindingContextSet(savedInstanceState);
var dialog = new AlertDialog.Builder(Context);
dialog.SetView(this.BindingInflate(Resource.Layout.SampleDialog, null));
return dialog.Create();
}
Sizing the layout
The Dialog.Window.SetLayout() takes in the pixel values for 200(width) and 460(height) which will vary in physical size with different device screen resolutions.
A better approach would be to use dp and convert it to pixels:
Add the desired size dimensions to your dimens.xml
<resources>
<dimen name="dialog_width">400dp</dimen>
<dimen name="dialog_height">200dp</dimen>
</resources>
Update your SampleDialog
public override void OnStart()
{
base.OnStart();
var width = Resources.GetDimension(Resource.Dimension.dialog_width);
var height = Resources.GetDimension(Resource.Dimension.dialog_height);
Dialog.Window.SetLayout((int)width, (int)height);
}

display of image requires two clics instead of one

A piece of code I created to open an image requires that I click twice on the words to open the image. I don't understand why it doesn't respond to just one click.
In the layout here is the TextView
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="The New Yorker"
android:id="#+id/the_new_yorker"
android:textStyle="italic"
android:textColor="#color/blue"
android:onClick="new_yorker_cartoon"/>
and here is the corresponding function in the java file
public void new_yorker_cartoon(View view) {
final TextView TextGenerique = (TextView) findViewById(R.id.the_new_yorker);
View.OnClickListener monEcouteur = new View.OnClickListener() {
#Override
public void onClick(View v) {
String imageUrl = "http://www.lapasserelle.com/english/l09/imgs/new_yorker.gif";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(imageUrl), "image/gif");
startActivity(intent);
}
};
TextGenerique.setOnClickListener(monEcouteur);
}
What I don't understand is why I need to click twice on the words New Yorker to display the image new_yorker.gif on my phone.
It might be that the first click is to activate the screen and the second to get the response.

Resources