我正在开发Xamarin.Android(C#)中的Android应用程序。但是,我确实认为任何Java开发人员也可以回答这个问题。
我是android开发的新手。无论如何,我创建了一个片段,里面只有一个LinearLayout
和一个TextView
。当我为它创建背景类时,我不会从extend
类继承(在JAVA的单词中,Fragment
),而是从LinearLayout
类继承它。
所以,MyFragment.cs
文件的开头是这样的:
public class MyFragment : LinearLayout
相当于JAVA
public class MyFragment extends LinearLayout
(P.S.我对JAVA和它的sytaxes知之甚少)。
无论如何,一切正常。我有一个Initialize
方法(在JAVA,它应该是Init
方法)膨胀片段的视图。从视图来看,它试图用给定的TextView
找到Id
。
所以,代码看起来像这样:
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
如下:
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属性绑定到ViewModel
的GoalTitle
属性时问题开始,如下所示:
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
的视图)并调试应用程序。执行时,我收到以下错误:
无法激活Java类型'md55bfae9a06327fa0fdf207b4f768604b1 / MyFragment'的JNI句柄0xfff02a68(key_handle 0x339790a)作为托管类型'TestApp.MyFragment'。
搜索谷歌,我意识到我试图在视图创建之前绑定属性(如果我错了,请纠正我)。我在其他SO答案中找到的建议要么是将代码放在OnCreateView
方法中,要么以某种方式延迟绑定部分代码的执行。
第一个解决方案对我不起作用,因为LinearLayout
又名View
没有这样的方法OnCreateView
,我可以覆盖。
那么,我该如何将TextView
绑定到ViewModel
呢?而且,我是否正在将片段视为LinearLayout
,因为我正在继承它?
我不熟悉MVVMLIght扩展,但是如果你正在使用一个片段(例如在tablayout中)你应该继承像这样的片段(这是一个v4支持片段):
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;
}
}