how can i move hamburger menu to right side on maui android? - maui

I am making android/ios app using maui.
I want to move my hamburger button to right side.
this is my appshell.xaml.
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MauiSample.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:MauiSample.Views"
xmlns:local="clr-namespace:MauiSample"
FlowDirection="RightToLeft">
<FlyoutItem
FlyoutDisplayOptions="AsMultipleItems">
<ShellContent Title="Dog2s"
ContentTemplate="{DataTemplate views:DogsPage}" />
<ShellContent Title="Monkeys"/>
<ShellContent Title="Elephants"/>
<ShellContent Title="Bears"/>
</FlyoutItem>
<ShellContent
Title="Home 2"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
</Shell>
I check added supportRtl="true" in android manifest.
android:supportsRtl="true"
I used FlowDirection="RightToLeft".
but not working on android.
working on ios.

Add this in your MainActivity.cs:
public class MainActivity : MauiAppCompatActivity
{    
protected override void OnCreate(Bundle savedInstanceState)    
{        
base.OnCreate(savedInstanceState);        
Window.DecorView.LayoutDirection = Android.Views.LayoutDirection.Rtl;    
}
}

Related

How to change the color of tab icons

As you can see I have added in FlyoutItem the Tabs that have Icon property which is an svg image that I need to change the color
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems" >
<Tab Title="Inicio" Icon="housesolid.svg">
<ShellContent ContentTemplate="{DataTemplate local:LoginCameraQR}" />
</Tab>
<Tab Title="Perfil" Icon="usergroupsolid.svg">
<ShellContent ContentTemplate="{DataTemplate local:LoginCameraQR}" />
</Tab>
<Tab Title="Cupones" Icon="tagssolid.svg">
<ShellContent ContentTemplate="{DataTemplate local:LoginCameraQR}" />
</Tab>
<Tab Title="Favoritos" Icon="heartsolid.svg">
<ShellContent ContentTemplate="{DataTemplate local:LoginCameraQR}" />
</Tab>
<Tab Title="Acerca de Nosotros" >
<ShellContent ContentTemplate="{DataTemplate local:LoginCameraQR}" />
</Tab>
<Tab Title="Facebook" Icon="facebook.svg">
<ShellContent ContentTemplate="{DataTemplate local:LoginCameraQR}" />
</Tab>
<Tab Title="Instagram" Icon="squareinstagram.svg">
<ShellContent ContentTemplate="{DataTemplate local:LoginCameraQR}" />
</Tab>
</FlyoutItem>
And I want to change the color of these svg icons, any ideas?
I tried with style, but it did not work, the property is not valid
<Style TargetType="Tab" Class="FlyoutItemImageStyle">
<Setter Property="Background"
Value="AliceBlue"></Setter>
</Style>
If I understand you correctly, you want to set the TintColor of the svg Image. You could just set the TintColor for the Image in csproj file:
<MauiImage Include="Resources\Images\housesolid.svg" TintColor="#66B3FF" />
Hope it works for you.

How can I hide a tab of a Shell TabBar conditionally?

I have a .Net MAUI app. In AppShell, it has a TabBar:
<TabBar>
<Tab Title="Home" Icon="{StaticResource IconHome}">
<ShellContent ContentTemplate="{DataTemplate local:MainPage}" />
</Tab>
<Tab Title="Estimator" Icon="{StaticResource IconCalculator}" >
<ShellContent ContentTemplate="{DataTemplate calculator:CoverageCalculatorPage}" />
</Tab>
<Tab Title="Distributors" Icon="{StaticResource IconLocator}">
<ShellContent ContentTemplate="{DataTemplate locator:DistributorsLocatorPage}" />
</Tab>
<Tab Title="Scan QR" Icon="{StaticResource IconQrScanner}">
<ShellContent ContentTemplate="{DataTemplate qrScanner:QrScannerPage}" />
</Tab>
<Tab Title="More" Icon="{StaticResource IconMore}">
<ShellContent ContentTemplate="{DataTemplate more:MoreFeaturesPage}" />
</Tab>
</TabBar>
I need to hide the "Scan QR" tab when run on Windows, and show only on iOS or Android. I realize that there is IsVisible property of Tab, but how can I make it conditional, based on the platform?
You can use class DeviceInfo.Platform to get the platform information. And add a bool variable to bind to property IsVisible of Tab.
Please refer to the following code:
public partial class AppShell : Shell
{
      public bool IsVisible {get;set;}
      public AppShell()
      {
            InitializeComponent();
            if (Microsoft.Maui.Devices.DeviceInfo.Platform == DevicePlatform.iOS || Microsoft.Maui.Devices.DeviceInfo.Platform == DevicePlatform.Android)
            {
                  IsVisible = true;
            }
            else
            {
                  IsVisible = false;
            }
            
            BindingContext = this;
}
}
And bind variable IsVisible to property IsVisible:
<Tab Title="Scan QR" Icon="grass.png" IsVisible="{Binding IsVisible}">
<ShellContent ContentTemplate="{DataTemplate local:QrScannerPage}" />
</Tab>

