Android DataBinding-如何绑定ViewGroup的属性 [英] Android DataBinding - How to Bind A ViewGroup's Properties

查看:235
本文介绍了Android DataBinding-如何绑定ViewGroup的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Xamarin.Android(C#)中开发一个Android应用程序.但是,我确实认为任何Java开发人员也可以回答这个问题.

I am developing an Android app in Xamarin.Android(C#). However, i do feel that this question can also be answered by any Java devs as well.

我是android开发的新手.无论如何,我创建了一个片段,里面只有一个LinearLayout和一个TextView.当我为它创建背景类时,我不是从Fragment类继承(以JAVA的话为extend),而是从LinearLayout类继承.

I am new in android development. Anyways, i created a fragment with just a LinearLayout and a TextView inside it. When i create the background class for it, i don't inherit(on in JAVA's word, extend) it from the Fragment class but rather from the LinearLayout class.

因此,MyFragment.cs文件开始如下:

public class MyFragment : LinearLayout

相当于JAVA的

public class MyFragment extends LinearLayout

(请注意,我对JAVA及其语法的了解有限).

(P.S. I have limited knowledge of JAVA and it's sytaxes).

无论如何,一切正常.我有一个Initialize方法(在JAVA中,它应该是Init方法),可以扩大片段的视图.从视图中,它尝试查找具有给定IdTextView.

Anyways, all works fine. I have an Initialize method(In JAVA, it should be the Init method) which inflates the view of the fragment. From the view, it tries to find the TextView with the given Id.

所以,代码看起来像这样:

So, the codes looks like this :

public class MyFragment : LinearLayout
{
 Context mContext;
  private void Initialize(Context ctx)
  {
        //Inflating the layout
        mContext = ctx;
        var inflatorService = (LayoutInflater)ctx.GetSystemService(Context.LayoutInflaterService);
        View v = inflatorService.Inflate(Resource.Layout.MyFragmentView, this, false);
        this.AddView(v);
        GoalHeader = v.FindViewById<TextView>(Resource.Id.GoalHeader);
  }

到目前为止,一切都很好.然后,我使用MVVMLight库继续实现MVVM模式.我创建一个ViewModel,如下所示:

All works pretty well this far. I then go on implementing the MVVM pattern, using MVVMLight library. I create a ViewModel as follows :

 public class Vm_MyFragment : ViewModelBase
{
    private string _goaltitle = "";
    public string GoalTitle
    {
        get { return _goaltitle; }
        set { Set(ref _goaltitle, value); }
    }
    public void SetTest()
    {
        DispatcherHelper.CheckBeginInvokeOnUI(() =>
        {
            GoalTitle = "Test";
        });
    }
}

仍然,一切都很好.当我尝试将TextView的text属性绑定到ViewModelGoalTitle属性时,问题开始,如下所示:

Still, everything's good. The problem starts when i try to bind the TextView's text property to the ViewModel's GoalTitle property, as follows :

 private readonly List<Binding> _bindings = new List<Binding>();

 private void Initialize(Context ctx)
    {
        //Inflating the layout
        mContext = ctx;
        var inflatorService = (LayoutInflater)ctx.GetSystemService(Context.LayoutInflaterService);
        View v = inflatorService.Inflate(Resource.Layout.MyFragmentView, this, false);
        this.AddView(v);
        Vm_MyFragmentView viewmodel = new Vm_MyFragmentView();
        GoalHeader = v.FindViewById<TextView>(Resource.Id.GoalHeader);
        _bindings.Add(
            this.SetBinding(
                () => mainViewModel.GoalTitle,
                () => GoalHeader.Text));
    }

注意:Binding来自GalaSoft.MvvmLight.Helpers命名空间.

我将片段添加到主视图(我的意思是MainActivity的视图)中,然后调试应用程序.执行后,出现以下错误:

I add the fragment in my main view(I mean, MainActivity's view) and debug the app. Upon execution, i get the following error :

无法将Java类型'md55bfae9a06327fa0fdf207b4f768604b1/MyFragment'的Java类型的JNI句柄0xfff02a68(key_handle 0x339790a)激活为托管类型'TestApp.MyFragment'.

Could not activate JNI Handle 0xfff02a68 (key_handle 0x339790a) of Java type 'md55bfae9a06327fa0fdf207b4f768604b1/MyFragment' as managed type 'TestApp.MyFragment'.

在搜索google时,我意识到我想在视图创建之前就绑定属性(如果我错了,请更正我).我在其他SO答案中发现的建议是将代码放入OnCreateView方法中,或者以某种方式延迟了绑定部分的代码的执行.

Searching google, i realized that i am trying to bind the property before the view is even created(correct me if i'm wrong). The suggestions i found on other SO answers were either to put the code in the OnCreateView method or somehow delay the execution of the binding part's code.

第一个解决方案对我不起作用,因为LinearLayout aka View没有这样的方法OnCreateView我可以覆盖.

The first solution didn't work for me as LinearLayout aka a View doesn't have such a method OnCreateView which i can override.

那么,我该如何将TextView绑定到ViewModel呢?而且,在将片段作为LinearLayout继承时,我是否处于正确的轨道上?

So, how am i supposed to bind the TextView to the ViewModel then? And also, am i on the right track on treating the fragment as a LinearLayout as i am inheriting from it?

推荐答案

我对MVVMLIght扩展名不熟悉,但是如果您按预期使用片段(即在TabLayout中),则应该从这样的片段继承(这是v4支持片段):

Im not familiar with MVVMLIght extension but if you are using a fragment as it is supposed to (ie. in a tablayout) you should inherit from a fragment like this (This is a v4 support fragment):

public class CategoryFragment : SupportFragment {
RecyclerView _recyclerView;
private View _view;

public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    _view = inflater.Inflate (Resource.Layout._CategoryLayout, container, false);

    // Get our RecyclerView layout:
    _recyclerView = _view.FindViewById<RecyclerView> (Resource.Id.categoryRecyclerView);

    // Instantiate the layout manager
    var linearLayoutManager = new LinearLayoutManager (Context, LinearLayoutManager.Vertical, false);
    _recyclerView.SetLayoutManager (linearLayoutManager);

    // Instantiate the adapter and pass in its data source:
    _adapter = new CategoryAdapter (_categories);
    //Register the item click handler with the adapter:
    _adapter.ItemClick += OnItemClick;
    // Plug the adapter into the RecyclerView:
    _recyclerView.SetAdapter (_adapter);
    return _view;
}

}

这篇关于Android DataBinding-如何绑定ViewGroup的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