Ryan Buening
Ryan Buening

Reputation: 1670

How to use ScrollView from Xamarin on Android

My XAML content is below. My issue is when I tap into an Entry field to enter some text, the onscreen keyboard appears but I'm not able to scroll the view on Android. The view does scroll on iOS.

Is there something I'm doing wrong or is this a bug? I'm using Xamarin.Forms 4.2.0.848062

I've tried commenting out the <Grid> but that didn't seem to help either.

<ContentPage
    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">

    <ContentPage.Content>
        <ScrollView>
            <StackLayout>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="250" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Grid>
                        <Image
                            x:Name="imageToUpload"
                            Grid.Row="0"
                            Aspect="AspectFill"
                            HorizontalOptions="FillAndExpand"
                            VerticalOptions="FillAndExpand" />
                        <Image Grid.Row="0" IsVisible="{Binding HasImage, Converter={StaticResource InverseBoolConverter}}">
                            <Image.GestureRecognizers>
                                <TapGestureRecognizer NumberOfTapsRequired="1" Tapped="OnPhotoImageTap" />
                            </Image.GestureRecognizers>
                            <Image.Source>
                                <FontImageSource
                                    FontFamily="{DynamicResource MaterialFontFamily}"
                                    Glyph="{StaticResource ImagePlusIcon}"
                                    Size="200" />
                            </Image.Source>
                        </Image>
                    </Grid>
                </Grid>

                <Entry
                    x:Name="Description"
                    Margin="30,20,30,0"
                    FontFamily="{StaticResource RegularFont}"
                    IsVisible="{Binding HasImage}"
                    Placeholder="{Binding DescriptionEntryPlaceholder}"
                    Text="{Binding Upload.Comment}" />

                <Grid
                    Margin="25,0,30,0"
                    HorizontalOptions="FillAndExpand"
                    IsVisible="{Binding HasImage}"
                    VerticalOptions="Start">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0.1*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <CheckBox
                        x:Name="EmailPhoto"
                        Grid.Row="0"
                        Grid.Column="0"
                        IsChecked="{Binding EmailPhoto}"
                        VerticalOptions="Center" />
                    <Label
                        Grid.Row="0"
                        Grid.Column="1"
                        FontFamily="{StaticResource RegularFont}"
                        FontSize="14"
                        Text="Email Photo"
                        VerticalOptions="Center" />
                </Grid>

                <Entry
                    x:Name="EmailAddressEntry"
                    Margin="30,0,30,20"
                    FontFamily="{StaticResource RegularFont}"
                    IsVisible="{Binding EmailPhoto}"
                    Keyboard="Email"
                    Placeholder="Email Address"
                    Text="{Binding Upload.EmailPhotoAddress}" />

                <Button
                    Grid.Row="4"
                    Grid.Column="1"
                    Clicked="OnSubmitClicked"
                    FontFamily="{StaticResource RegularFont}"
                    IsVisible="{Binding HasImage}"
                    Text="Submit Photo" />
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>
</ContentPage>

Upvotes: 0

Views: 88

Answers (1)

Leo Zhu
Leo Zhu

Reputation: 15021

it seems the issue of Android,you could try to add this below MainActivity LoadApplication(new App()); :

Xamarin.Forms.Application.Current.On<Xamarin.Forms.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);

Another way we need to implement a workaround named AndroidBug5497Workaround like :

public class AndroidBug5497WorkaroundForXamarinAndroid

{

// For more information, see https://code.google.com/p/android/issues/detail?id=5497
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

// CREDIT TO Joseph Johnson (http://stackoverflow.com/users/341631/joseph-johnson) for publishing the original Android solution on stackoverflow.com

public static void assistActivity(Activity activity)
{
    new AndroidBug5497WorkaroundForXamarinAndroid(activity);
}

private Android.Views.View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;

private AndroidBug5497WorkaroundForXamarinAndroid(Activity activity)
{
    FrameLayout content = (FrameLayout)activity.FindViewById(Android.Resource.Id.Content);
    mChildOfContent = content.GetChildAt(0);
    ViewTreeObserver vto = mChildOfContent.ViewTreeObserver;
    vto.GlobalLayout += (object sender, EventArgs e) => {
                         possiblyResizeChildOfContent();
                         };
    frameLayoutParams = (FrameLayout.LayoutParams)mChildOfContent.LayoutParameters;
}

private void possiblyResizeChildOfContent()
{
    int usableHeightNow = computeUsableHeight();
    if (usableHeightNow != usableHeightPrevious)
    {
        int usableHeightSansKeyboard = mChildOfContent.RootView.Height;
        int heightDifference = usableHeightSansKeyboard - usableHeightNow;

        frameLayoutParams.Height = usableHeightSansKeyboard - heightDifference;

        mChildOfContent.RequestLayout();
        usableHeightPrevious = usableHeightNow;
    }
}

private int computeUsableHeight()
  {
    Rect r = new Rect();
    mChildOfContent.GetWindowVisibleDisplayFrame(r);
    return (r.Bottom - r.Top);
  }
}

you could refer to here

Upvotes: 1

Related Questions