How to change position of the app title in .NET MAUI?

I want to change the position of title to the middle or right side of the screen. I used the following code:
<Shell
x:Class="CostManagement.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:CostManagement"
Shell.FlyoutBehavior="Disabled"
FlowDirection="RightToLeft">
<ShellContent
Title="Main Page"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
</Shell>
How can I change its position?
This can be customized by setting the Shell.FlyoutContent and use the CollectionView to define the appearance of the menu item like the title as you said. You can refer to the code sample below:
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="CostManagement.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:CostManagement"
FlyoutBackgroundColor="LightGray"
FlyoutBehavior="Flyout"
FlyoutWidth="400"
FlyoutHeight="400">
<Shell.FlyoutContent>
<CollectionView BindingContext="{x:Reference shell}" ItemsSource="{Binding FlyoutItems}" IsGrouped="True">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="40,*" Padding="10">
<Image Source="{Binding Icon}"></Image>
<Label Grid.Column="1" Text="{Binding Title}" TextColor="Black"></Label>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Shell.FlyoutContent>
</Shell>

TabbedPage renders multiple times in Xamarin Forms using shell

I have a problem using TabbedPages in my Xamarin.Forms mobile app (Shell).
When I navigate to a TabbedPage containing 3 tabs, the 3 tabs are crunched up and repeating themselves all down the page.
To replicate it I:
Created a standard Xamarin Forms Shell app in Visual Studio 2019 Version 16.4.5
Upgraded to Xamarin Forms 4.4.0.991640
Added a TabbedPage and changed the navigation of the About button to navigate to the TabbedPage instead.
Here is a photo of how it looks on my android phone
If I remember correctly it also happened when I deployed to my iPhone.
Update due to Jason's comment
All the code is automatically generated by Microsoft, my only interaction was to add an empty TabbedPage and change a line of code in AppShell.xaml.
(Note - while not relevant to this particular demo, I also got the same issue when navigating from a ListView in a ContentPage in my Xamarin.Forms app.)
Added TabbedPage1.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="App1.Views.TabbedPage1">
<!--Pages can be added as references or inline-->
<ContentPage Title="Tab 1" />
<ContentPage Title="Tab 2" />
<ContentPage Title="Tab 3" />
</TabbedPage>
Added TabbedPage1.xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace App1.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TabbedPage1 : TabbedPage
{
public TabbedPage1()
{
InitializeComponent();
}
}
}
Amended AppShell.xaml (all I did was change the line from DataTemplate local:AboutPage to DataTemplate local:TabbedPage1):
<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:App1.Views"
Title="App1"
x:Class="App1.AppShell">
<!--
Styles and Resources
-->
<Shell.Resources>
<ResourceDictionary>
<Color x:Key="NavigationPrimary">#2196F3</Color>
<Style x:Key="BaseStyle" TargetType="Element">
<Setter Property="Shell.BackgroundColor" Value="{StaticResource NavigationPrimary}" />
<Setter Property="Shell.ForegroundColor" Value="White" />
<Setter Property="Shell.TitleColor" Value="White" />
<Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
<Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
<Setter Property="Shell.TabBarBackgroundColor" Value="{StaticResource NavigationPrimary}" />
<Setter Property="Shell.TabBarForegroundColor" Value="White"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF"/>
<Setter Property="Shell.TabBarTitleColor" Value="White"/>
</Style>
<Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
</ResourceDictionary>
</Shell.Resources>
<!-- Your Pages -->
<TabBar>
<Tab Title="Browse" Icon="tab_feed.png">
<ShellContent ContentTemplate="{DataTemplate local:ItemsPage}" />
</Tab>
<Tab Title="About" Icon="tab_about.png">
<ShellContent ContentTemplate="{DataTemplate local:TabbedPage1}" />
</Tab>
</TabBar>
<!-- Optional Templates
// These may be provided inline as below or as separate classes.
// This header appears at the top of the Flyout.
<Shell.FlyoutHeaderTemplate>
<DataTemplate>
<Grid>ContentHere</Grid>
</DataTemplate>
</Shell.FlyoutHeaderTemplate>
// ItemTemplate is for ShellItems as displayed in a Flyout
<Shell.ItemTemplate>
<DataTemplate>
<ContentView>
Bindable Properties: Title, Icon
</ContentView>
</DataTemplate>
</Shell.ItemTemplate>
// MenuItemTemplate is for MenuItems as displayed in a Flyout
<Shell.MenuItemTemplate>
<DataTemplate>
<ContentView>
Bindable Properties: Text, Icon
</ContentView>
</DataTemplate>
</Shell.MenuItemTemplate>
-->
</Shell>

