Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
Fixed ScrollView Visibility on Android (#10659) fixes #8015 fixes #9103
Browse files Browse the repository at this point in the history
Co-authored-by: Samantha Houts <samhouts@users.noreply.github.com>
  • Loading branch information
jsuarezruiz and samhouts authored Sep 10, 2020
1 parent 0bb52af commit 7483a99
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 74 deletions.
154 changes: 84 additions & 70 deletions Xamarin.Forms.Controls/GalleryPages/ScrollGallery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,112 +11,121 @@ public class ScrollGallery : ContentPage
readonly ScrollView _scrollview;
readonly StackLayout _stack;
ScrollOrientation _orientation;
List<Button> _buttons = new List<Button> ();
List<Button> _buttons = new List<Button>();
Button _toNavigateTo;
public ScrollGallery (ScrollOrientation orientation = ScrollOrientation.Vertical)
public ScrollGallery(ScrollOrientation orientation = ScrollOrientation.Vertical)
{
_orientation = orientation;
var root = new Grid ();
root.RowDefinitions.Add (new RowDefinition () { Height = GridLength.Auto });
root.RowDefinitions.Add (new RowDefinition () { Height = GridLength.Auto });
root.RowDefinitions.Add (new RowDefinition () { Height = GridLength.Auto });
root.RowDefinitions.Add (new RowDefinition ());
var root = new Grid();
root.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
root.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
root.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
root.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
root.RowDefinitions.Add(new RowDefinition());

var btnStack1 = new StackLayout { Orientation = StackOrientation.Horizontal };
var btnStack = new StackLayout { Orientation = StackOrientation.Horizontal };
var btnStack2 = new StackLayout { Orientation = StackOrientation.Horizontal };
var btnStack3 = new StackLayout { Orientation = StackOrientation.Horizontal };

var btn = new Button { Text = "Scroll to 100" };
var btn4 = new Button { Text = "Scroll to 100 no anim" };
var btn1 = new Button { Text = "Start" };
var btn2 = new Button { Text = "Center" };
var btn3 = new Button { Text = "End" };
var btn7 = new Button { Text = "Toggle Scroll Bar Visibility" };
var btn6 = new Button { Text = "MakeVisible", HorizontalOptions= LayoutOptions.CenterAndExpand, BackgroundColor = Color.Accent };
var btn8 = new Button { Text = "Toggle Orientation" };
var btn9 = new Button { Text = "Default Scroll Bar Visibility" };
var btn7 = new Button { Text = "Toggle Scroll Bar Visibility", WidthRequest = 120 };
var btn6 = new Button { Text = "MakeVisible", HorizontalOptions = LayoutOptions.CenterAndExpand, BackgroundColor = Color.Accent };
var btn8 = new Button { Text = "Toggle Orientation", WidthRequest = 120 };
var btn9 = new Button { Text = "Default Scroll Bar Visibility", WidthRequest = 120 };

var labelStack = new StackLayout { Orientation = StackOrientation.Horizontal };
var label = new Label { Text = string.Format ("X: {0}, Y: {1}", 0, 0) };
var label = new Label { Text = string.Format("X: {0}, Y: {1}", 0, 0) };
var scrollStatusLabel = new Label { Text = string.Empty };

root.Children.Add (labelStack);
root.Children.Add (btnStack);
root.Children.Add (btnStack1);

btnStack.Children.Add (btn1);
btnStack.Children.Add (btn2);
btnStack.Children.Add (btn3);
btnStack.Children.Add(btn7);
btnStack.Children.Add(btn9);
btnStack.Children.Add(btn8);
root.Children.Add(labelStack);
root.Children.Add(btnStack1);
root.Children.Add(btnStack2);
root.Children.Add(btnStack3);

btnStack1.Children.Add(btn1);
btnStack1.Children.Add(btn2);
btnStack1.Children.Add(btn3);

btnStack2.Children.Add(btn);
btnStack2.Children.Add(btn4);

btnStack1.Children.Add (btn);
btnStack1.Children.Add (btn4);
btnStack3.Children.Add(btn7);
btnStack3.Children.Add(btn9);
btnStack3.Children.Add(btn8);

labelStack.Children.Add(label);
labelStack.Children.Add(scrollStatusLabel);

Grid.SetRow (btnStack, 1);
Grid.SetRow (btnStack1, 2);

var grid = new Grid ();
grid.RowDefinitions.Add (new RowDefinition { Height = GridLength.Auto });
grid.RowDefinitions.Add (new RowDefinition ());
_stack = new StackLayout ();
Grid.SetRow (_stack, 1);
grid.Children.Add (btn6);
grid.Children.Add (_stack);
_scrollview = new ScrollView {
AutomationId="thescroller",
Grid.SetRow(btnStack1, 1);
Grid.SetRow(btnStack2, 2);
Grid.SetRow(btnStack3, 3);

var grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
grid.RowDefinitions.Add(new RowDefinition());
_stack = new StackLayout();
Grid.SetRow(_stack, 1);
grid.Children.Add(btn6);
grid.Children.Add(_stack);
_scrollview = new ScrollView
{
AutomationId = "thescroller",
BackgroundColor = Color.Aqua,
Content = grid
};
root.Children.Add (_scrollview);
Grid.SetRow (_scrollview, 3);
root.Children.Add(_scrollview);
Grid.SetRow(_scrollview, 4);

_scrollview.Scrolled+= (object sender, ScrolledEventArgs e) => {
label.Text = string.Format ("X: {0}, Y: {1}", e.ScrollX, e.ScrollY);
_scrollview.Scrolled += (object sender, ScrolledEventArgs e) => {
label.Text = string.Format("X: {0}, Y: {1}", e.ScrollX, e.ScrollY);
};

btn.Clicked += async (object sender, EventArgs e) => {
scrollStatusLabel.Text = "scrolling";
switch (orientation) {
switch (orientation)
{
case ScrollOrientation.Horizontal:
await _scrollview.ScrollToAsync (100, 0, true);
await _scrollview.ScrollToAsync(100, 0, true);
break;
case ScrollOrientation.Vertical:
await _scrollview.ScrollToAsync (0, 100, true);
await _scrollview.ScrollToAsync(0, 100, true);
break;
case ScrollOrientation.Both:
await _scrollview.ScrollToAsync (100, 100, true);
await _scrollview.ScrollToAsync(100, 100, true);
break;
}
scrollStatusLabel.Text = "completed";
};
btn4.Clicked += async (object sender, EventArgs e) => {
switch (orientation) {
switch (orientation)
{
case ScrollOrientation.Horizontal:
await _scrollview.ScrollToAsync (100, 0, false);
await _scrollview.ScrollToAsync(100, 0, false);
break;
case ScrollOrientation.Vertical:
await _scrollview.ScrollToAsync (0, 100, false);
await _scrollview.ScrollToAsync(0, 100, false);
break;
case ScrollOrientation.Both:
await _scrollview.ScrollToAsync (100, 100, true);
await _scrollview.ScrollToAsync(100, 100, true);
break;
}
};

btn1.Clicked += async (object sender, EventArgs e) => {
await _scrollview.ScrollToAsync (_toNavigateTo, ScrollToPosition.Start, true);
await _scrollview.ScrollToAsync(_toNavigateTo, ScrollToPosition.Start, true);
};
btn2.Clicked += async (object sender, EventArgs e) => {
await _scrollview.ScrollToAsync (_toNavigateTo, ScrollToPosition.Center, true);
await _scrollview.ScrollToAsync(_toNavigateTo, ScrollToPosition.Center, true);
};
btn3.Clicked += async (object sender, EventArgs e) => {
await _scrollview.ScrollToAsync (_toNavigateTo, ScrollToPosition.End, true);
await _scrollview.ScrollToAsync(_toNavigateTo, ScrollToPosition.End, true);
};
btn6.Clicked += async (object sender, EventArgs e) => {
await _scrollview.ScrollToAsync (_toNavigateTo, ScrollToPosition.MakeVisible, true);
await _scrollview.ScrollToAsync(_toNavigateTo, ScrollToPosition.MakeVisible, true);
};
btn7.Clicked += (object sender, EventArgs e) =>
{
Expand Down Expand Up @@ -151,53 +160,58 @@ public ScrollGallery (ScrollOrientation orientation = ScrollOrientation.Vertical
_scrollview.HorizontalScrollBarVisibility = ScrollBarVisibility.Default;
};

_stack.Padding = new Size (20, 60);
_stack.Padding = new Size(20, 60);

PopulateStack (_stack);
PopulateStack(_stack);

_scrollview.Orientation = _orientation;

if (orientation == ScrollOrientation.Horizontal || orientation == ScrollOrientation.Both) {
if (orientation == ScrollOrientation.Horizontal || orientation == ScrollOrientation.Both)
{
_stack.Orientation = StackOrientation.Horizontal;
}

if (orientation == ScrollOrientation.Both) {
var stack2 = new StackLayout ();
PopulateStack (stack2);
_stack.Children.Add (stack2);
if (orientation == ScrollOrientation.Both)
{
var stack2 = new StackLayout();
PopulateStack(stack2);
_stack.Children.Add(stack2);
}

Content = root;
}

void PopulateStack (StackLayout stack)
void PopulateStack(StackLayout stack)
{
for (int i = 0; i < 100; i++) {
for (int i = 0; i < 100; i++)
{

var newButton = new Button { Text = "Foo Bar", AutomationId =string.Format ("btn_{0}", i) };
var newButton = new Button { Text = "Foo Bar", AutomationId = string.Format("btn_{0}", i) };
if (i == 49)
newButton.Text = "the before";

if (i == 50) {
if (i == 50)
{
newButton.Text = "the scrollto button";
newButton.BackgroundColor = Color.Yellow;
newButton.TextColor = Color.Black;
_toNavigateTo = newButton;
}
if (i == 51)
newButton.Text = "the after";
if (i == 53) {
if (i == 53)
{
newButton.Text = "the make visible from start";
newButton.Clicked += async (object sender, EventArgs e) => {
await _scrollview.ScrollToAsync (_toNavigateTo, ScrollToPosition.MakeVisible, true);
await _scrollview.ScrollToAsync(_toNavigateTo, ScrollToPosition.MakeVisible, true);
};
}

_buttons.Add (newButton);
stack.Children.Add (newButton);
_buttons.Add(newButton);
stack.Children.Add(newButton);
}

stack.Children.Add (new Button { Text = "Foo Bottom" });
stack.Children.Add(new Button { Text = "Foo Bottom" });
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public class ScrollViewRenderer : NestedScrollView, IVisualElementRenderer, IEff
LayoutDirection _prevLayoutDirection = LayoutDirection.Ltr;
bool _checkedForRtlScroll = false;

public ScrollViewRenderer(Context context) : base(context)
public ScrollViewRenderer(Context context) : base(
new ContextThemeWrapper(context, Resource.Style.scrollViewTheme), null,
Resource.Attribute.scrollViewStyle)
{
}

Expand Down
4 changes: 4 additions & 0 deletions Xamarin.Forms.Platform.Android/Resources/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@
<attr name="collectionViewStyle" format="reference"/>
</declare-styleable>

<declare-styleable name="ScrollViewRendererTheme">
<attr name="scrollViewStyle" format="reference"/>
</declare-styleable>

</resources>
9 changes: 6 additions & 3 deletions Xamarin.Forms.Platform.Android/Resources/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@
attribute defined in attrs.xml), we can apply the collectionViewScrollBars style explicitly to the renderer we are
creating (and avoid forcing every child control to have scrollbars).
-->

<style name="collectionViewScrollBars">
<style name="scrollViewScrollBars">
<item name="android:scrollbars">vertical|horizontal</item>
</style>

<style name="collectionViewTheme">
<item name="collectionViewStyle">@style/collectionViewScrollBars</item>
<item name="collectionViewStyle">@style/scrollViewScrollBars</item>
</style>

<style name="scrollViewTheme">
<item name="scrollViewStyle">@style/scrollViewScrollBars</item>
</style>

<style name="MainTheme" parent="MainTheme.Base">
Expand Down

0 comments on commit 7483a99

Please sign in to comment.