/ XAMARIN

Xamarin and Android – Specific Solutions to Specific Problems #4

 

It’s been a while but I’m finally back with another one of my recent discoveries while working with Xamarin and Android. We are at the pointy end of our project so it has been hard to find the time to blog but luckily now that I do have some, I also have a lot of material banked up. Stay tuned…

I have list view inside a scroll view and I want to be able to be able to scroll both depending on which one I am touching.

In order to support devices with small screens, sometimes I resort to lazy man’s responsive design. I wrap the whole layout in a ScrollView element. While this works fine most of the time it does have an interesting time dealing with child elements that are also scrollable. The one I run into the most is the existence of a ListView inside a ScrollView.

Let’s say we have something like the following:

<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fillViewport="true"> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Vegetable Groups" android:textSize="30dp" android:background="#00000000" android:textColor="#FF267F00" android:textStyle="bold" android:padding="5dp" /> <ListView android:id="@+id/List" android:layout_width="fill_parent" android:layout_height="wrap_content" android:cacheColorHint="#FFDAFF7F" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Vegetable Sub Groups" android:textSize="30dp" android:background="#00000000" android:textColor="#FF267F00" android:textStyle="bold" android:padding="5dp" /> <ListView android:id="@+id/List2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:cacheColorHint="#FFDAFF7F" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Vegetable Description" android:textSize="30dp" android:background="#00000000" android:textColor="#FF267F00" android:textStyle="bold" android:padding="5dp" /> </LinearLayout> </ScrollView>

</div>

This will result in a screen that looks something like the following with the bottom list view as the only scrollable element and an inability to scroll down to the bottom TextView showing Vegetable Descriptions.

image

My next attempt to resolve this was to set the list views to a fixed height but the result is a little unexpected. For example if we set the list view heights to 250dp the scroll view will now operate properly but neither of the list views will scroll.

image

Then I found this article which describes the use of the OnTouchListener  to control how the layout scrolls when individual screen elements are touched. As I’m using Xamarin, most of these have been converted to events so I was able to attach a delegate and perform the same strategy as suggested in the article.

protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView(Resource.Layout.HomeScreen); listView = FindViewById<ListView>(Resource.Id.List); listView2 = FindViewById<ListView>(Resource.Id.List2); tableItems.Add(new TableItem() { Heading = "Vegetables", SubHeading = "65 items", ImageResourceId = Resource.Drawable.Vegetables }); tableItems.Add(new TableItem() { Heading = "Fruits", SubHeading = "17 items", ImageResourceId = Resource.Drawable.Fruits }); tableItems.Add(new TableItem() { Heading = "Flower Buds", SubHeading = "5 items", ImageResourceId = Resource.Drawable.FlowerBuds }); tableItems.Add(new TableItem() { Heading = "Legumes", SubHeading = "33 items", ImageResourceId = Resource.Drawable.Legumes }); tableItems.Add(new TableItem() { Heading = "Bulbs", SubHeading = "18 items", ImageResourceId = Resource.Drawable.Bulbs }); listView.Adapter = new HomeScreenAdapter(this, tableItems); listView2.Adapter = new HomeScreenAdapter(this, tableItems); listView.ItemClick += OnListItemClick; listView.Touch += ListViewOnTouch; listView2.Touch += ListViewOnTouch; } private void ListViewOnTouch(object sender, View.TouchEventArgs touchEventArgs) { View view = (View) sender; view.Parent.RequestDisallowInterceptTouchEvent(true); touchEventArgs.Handled = false; }

</div>

This results in a screen that is scrollable when not clicking on the list views while still being able to scroll the list views individually.