In the MvvmCross application, I have a page with the classic chat behavior (WhatsApp like): this page displays the history of messages exchanged between two users, with the last message at the bottom of the list. I have successfully implemented the view in Windows Phone 8.1, but I'm struggling with a problem in Android.
I will give you a brief introduction and description of my problem, and then I will look at the technical details.
Introduction
Actually, my need is to apply different styles to messages sent by different users: it is typical to align left messages sent from another user and align the correct messages sent by me (I do this through a property weight); I need to apply a different background drawableand set a different property gravity. I use custom binding because, AFAIK, these properties cannot be bound to classic binding: it local:MvxBind="Gravity MyPropery"does not work because there is no Gravity property.
So, I have, of course, two axml files:
- the first one contains Mvx.MvxListView
- the second contains an element template for MvxListView
And I created three different user bindings (for background, gravity and weight) in the following manuals:
, , , . , .
, , : , , .
, , : ( , , ), . .
, , .
DEBUG
, , .
public class LinearLayoutWeightTargetBinding : MvxAndroidTargetBinding
{
public static int debugCounter = 0;
public LinearLayoutWeightTargetBinding(object target) : base(target)
{
}
protected LinearLayout MyTarget
{
get { return (LinearLayout)Target; }
}
public override Type TargetType { get { return typeof(bool); } }
protected override void SetValueImpl(object target, object value)
{
var ll = (LinearLayout)target;
var itsMe = (bool)value;
var weight = itsMe ? (float)20.0 : (float)5.0;
var layoutParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WrapContent, weight);
ll.LayoutParameters = layoutParams;
Log.Debug("MeeCHAT", string.Format("LinearLayoutWeightTargetBinding::SetValueImpl::ItsMe:{0} - counter:{1}", itsMe, ++debugCounter));
}
public override MvxBindingMode DefaultMode { get {return MvxBindingMode.TwoWay;} }
}
, , (debugCounter ).
, , , 10 , , . , 10 , ( ), .
, . .
, http://gregshackles.com/presenters-in-mvvmcross-navigating-android-with-fragments/ Activity Fragment View; a Presenter ViewModel .
, Mvx.MvxListView,
public class MyMatchersChatView : MvxFragment
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignore = base.OnCreateView(inflater, container, savedInstanceState);
var result = this.BindingInflate(Resource.Layout.MyMatchersChatView, null);
var headerFrame = result.FindViewById<FrameLayout>(Resource.Id.headerFrameMyMatchersChatView);
var headerWidget = new HeaderWidget() { ViewModel = this.ViewModel };
var tran = ChildFragmentManager.BeginTransaction();
tran.Add(headerFrame.Id, headerWidget, "headerMyMatchersChat");
tran.Commit();
var listView = result.FindViewById<MvxListView>(Resource.Id.messagesList);
listView.SetSelection(listView.Adapter.Count - 1);
return result;
}
}
listView.SetSelection(listView.Adapter.Count - 1); .
: axml.
Setup.cs :
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
base.FillTargetFactories(registry);
registry.RegisterFactory(new MvxCustomBindingFactory<LinearLayout>("CustomWeight",
(b) => new LinearLayoutWeightTargetBinding(b)));
}
axml :
<LinearLayout
android:orientation="horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
local:MvxBind="CustomWeight IsCurrentUser">
LISTVIEW VIEWMODEL
ListView
<Mvx.MvxListView
android:id="@+id/messagesList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
local:MvxBind="ItemsSource MyMessages"
local:MvxItemTemplate="@layout/mymatcherschatview_itemtemplate" />
ViewModel
private IEnumerable<MyMatchMessageModel> _myMessages;
public IEnumerable<MyMatchMessageModel> MyMessages
{
get { return _myMessages; }
set
{
_myMessages = value;
RaisePropertyChanged(() => MyMessages);
}
}
, :
- Visual Studio 2015
- MvvmCross 3.5.1
- :.NET Framework 4.5, Windows 8, ASP.NET Core 5.0, Windows Phone 8.1, Xamarin.Android, Xamarin.iOS, Xamarin.iOS().
- Android- API- 19 ( Xamarin.Android v4.4).
- Xamarin 3.11.1450.0
- Xamarin.Android 5.1.6.7
- , - ?
!
→ EDIT 1 <
, stackFromBottom transcriptMode Fragment, , : ( )
axml...
<Mvx.MvxListView
android:id="@+id/messagesList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
local:MvxBind="ItemsSource MyMessages"
local:MvxItemTemplate="@layout/mymatcherschatview_itemtemplate" />
...
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignore = base.OnCreateView(inflater, container, savedInstanceState);
var result = this.BindingInflate(Resource.Layout.MyMatchersChatView, null);
var headerFrame = result.FindViewById<FrameLayout>(Resource.Id.headerFrameMyMatchersChatView);
var headerWidget = new HeaderWidget() { ViewModel = this.ViewModel };
var tran = ChildFragmentManager.BeginTransaction();
tran.Add(headerFrame.Id, headerWidget, "headerMyMatchersChat");
tran.Commit();
return result;
}