Я унаследовал некоторый код, который требует изменения в том, как он работает.Оригинальный способ не обладал необходимой гибкостью.
Приложение является генератором форм и, следовательно, должно создавать пользовательский интерфейс по требованию.Это родной Xamarin, а не формы Xamarin.
FrameLayout для каждого вопроса формы создается программно, добавляется в представление, затем к этому FrameLayout добавляется фрагмент.Все это происходит ПОСЛЕ OnCreateView после загрузки пользовательского интерфейса для отображения круга выполнения.
После проработки нескольких исключений я застрял с исключением
Java.Lang.IllegalArgumentException: No view found for id 0x50 (unknown) for fragment UploadFragment{a31e878 #7 id=0x50 upload_80}
Я предполагаю, что FrameLayout не существует, когда фрагмент пытается отображаться.
Исключение возникает после запуска метода OnCreate()
после завершения OnCreateView()
.
Мне не удалось найти ни одного прецедента кода для программного добавления FrameLayouts с фрагментами.
Фрагмент кода
frame = new FrameLayout(this.Context);
frame.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent);
upload = new Widgets.UploadFragment(control, binding, Inflater, a, xFormInstance);
MainFormLayout.AddView(frame);
frame.Id = control.id;
fragmentTx.Add(frame.Id, upload, $"upload_{control.id}");
fragmentTx.Commit();
Буду признателен за любой совет.Спасибо.
Расширенное объяснение
Это может быть немного много для всего, что он делает, но постараюсь и приложу столько, сколько смогу.Иерархия страницы:
Activity -> FormFragment -> UploadFragment
Таким образом, родительский элемент UploadFragment также является фрагментом, а не Activity.
Загрузить фрагмент
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout>
<LinearLayout>
<TextView/>
<ImageButton/>
</LinearLayout>
<ImageView/>
</RelativeLayout>
</LinearLayout>
КОД
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
_inflater = inflater;
v = _inflater.Inflate(Resource.Layout.BindImageInput, container, false);
SetUpload();
return v;
//return base.OnCreateView(inflater, container, savedInstanceState);
}
SetUpload()
Устанавливает значения метки, события для кнопок иизображение (если существует) для изображения.Он также имеет дело с несколькими дополнительными событиями, связанными с обработкой событий формы.Остановка работы SetUpload()
по-прежнему вызывает исключение.
FormFragment
<RelativeLayout>
<TextView />
<View />
<ScrollView>
<LinearLayout />
</ScrollView>
</RelativeLayout>
CODE
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
ShowLoading();
View v = inflater.Inflate(Resource.Layout.Form2, container, false);
MainFormLayout = v.FindViewById<LinearLayout>(Resource.Id.mainFormView);
MainScrollView = v.FindViewById<ScrollView>(Resource.Id.mainScrollView);
formBuilderWorker = new BackgroundWorker();
return v;
}
OnResume()
Вызывает методгде formBuilderWorker.DoWork()
существует
formBuilderWorker.DoWork += delegate
{
Form.LoadForm(null, this, FormInstance);
}
LoadForm()
использует интерфейс, чтобы сообщить FormFragment
об отображении элемента управления.Одним из них является UploadFragment.
public void AddControl(Controls control, int? sectionID)
{
///CODE REMOVED FOR OTHER CONTROL TYPES (they still use old codebase)
Bindings binding = XForm.GetBindingForControl(control, FormInstance);
try
{
// Create a new fragment and a transaction.
FragmentTransaction fragmentTx = this.FragmentManager.BeginTransaction();
FrameLayout frame = null;
Widgets.UploadFragment upload = null;
frame = new FrameLayout(this.Context);
frame.LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent);
frame.Id = control.id;
upload = new Widgets.UploadFragment(control, binding, Inflater, a, xFormInstance);
MainFormLayout.AddView(frame);
ControlViews.Add(frame);
fragmentTx.Replace(frame.Id, upload, $"upload_{control.id}");
//fragmentTx.Show(upload);
fragmentTx.Commit();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Это очищенный код, позволяющий удалить как можно больше ненужного кода.Показанный код - это путь, по которому проходит рассматриваемый код.