Skip to content

Commit

Permalink
Merge pull request #64 from Clancey/mhac/dev
Browse files Browse the repository at this point in the history
RecyclerView and ActionBar
  • Loading branch information
jonlipsky authored Jul 23, 2019
2 parents 4b2feed + cbd27e6 commit 88172ef
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 61 deletions.
2 changes: 1 addition & 1 deletion sample/HotUI.Android.Sample/MainActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

namespace HotUI.Android.Sample
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
[Activity(Label = "@string/app_name", MainLauncher = true)]
public class MainActivity : HotUIActivity
{

Expand Down
2 changes: 2 additions & 0 deletions sample/HotUI.Samples/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public MainPage (List<MenuItem> additionalPage = null)
if (additionalPage != null)
pages.AddRange(additionalPage);

this.Title("UI Samples");

Body = () => new NavigationView
{
new ListView<MenuItem> (pages)
Expand Down
6 changes: 4 additions & 2 deletions src/HotUI.Android/Controls/HotUIFragment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@ namespace HotUI.Android.Controls
public class HotUIFragment : Fragment
{
private readonly View view;
public string Title { get; }

public HotUIFragment(View view)
{
this.view = view;

this.Title = view?.GetEnvironment<string>(EnvironmentKeys.View.Title) ?? "";
}
AView currentBuiltView;
public override AView OnCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) => currentBuiltView = view.ToView(false);
public override void OnDestroy()
{
if(view != null)
if (view != null)
{
view.ViewHandler = null;
}
Expand Down
117 changes: 66 additions & 51 deletions src/HotUI.Android/Handlers/ListViewHandler.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,25 @@
using System;
using Android.Views;
using Android.Widget;
using Android.Support.V7.Widget;
using AView = Android.Views.View;
using AListView = Android.Widget.ListView;
using HotUI.Android.Controls;

namespace HotUI.Android.Handlers
{
public class ListViewHandler : AListView, AndroidViewHandler
public class ListViewHandler : RecyclerView, AndroidViewHandler
{
public event EventHandler<ViewChangedEventArgs> NativeViewChanged;

public ListViewHandler() : base(AndroidContext.CurrentContext)
{
this.Adapter = new ListViewAdapter();
this.ItemSelected += ListViewHandler_ItemSelected;
this.ItemClick += ListViewHandler_ItemClick;
}
var layoutManager = new LinearLayoutManager(this.Context);

private void ListViewHandler_ItemClick(object sender, ItemClickEventArgs e)
{
//TODO: Account for Section
((ListViewAdapter) this.Adapter).ListView?.OnSelected(0,e.Position);
SetLayoutManager(layoutManager);
this.SetAdapter(new RecyclerViewAdapter());
this.AddItemDecoration(new DividerItemDecoration(Context, layoutManager.Orientation));
}

private void ListViewHandler_ItemSelected(object sender, ItemSelectedEventArgs e)
{
//TODO: Account for Section
((ListViewAdapter) this.Adapter).ListView?.OnSelected(0,e.Position);
}

public AView View => this;
public object NativeView => View;
public bool HasContainer { get; set; } = false;
Expand All @@ -53,65 +43,90 @@ public void Remove(View view)

public void SetView(View view)
{
((ListViewAdapter) this.Adapter).ListView = view as ListView;
((RecyclerViewAdapter)this.GetAdapter()).ListView = view as ListView;
ViewHandler.AddGestures(this, view);
}

public void UpdateValue(string property, object value)
{
if(nameof(ListView.ReloadData) == property)
switch (property)
{
(this.Adapter as ListViewAdapter)?.NotifyDataSetChanged();
}
else if (property == Gesture.AddGestureProperty)
{
ViewHandler.AddGesture(this, (Gesture)value);
}
else if (property == Gesture.RemoveGestureProperty)
{
ViewHandler.RemoveGesture(this, (Gesture)value);
case nameof(ListView.ReloadData):
((RecyclerViewAdapter)this.GetAdapter()).NotifyDataSetChanged();
break;
case Gesture.AddGestureProperty:
ViewHandler.AddGesture(this, (Gesture)value);
break;
case Gesture.RemoveGestureProperty:
ViewHandler.RemoveGesture(this, (Gesture)value);
break;
}
}

class ListViewAdapter : BaseAdapter<object>
class RecyclerViewAdapter : Adapter
{
public IListView ListView { get; set; }
//TODO: Account for Section
public override object this[int position] => ListView?.ViewFor(0,position);

//TODO: Account for Section
public override int Count => ListView?.Rows(0) ?? 0;

public override long GetItemId(int position) => position;
public override int ItemCount => ListView?.Rows(0) ?? 0;

public override AView GetView(int position, AView convertView, ViewGroup parent)
public override void OnBindViewHolder(ViewHolder holder, int position)
{
var rvh = holder as RecyclerViewHolder;

//TODO: Account for Section
var view = ListView?.ViewFor(0,position);
var view = ListView?.ViewFor(0, position);
var cell = view?.ToView();

var displayMetrics = parent.Context.Resources.DisplayMetrics;
var density = displayMetrics.Density;

var scaledSize = new SizeF(parent.Width / density, parent.Height / density);
var measuredSize = view.Measure(scaledSize);
view.MeasuredSize = measuredSize;
view.MeasurementValid = true;
if (rvh != null && cell != null)
{
var parent = rvh.Parent;

cell.LayoutParameters = new ViewGroup.LayoutParams(parent.Width, (int)(measuredSize.Height* density));
cell.SetMinimumHeight((int)(measuredSize.Height * density));
var displayMetrics = parent.Context.Resources.DisplayMetrics;
var density = displayMetrics.Density;

return cell;
var scaledSize = new SizeF(parent.Width / density, parent.Height / density);
var measuredSize = view.Measure(scaledSize);
view.MeasuredSize = measuredSize;
view.MeasurementValid = true;

cell.LayoutParameters = new ViewGroup.LayoutParams(parent.Width, (int)(measuredSize.Height * density));
cell.SetMinimumHeight((int)(measuredSize.Height * density));

rvh.Container.RemoveAllViews();
// cell may sometimes have a parent already
(cell.Parent as FrameLayout)?.RemoveView(cell);
rvh.Container.AddView(cell);
}
}

public override ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
return new RecyclerViewHolder(new FrameLayout(parent.Context), parent, ListView);
}
}

protected override void Dispose(bool disposing)
public class RecyclerViewHolder : ViewHolder
{
if (!disposing)
return;
this.ItemSelected -= ListViewHandler_ItemSelected;
this.ItemClick -= ListViewHandler_ItemClick;
base.Dispose(disposing);
private readonly IListView listView;

public FrameLayout Container { get; }
public ViewGroup Parent { get; }

public RecyclerViewHolder(FrameLayout itemView, ViewGroup parent, IListView listView)
: base(itemView)
{
Container = itemView;
Parent = parent;
this.listView = listView;

Container.Click += HandleClick;
}

private void HandleClick(object sender, EventArgs e)
{
listView?.OnSelected(0, this.AdapterPosition);
}
}
}
}
10 changes: 6 additions & 4 deletions src/HotUI.Android/HotUI.Android.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
<Reference Include="Xamarin.Android.Support.v7.AppCompat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
<HintPath>..\..\..\..\..\..\Users\jlipsky\.nuget\packages\xamarin.android.support.v7.appcompat\28.0.0.1\lib\monoandroid90\Xamarin.Android.Support.v7.AppCompat.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AndroidContext.cs" />
Expand Down Expand Up @@ -106,9 +103,14 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat" Version="28.0.0.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.2.0" />
<PackageReference Include="Xamarin.FFImageLoading" Version="2.4.11.982" />
<PackageReference Include="Xamarin.Android.Support.v7.AppCompat">
<Version>28.0.0.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.Android.Support.v7.RecyclerView">
<Version>28.0.0.1</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand Down
35 changes: 32 additions & 3 deletions src/HotUI.Android/HotUIActivity.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using Android.App;
using System.Linq;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using AView = Android.Views.View;
using HotUI.Android.Controls;
using static Android.Support.V4.App.FragmentManager;

namespace HotUI.Android
{
public abstract class HotUIActivity : AppCompatActivity
public abstract class HotUIActivity : AppCompatActivity, IOnBackStackChangedListener

{
private View _page;

Expand All @@ -17,6 +19,11 @@ public View Page
{
_page = value;
SetContentView(_page?.ToView());

if (SupportActionBar != null)
{
SupportActionBar.Title = value?.GetEnvironment<string>(EnvironmentKeys.View.Title) ?? "";
}
}
}

Expand All @@ -25,12 +32,34 @@ protected override void OnCreate(Bundle savedInstanceState)
base.OnCreate(savedInstanceState);
AndroidContext.CurrentContext = this;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);

SupportFragmentManager.AddOnBackStackChangedListener(this);
}

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] global::Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

public override bool OnSupportNavigateUp()
{
if (SupportFragmentManager.BackStackEntryCount > 0)
{
SupportFragmentManager.PopBackStack();
}

return base.OnSupportNavigateUp();
}

public void OnBackStackChanged()
{
SupportActionBar?.SetDisplayHomeAsUpEnabled(SupportFragmentManager.BackStackEntryCount > 0);

if (SupportFragmentManager.Fragments.Last() is HotUIFragment fragment && SupportActionBar != null)
{
SupportActionBar.Title = fragment.Title;
}
}
}
}

0 comments on commit 88172ef

Please sign in to comment.