如何在 Xamarin 的 AlertDialog 中创建带有自定义适配器的列表视图 Android
How can I create a listview with custom adapter inside a AlertDialog in Xamarin Android
我正在尝试在 Xamarin 的 AllertDialog 中创建一个 ListView Android。
我搜索并找到了一些示例,但我没有在 AlertDialog 中找到任何使用 C# 的 ListView 和自定义适配器。
我找到的最接近样本的是下面的样本 (Thanks to Macoratti)。这个没有AlertDialog。
我试图适应但我得到 System.NullReferenceException: 'Object reference not set to an instance of an object.'.
主要activity:
namespace App.CustomAdapterListView
{
[Activity(Label = "App.CustomAdapterListView", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
/* Original
var filmesListView = FindViewById<ListView>(Resource.Id.filmeslistView);
filmesListView.FastScrollEnabled = true;
filmesListView.ItemClick += FilmesListView_ItemClick;
var filmesAdapter = new FilmeAdapter(this, FilmesRepositorio.Filmes);
filmesListView.Adapter = filmesAdapter;
*/
var ViewAD = LayoutInflater.Inflate(Resource.Layout.Filmes, null);
AlertDialog alertDialog;
using (var dialog = new AlertDialog.Builder(this))
{
dialog.SetView(ViewAD);
dialog.SetNegativeButton("Cancel", (s, a) => { });
alertDialog = dialog.Create();
}
var adapter = new FilmeAdapter(this, FilmesRepositorio.Filmes);
// Here I get - System.NullReferenceException: 'Object reference not set to an instance of an object.'
ViewAD.FindViewById<ListView>(Resource.Id.filmeslistView).Adapter = adapter;
alertDialog.Show();
}
private void FilmesListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
Toast.MakeText(this, FilmesRepositorio.Filmes[e.Position].ToString(), ToastLength.Long).Show();
}
}
}
适配器class:
namespace App.CustomAdapterListView
{
public class Filme
{
public int Id { get; set; }
public string Titulo { get; set; }
public string Diretor { get; set; }
public DateTime DataLancamento { get; set; }
public override string ToString()
{
return Titulo + " por " + Diretor;
}
}
}
适配器:
namespace App.CustomAdapterListView
{
public class FilmeAdapter : BaseAdapter<Filme>
{
private readonly Activity context;
private readonly List<Filme> filmes;
public FilmeAdapter(Activity context, List<Filme> filmes)
{
this.context = context;
this.filmes = filmes;
}
public override Filme this[int position]
{
get
{
return filmes[position];
}
}
public override int Count
{
get
{
return filmes.Count;
}
}
public override long GetItemId(int position)
{
return filmes[position].Id;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var view = convertView ?? context.LayoutInflater.Inflate(Resource.Layout.Filmes, parent, false);
var txtTitulo = view.FindViewById<TextView>(Resource.Id.tituloTextView);
var txtDiretor = view.FindViewById<TextView>(Resource.Id.diretorTextView);
var txtLancamento = view.FindViewById<TextView>(Resource.Id.dataLancamentoTextView);
txtTitulo.Text = filmes[position].Titulo;
txtDiretor.Text = "Dirigido por: " + filmes[position].Diretor;
txtLancamento.Text = "Lançado em : " + filmes[position].DataLancamento.ToShortDateString();
return view;
}
}
}
数据库:
namespace App.CustomAdapterListView
{
public static class FilmesRepositorio
{
public static List<Filme> Filmes { get; private set; }
static FilmesRepositorio()
{
Filmes = new List<Filme>();
for (int i = 0; i < 10; i++)
{
AddFilmes();
}
}
private static void AddFilmes()
{
Filmes.Add(new Filme
{
Id = 1,
Titulo = "A New Hope",
Diretor = "George Lucas",
DataLancamento = new DateTime(1977, 05, 25)
});
Filmes.Add(new Filme
{
Id = 2,
Titulo = "The Empire Strikes Back",
Diretor = "George Lucas",
DataLancamento = new DateTime(1980, 05, 17)
});
Filmes.Add(new Filme
{
Id = 3,
Titulo = "O Reterono de Jedi",
Diretor = "George Lucas",
DataLancamento = new DateTime(1983, 05, 25)
});
Filmes.Add(new Filme
{
Id = 4,
Titulo = "A ameaça fantasma",
Diretor = "George Lucas",
DataLancamento = new DateTime(1999, 05, 19)
});
Filmes.Add(new Filme
{
Id = 5,
Titulo = "A vingança dos Sith",
Diretor = "George Lucas",
DataLancamento = new DateTime(2005, 05, 19)
});
Filmes.Add(new Filme
{
Titulo = "Marte",
Diretor = "J.J. Abrams",
DataLancamento = new DateTime(2015, 12, 11)
});
}
}
}
主要布局 axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:background="#eee5d5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/filmeslistView" />
</LinearLayout>
ListView的自定义布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="8dp">
<TextView
android:id="@+id/tituloTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20dp"
android:textStyle="bold"
android:paddingLeft="5dp" />
<TextView
android:id="@+id/diretorTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#00A14B"
android:paddingLeft="5dp" />
<TextView
android:id="@+id/dataLancamentoTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#7F3F97"
android:paddingLeft="5dp" />
</LinearLayout>
抱歉这个菜鸟问题。
我将不胜感激。
谢谢
您应该为包含 ListView
的视图创建一个 xml (dialogview.xml
) 并为每个项目创建 xml (itemview.xml
)列表视图。
例如:
创建 dialogview.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:background="#eee5d5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/filmeslistView" />
</LinearLayout>
创建 itemview.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="8dp">
<TextView
android:id="@+id/tituloTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20dp"
android:textStyle="bold"
android:paddingLeft="5dp" />
<TextView
android:id="@+id/diretorTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#00A14B"
android:paddingLeft="5dp" />
<TextView
android:id="@+id/dataLancamentoTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#7F3F97"
android:paddingLeft="5dp" />
</LinearLayout>
在您的 MainActivity 中:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
var ViewAD = LayoutInflater.Inflate(Resource.Layout.dialogview, null);
var adapter = new FilmeAdapter(this, FilmesRepositorio.Filmes);
ViewAD.FindViewById<ListView>(Resource.Id.filmeslistView).Adapter = adapter;
AlertDialog alertDialog;
using (var dialog = new AlertDialog.Builder(this))
{
dialog.SetView(ViewAD);
dialog.SetNegativeButton("Cancel", (s, a) => { });
alertDialog = dialog.Create();
}
alertDialog.Show();
}
并在您的适配器中:
namespace App.CustomAdapterListView
{
public class FilmeAdapter : BaseAdapter<Filme>
{
private readonly Activity context;
private readonly List<Filme> filmes;
public FilmeAdapter(Activity context, List<Filme> filmes)
{
this.context = context;
this.filmes = filmes;
}
public override Filme this[int position]
{
get
{
return filmes[position];
}
}
public override int Count
{
get
{
return filmes.Count;
}
}
public override long GetItemId(int position)
{
return filmes[position].Id;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var view = convertView ?? context.LayoutInflater.Inflate(Resource.Layout.itemview, parent, false);// inflate the xml for each item
var txtTitulo = view.FindViewById<TextView>(Resource.Id.tituloTextView);
var txtDiretor = view.FindViewById<TextView>(Resource.Id.diretorTextView);
var txtLancamento = view.FindViewById<TextView>(Resource.Id.dataLancamentoTextView);
txtTitulo.Text = filmes[position].Titulo;
txtDiretor.Text = "Dirigido por: " + filmes[position].Diretor;
txtLancamento.Text = "Lançado em : " + filmes[position].DataLancamento.ToShortDateString();
return view;
}
}
}
更新
var ViewAD = LayoutInflater.Inflate(Resource.Layout.dialogview, null);
var adapter = new FilmeAdapter(this, FilmesRepositorio.Filmes);
ListView listview = ViewAD.FindViewById<ListView>(Resource.Id.filmeslistView);
listview.Adapter = adapter;
listView.ItemClick += ListView_ItemClick;
...
private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
//you could get the select data
}
我正在尝试在 Xamarin 的 AllertDialog 中创建一个 ListView Android。
我搜索并找到了一些示例,但我没有在 AlertDialog 中找到任何使用 C# 的 ListView 和自定义适配器。
我找到的最接近样本的是下面的样本 (Thanks to Macoratti)。这个没有AlertDialog。 我试图适应但我得到 System.NullReferenceException: 'Object reference not set to an instance of an object.'.
主要activity:
namespace App.CustomAdapterListView
{
[Activity(Label = "App.CustomAdapterListView", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
/* Original
var filmesListView = FindViewById<ListView>(Resource.Id.filmeslistView);
filmesListView.FastScrollEnabled = true;
filmesListView.ItemClick += FilmesListView_ItemClick;
var filmesAdapter = new FilmeAdapter(this, FilmesRepositorio.Filmes);
filmesListView.Adapter = filmesAdapter;
*/
var ViewAD = LayoutInflater.Inflate(Resource.Layout.Filmes, null);
AlertDialog alertDialog;
using (var dialog = new AlertDialog.Builder(this))
{
dialog.SetView(ViewAD);
dialog.SetNegativeButton("Cancel", (s, a) => { });
alertDialog = dialog.Create();
}
var adapter = new FilmeAdapter(this, FilmesRepositorio.Filmes);
// Here I get - System.NullReferenceException: 'Object reference not set to an instance of an object.'
ViewAD.FindViewById<ListView>(Resource.Id.filmeslistView).Adapter = adapter;
alertDialog.Show();
}
private void FilmesListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
Toast.MakeText(this, FilmesRepositorio.Filmes[e.Position].ToString(), ToastLength.Long).Show();
}
}
}
适配器class:
namespace App.CustomAdapterListView
{
public class Filme
{
public int Id { get; set; }
public string Titulo { get; set; }
public string Diretor { get; set; }
public DateTime DataLancamento { get; set; }
public override string ToString()
{
return Titulo + " por " + Diretor;
}
}
}
适配器:
namespace App.CustomAdapterListView
{
public class FilmeAdapter : BaseAdapter<Filme>
{
private readonly Activity context;
private readonly List<Filme> filmes;
public FilmeAdapter(Activity context, List<Filme> filmes)
{
this.context = context;
this.filmes = filmes;
}
public override Filme this[int position]
{
get
{
return filmes[position];
}
}
public override int Count
{
get
{
return filmes.Count;
}
}
public override long GetItemId(int position)
{
return filmes[position].Id;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var view = convertView ?? context.LayoutInflater.Inflate(Resource.Layout.Filmes, parent, false);
var txtTitulo = view.FindViewById<TextView>(Resource.Id.tituloTextView);
var txtDiretor = view.FindViewById<TextView>(Resource.Id.diretorTextView);
var txtLancamento = view.FindViewById<TextView>(Resource.Id.dataLancamentoTextView);
txtTitulo.Text = filmes[position].Titulo;
txtDiretor.Text = "Dirigido por: " + filmes[position].Diretor;
txtLancamento.Text = "Lançado em : " + filmes[position].DataLancamento.ToShortDateString();
return view;
}
}
}
数据库:
namespace App.CustomAdapterListView
{
public static class FilmesRepositorio
{
public static List<Filme> Filmes { get; private set; }
static FilmesRepositorio()
{
Filmes = new List<Filme>();
for (int i = 0; i < 10; i++)
{
AddFilmes();
}
}
private static void AddFilmes()
{
Filmes.Add(new Filme
{
Id = 1,
Titulo = "A New Hope",
Diretor = "George Lucas",
DataLancamento = new DateTime(1977, 05, 25)
});
Filmes.Add(new Filme
{
Id = 2,
Titulo = "The Empire Strikes Back",
Diretor = "George Lucas",
DataLancamento = new DateTime(1980, 05, 17)
});
Filmes.Add(new Filme
{
Id = 3,
Titulo = "O Reterono de Jedi",
Diretor = "George Lucas",
DataLancamento = new DateTime(1983, 05, 25)
});
Filmes.Add(new Filme
{
Id = 4,
Titulo = "A ameaça fantasma",
Diretor = "George Lucas",
DataLancamento = new DateTime(1999, 05, 19)
});
Filmes.Add(new Filme
{
Id = 5,
Titulo = "A vingança dos Sith",
Diretor = "George Lucas",
DataLancamento = new DateTime(2005, 05, 19)
});
Filmes.Add(new Filme
{
Titulo = "Marte",
Diretor = "J.J. Abrams",
DataLancamento = new DateTime(2015, 12, 11)
});
}
}
}
主要布局 axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:background="#eee5d5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/filmeslistView" />
</LinearLayout>
ListView的自定义布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="8dp">
<TextView
android:id="@+id/tituloTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20dp"
android:textStyle="bold"
android:paddingLeft="5dp" />
<TextView
android:id="@+id/diretorTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#00A14B"
android:paddingLeft="5dp" />
<TextView
android:id="@+id/dataLancamentoTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#7F3F97"
android:paddingLeft="5dp" />
</LinearLayout>
抱歉这个菜鸟问题。 我将不胜感激。
谢谢
您应该为包含 ListView
的视图创建一个 xml (dialogview.xml
) 并为每个项目创建 xml (itemview.xml
)列表视图。
例如:
创建 dialogview.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:background="#eee5d5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/filmeslistView" />
</LinearLayout>
创建 itemview.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="8dp">
<TextView
android:id="@+id/tituloTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="20dp"
android:textStyle="bold"
android:paddingLeft="5dp" />
<TextView
android:id="@+id/diretorTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#00A14B"
android:paddingLeft="5dp" />
<TextView
android:id="@+id/dataLancamentoTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#7F3F97"
android:paddingLeft="5dp" />
</LinearLayout>
在您的 MainActivity 中:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
var ViewAD = LayoutInflater.Inflate(Resource.Layout.dialogview, null);
var adapter = new FilmeAdapter(this, FilmesRepositorio.Filmes);
ViewAD.FindViewById<ListView>(Resource.Id.filmeslistView).Adapter = adapter;
AlertDialog alertDialog;
using (var dialog = new AlertDialog.Builder(this))
{
dialog.SetView(ViewAD);
dialog.SetNegativeButton("Cancel", (s, a) => { });
alertDialog = dialog.Create();
}
alertDialog.Show();
}
并在您的适配器中:
namespace App.CustomAdapterListView
{
public class FilmeAdapter : BaseAdapter<Filme>
{
private readonly Activity context;
private readonly List<Filme> filmes;
public FilmeAdapter(Activity context, List<Filme> filmes)
{
this.context = context;
this.filmes = filmes;
}
public override Filme this[int position]
{
get
{
return filmes[position];
}
}
public override int Count
{
get
{
return filmes.Count;
}
}
public override long GetItemId(int position)
{
return filmes[position].Id;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var view = convertView ?? context.LayoutInflater.Inflate(Resource.Layout.itemview, parent, false);// inflate the xml for each item
var txtTitulo = view.FindViewById<TextView>(Resource.Id.tituloTextView);
var txtDiretor = view.FindViewById<TextView>(Resource.Id.diretorTextView);
var txtLancamento = view.FindViewById<TextView>(Resource.Id.dataLancamentoTextView);
txtTitulo.Text = filmes[position].Titulo;
txtDiretor.Text = "Dirigido por: " + filmes[position].Diretor;
txtLancamento.Text = "Lançado em : " + filmes[position].DataLancamento.ToShortDateString();
return view;
}
}
}
更新
var ViewAD = LayoutInflater.Inflate(Resource.Layout.dialogview, null);
var adapter = new FilmeAdapter(this, FilmesRepositorio.Filmes);
ListView listview = ViewAD.FindViewById<ListView>(Resource.Id.filmeslistView);
listview.Adapter = adapter;
listView.ItemClick += ListView_ItemClick;
...
private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
//you could get the select data
}