Cannot start another activity

I followed the full instructions on http://developer.android.com/training/basics/firstapp/creating-project.html multiple times and have been unable to start an activity. The app basically has a text field and send button. When I enter text in the text field and hit the send button, another activity should be started. However, with my current code, hitting the send button does nothing.
MySecondApp/src/MainActivity.java
package com.example.mysecondapp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends Activity {
public final static String EXTRA_MESSAGE = "com.example.mysecondapp.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}
MySecondApp/src/DisplayMessageActivity.java
package com.example.mysecondapp;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.view.MenuItem;
import android.widget.TextView;
public class DisplayMessageActivity extends Activity {
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the message from the intent
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
// Create the text view
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
// Set the text view as the activity layout
setContentView(textView);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
MySecondApp/res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="horizontal" >
<EditText android:id="#+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="#string/edit_message" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send" />
android:onClick="sendMessage" />
</LinearLayout>
MySecondApp/res/layout/activity_display_message.xml
<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=".DisplayMessageActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</RelativeLayout>
MySecondApp/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Safe\'s First App</string>
<string name="edit_message">Enter a message</string>
<string name="button_send">Send</string>
<string name="action_settings">Settings</string>
<string name="title_activity_main">MainActivity</string>
<string name="title_activity_display_message">My Message</string>
<string name="hello_world">Hello world!</string>
</resources>
MySecondApp/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mysecondapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.mysecondapp.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>
<activity
android:name="com.example.mysecondapp.DisplayMessageActivity"
android:label="#string/title_activity_display_message"
android:parentActivityName="com.example.mysecondapp.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.mysecondapp.MainActivity" />
</activity>
</application>
</manifest>
Your problem is in the xml for your first activity. You have two terminating characters in the Button. Remove the /> after your android:text line.
Change you xml:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send" />
android:onClick="sendMessage" />
to:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
android:onClick="sendMessage" />
And also, I think you should reference your button in the onCreate method.
You can also try to change your code to:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class Main extends Activity {
public final static String EXTRA_MESSAGE = "com.example.mysecondapp.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button yourButton = (Button) findViewById(R.id.yourid);
yourButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Main.this, YourSecondActivity.class);
EditText editText = (EditText) findViewById(R.id.yourEditText);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
And Change your xml from:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send" />
android:onClick="sendMessage" />
To:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send" />
android:onClick="sendMessage" />
See how the last line is black? That's because you ended the button tag twice with />
So take the closing tag away on the second last line: android:text="#string/button_send"
and your code would be:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
android:onClick="sendMessage" />
When locating the onClick property and select sendMessage [MainActivity] from the drop-down list, at .xml file: android:onClick="sendMessage (MainActivity)".
Delete "(MainActivity)":
So, at .xml file: android:onClick="sendMessage"
And run the app again!