#android #android-fragments #xamarin
#Android #android-фрагменты #xamarin
Вопрос:
У меня есть вызываемое действие Session
, которое показывает разные таблицы, и при нажатии кнопки для каждой таблицы Seats
они должны отображаться, но они отображаются только в первой таблице.
Сеанс содержит список Table Fragments
, и каждая таблица содержит список Seat Fragments
.
[Activity] Session
[List<TableFragment>] Tables
[List<SeatFragment>] Seats
Ожидаемый результат для всех таблиц:
Как это выглядит во всех таблицах, кроме первой таблицы:
Также, когда я вхожу в Session
действие, создается пустая таблица с «Именем таблицы» и «Местами» с именем, заданным, Seat Fragment
что странно. «Имя таблицы» — это переменная, взятая из файла макета, так что все в порядке, но кнопки создаются программно, поэтому их не должно быть в этом «пустом» фрагменте. Текст «Имя таблицы» отображается правильно на всех разных Table Fragments
, поэтому я почти уверен, что это как-то связано с тем, когда я создаю Seat Fragments
, но я не знаю, что это может быть. Все теги разные, и первая таблица работает как шарм.
У Session
меня есть метод для создания таблиц, и в то же время я создаю места. Сначала я подумал, что это как-то связано с тем, что фиксация занимает некоторое время, поэтому я удалил его из CreateTables, но с тем же результатом:
private void CreateTables()
{
try
{
tables = new List<Fragments.Session.Table>();
foreach (var table in A.ActiveSession.Tables)
{
FragmentTransaction trans = this.FragmentManager.BeginTransaction();
var frag = new Fragments.Session.Table();
trans.Add(Resource.Id.frameLayoutSessionTable, frag, "table-" table.Id.ToString());
trans.Commit();
frag.CreateSeats(table.Seats);
tables.Add(frag);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Toast.MakeText(this, "Could not create tables ...", ToastLength.Short).Show();
}
}
Таблица.CreateSeats():
public void CreateSeats(List<SessionSeatViewModel> _seats)
{
Console.WriteLine("Fragments.Table.CreateSeats()");
seats = new List<Seat>();
foreach (var seat in _seats)
{
Console.WriteLine("Tag: " "seat-" seat.Id.ToString());
var tag = "seat-" seat.Id.ToString();
FragmentTransaction trans = this.FragmentManager.BeginTransaction();
var frag = new Fragments.Session.Seat();
trans.Add(Resource.Id.layoutSeats, frag, tag);
trans.Commit();
seats.Add(frag);
}
}
Я могу сказать, что места создаются, как и ожидалось, и когда я вызываю свой «Стол».Show ()» правильные идентификаторы места распечатываются в журнал:
var activeTable = this.FragmentManager.FindFragmentByTag<Fragments.Session.Table>("table-" table.Id.ToString());
activeTable.Update(table); //Updates the seats with correct values
activeTable.Show();
Таблица.Показать ():
public void Show()
{
Console.WriteLine("Fragments.Table.Show()");
this.FragmentManager.BeginTransaction().Show(this).Commit();
foreach (var seat in seats)
seat.Show();
}
Место.Показать ():
public void Show()
{
Console.WriteLine("Fragments.Session.Seat.Show()");
this.FragmentManager.BeginTransaction().Show(this).Commit();
}
Я также пробовал this.FragmentManager.ExecutePendingTransactions()
после создания каждой таблицы и раньше CreateSeats
, но безуспешно.
Ответ №1:
Когда дело доходит до вложенных фрагментов, нам нужно использовать ChildFragmentManager.
Вот как я решил это в Xamarin:
В разделе Session
я создаю таблицы, как и раньше:
private void CreateTables()
{
try
{
tables = new List<Fragments.Session.Table>();
var trans = SupportFragmentManager.BeginTransaction();
foreach (var table in A.ActiveSession.Tables)
{
var tag = "table-" table.Id.ToString();
var frag = new Fragments.Session.Table();
trans.Add(Resource.Id.frameLayoutSessionTable, frag, tag);
tables.Add(frag);
if (mCurrentFragment == null) mCurrentFragment = frag;
else trans.Hide(frag);
}
trans.Commit();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Toast.MakeText(this, "Could not create tables ...", ToastLength.Short).Show();
}
}
В разделе Table.OnCreateView
я создаю Seat
фрагменты, используя ChildFragmentManager
(фиксированный размер является временным):
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Console.WriteLine("Table.OnCreateView");
var view = inflater.Inflate(Resource.Layout.table_session, container, false);
mText = view.FindViewById<TextView>(Resource.Id.textViewTableSessionName);
var trans = ChildFragmentManager.BeginTransaction();
seats = new List<Seat>();
for (int i = 0; i < 9; i )
{
var frag = new Fragments.Session.Seat();
trans.Add(Resource.Id.layoutSeats, frag, "seat-" (i 1).ToString());
seats.Add(frag);
}
trans.Commit();
return view;
}
Session
наследуется от Android.Support.V4.App.Fragment
Table
и Seat
от Android.Support.V4.App.Fragment
.
Я нашел ответ в этом руководстве: https://www.youtube.com/watch?v=3wEGeT3zg6Iamp;list=PLCuRg51-gw5VqYchUekCqxUS9hEZkDf6lamp;index=62 (Проверьте учебники 55 и 56, если вы не понимаете).