AndroidX 迁移后,ListView 未在 OnCreate/OnStart 上显示任何数据
A ListView is not displaying any data on OnCreate/OnStart after AndroidX migration
我有一个应用程序只显示数据,直到我在 SearchView 上过滤某些内容。现在,在下面的示例中,我在主页 Activity 和 更多站点 Activity (错误发生的位置)[ 之间切换=59=].
如您所见,当我切换到“更多站点”activity 时,它唯一的 ListView 一直是空的,直到我“过滤”了一些东西。重要的是要强调,在我将应用程序迁移到 AndroidX 之前,更多站点 Activity 曾经正常工作。
这是我当前代码的一部分:
other_ruins.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/search_container" />
<ListView
android:id="@+id/lstOtherRuins"
android:layout_margin="8dp"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:choiceMode="singleChoice"
android:layout_gravity="left|start" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:adSize="SMART_BANNER"
app:adUnitId="@string/banner_ad_unit_id" />
</LinearLayout>
search_container.xml
<?xml version="1.0" encoding="UTF-8" ?>
<FrameLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
app:theme="@style/ToolBarStyle"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary" />
<com.miguelcatalan.materialsearchview.MaterialSearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
这是我的 C# 代码,在这两种情况下,我都使用 UpdateListView
方法:
protected override void OnStart()
{
base.OnStart();
UpdateListView(AllRuins);
}
private void UpdateListView(List<Row> result)
{
List<IMenuItemsType> item = new();
string prevCountry = "";
foreach (var datum in result)
{
if (datum.Col3 != prevCountry)
{
prevCountry = datum.Col3;
item.Add(new MenuHeaderItem(prevCountry));
}
item.Add(new MenuContentSimpleItem(datum.Col1, datum.Col2, datum.Col3, datum.Col4, datum.Col5));
}
LstOtherRuins.Adapter = new OtherRuinsAdapter(this, item);
}
这是 SearchView 过滤器:
public partial class OtherRuinsActivity
{
public class MaterialSearchViewListener : Java.Lang.Object, MaterialSearchView.IOnQueryTextListener
{
private readonly OtherRuinsActivity OActivity;
public MaterialSearchViewListener(OtherRuinsActivity oActivity)
{
OActivity = oActivity;
}
public bool OnQueryTextChange(string p0)
{
OActivity.CurrentWord = p0;
OActivity.UpdateListView(OActivity.AllRuins.Where(x => x.Col1.ToLower().Contains(p0)).ToList());
return true;
}
public bool OnQueryTextSubmit(string p0)
{
OActivity.CurrentWord = p0;
OActivity.UpdateListView(OActivity.AllRuins.Where(x => x.Col1.ToLower().Contains(p0)).ToList());
return true;
}
}
}
我已经验证并有数据:
这也是我的适配器:
public partial class OtherRuinsAdapter
{
private class OtherRuinsViewHolder : Java.Lang.Object
{
public TextView LblName { get; set; }
public TextView LblLocation { get; set; }
}
}
public partial class OtherRuinsAdapter : ArrayAdapter<IMenuItemsType>
{
public OtherRuinsAdapter(Context context, List<IMenuItemsType> items) : base(context, 0, items)
{
Context1 = context;
Items = items;
Inflater = (LayoutInflater)Context1.GetSystemService(Context.LayoutInflaterService);
}
public override int Count
{
get
{
return Items.Count;
}
}
public Context Context1 { get; set; }
public List<IMenuItemsType> Items { get; set; }
public LayoutInflater Inflater { get; set; }
public LayoutInflater Inflater1 { get => Inflater; set => Inflater = value; }
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var inflater = LayoutInflater.From(parent.Context);
OtherRuinsViewHolder holder = null;
var view = convertView;
if (view != null)
{
holder = view.Tag as OtherRuinsViewHolder;
}
if (holder == null)
{
holder = new OtherRuinsViewHolder();
view = inflater.Inflate(Resource.Layout.other_ruins_list, parent, false);
holder.LblName = view.FindViewById<TextView>(Resource.Id.lblName);
holder.LblLocation = view.FindViewById<TextView>(Resource.Id.lblLocation);
view.Tag = holder;
}
IMenuItemsType item = Items[position];
if (item.GetMenuItemsType() == 0)
{
MenuHeaderItem _headerItem = (MenuHeaderItem)item;
view = inflater.Inflate(Resource.Layout.listview_header_item, null);
// user dont click header item
view.Clickable = false;
var headerName = view.FindViewById<TextView>(Resource.Id.txtHeader);
headerName.Text = _headerItem.HeaderText;
}
else if (item.GetMenuItemsType() == 1)
{
MenuContentSimpleItem _contentItem = (MenuContentSimpleItem)item;
if (!string.IsNullOrEmpty(_contentItem.Wiki))
{
holder.LblName.PaintFlags = PaintFlags.UnderlineText;
holder.LblName.SetTextColor(Color.Argb(255, 10, 150, 124));
holder.LblName.Click += LblName_Click;
}
else
{
holder.LblName.PaintFlags = PaintFlags.AntiAlias;
holder.LblName.SetTextColor(Color.Argb(255, 33, 33, 33));
holder.LblName.Click -= LblName_Click;
}
if (!string.IsNullOrEmpty(_contentItem.SubScript))
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
holder.LblName.SetText(Html.FromHtml($"{_contentItem.Title}<sub><small>{_contentItem.SubScript}</small></sub>", FromHtmlOptions.ModeLegacy), BufferType.Spannable);
else
#pragma warning disable CS0618 // Type or member is obsolete
holder.LblName.SetText(Html.FromHtml($"{_contentItem.Title}<sub><small>{_contentItem.SubScript}</small></sub>"), BufferType.Spannable);
#pragma warning restore CS0618 // Type or member is obsolete
}
else
{
holder.LblName.Text = _contentItem.Title;
}
holder.LblLocation.Text = _contentItem.Description;
holder.LblLocation.PaintFlags = PaintFlags.UnderlineText;
holder.LblLocation.Click += LblLocation_Click;
}
return view;
}
private void LblName_Click(object sender, System.EventArgs e)
{
Context1.StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse(new XML2CSharp("OtherRuins.xml").FromXml<Book>().Row.Where(x => x.Col1 == ((TextView)sender).Text).FirstOrDefault().Col4)));
}
private void LblLocation_Click(object sender, System.EventArgs e)
{
Intent mapIntent = new Intent(Intent.ActionView, Android.Net.Uri.Parse($"google.navigation:q={((TextView)sender).Text}, {new XML2CSharp("OtherRuins.xml").FromXml<Book>().Row.Where(x => x.Col2 == ((TextView)sender).Text).FirstOrDefault().Col3}"));
mapIntent.SetPackage("com.google.android.apps.maps");
Context1.StartActivity(mapIntent);
}
}
P.S.:
似乎 GetView
没有被调用是因为这个布局:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/search_container" />
<ListView
android:id="@+id/lstOtherRuins"
android:layout_margin="8dp"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:choiceMode="singleChoice"
android:layout_gravity="left|start" />
</LinearLayout>
如果我删除 LinearLayout
,那么它可以工作,但会产生一个新错误:
由于 LinerLayout
包含 ListView
,因此未调用 GetView
方法。我重写了布局,现在可以正常使用了。
other_ruins.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/search_container" />
<ListView
android:id="@+id/lstOtherRuins"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:nestedScrollingEnabled="true"
android:layout_margin="8dp"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:choiceMode="singleChoice"
android:layout_below="@id/toolbar_container"
android:layout_gravity="left|start" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:adSize="SMART_BANNER"
app:adUnitId="@string/banner_ad_unit_id" />
</LinearLayout>
此外,我需要通过添加 AppBarLayout
来更改容器,因为它被重叠了。
search_container.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<com.google.android.material.appbar.AppBarLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
app:theme="@style/ToolBarStyle"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary" />
<com.miguelcatalan.materialsearchview.MaterialSearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
</com.google.android.material.appbar.AppBarLayout>
我有一个应用程序只显示数据,直到我在 SearchView 上过滤某些内容。现在,在下面的示例中,我在主页 Activity 和 更多站点 Activity (错误发生的位置)[ 之间切换=59=].
如您所见,当我切换到“更多站点”activity 时,它唯一的 ListView 一直是空的,直到我“过滤”了一些东西。重要的是要强调,在我将应用程序迁移到 AndroidX 之前,更多站点 Activity 曾经正常工作。
这是我当前代码的一部分:
other_ruins.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/search_container" />
<ListView
android:id="@+id/lstOtherRuins"
android:layout_margin="8dp"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:choiceMode="singleChoice"
android:layout_gravity="left|start" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:adSize="SMART_BANNER"
app:adUnitId="@string/banner_ad_unit_id" />
</LinearLayout>
search_container.xml
<?xml version="1.0" encoding="UTF-8" ?>
<FrameLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
app:theme="@style/ToolBarStyle"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary" />
<com.miguelcatalan.materialsearchview.MaterialSearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
这是我的 C# 代码,在这两种情况下,我都使用 UpdateListView
方法:
protected override void OnStart()
{
base.OnStart();
UpdateListView(AllRuins);
}
private void UpdateListView(List<Row> result)
{
List<IMenuItemsType> item = new();
string prevCountry = "";
foreach (var datum in result)
{
if (datum.Col3 != prevCountry)
{
prevCountry = datum.Col3;
item.Add(new MenuHeaderItem(prevCountry));
}
item.Add(new MenuContentSimpleItem(datum.Col1, datum.Col2, datum.Col3, datum.Col4, datum.Col5));
}
LstOtherRuins.Adapter = new OtherRuinsAdapter(this, item);
}
这是 SearchView 过滤器:
public partial class OtherRuinsActivity
{
public class MaterialSearchViewListener : Java.Lang.Object, MaterialSearchView.IOnQueryTextListener
{
private readonly OtherRuinsActivity OActivity;
public MaterialSearchViewListener(OtherRuinsActivity oActivity)
{
OActivity = oActivity;
}
public bool OnQueryTextChange(string p0)
{
OActivity.CurrentWord = p0;
OActivity.UpdateListView(OActivity.AllRuins.Where(x => x.Col1.ToLower().Contains(p0)).ToList());
return true;
}
public bool OnQueryTextSubmit(string p0)
{
OActivity.CurrentWord = p0;
OActivity.UpdateListView(OActivity.AllRuins.Where(x => x.Col1.ToLower().Contains(p0)).ToList());
return true;
}
}
}
我已经验证并有数据:
这也是我的适配器:
public partial class OtherRuinsAdapter
{
private class OtherRuinsViewHolder : Java.Lang.Object
{
public TextView LblName { get; set; }
public TextView LblLocation { get; set; }
}
}
public partial class OtherRuinsAdapter : ArrayAdapter<IMenuItemsType>
{
public OtherRuinsAdapter(Context context, List<IMenuItemsType> items) : base(context, 0, items)
{
Context1 = context;
Items = items;
Inflater = (LayoutInflater)Context1.GetSystemService(Context.LayoutInflaterService);
}
public override int Count
{
get
{
return Items.Count;
}
}
public Context Context1 { get; set; }
public List<IMenuItemsType> Items { get; set; }
public LayoutInflater Inflater { get; set; }
public LayoutInflater Inflater1 { get => Inflater; set => Inflater = value; }
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var inflater = LayoutInflater.From(parent.Context);
OtherRuinsViewHolder holder = null;
var view = convertView;
if (view != null)
{
holder = view.Tag as OtherRuinsViewHolder;
}
if (holder == null)
{
holder = new OtherRuinsViewHolder();
view = inflater.Inflate(Resource.Layout.other_ruins_list, parent, false);
holder.LblName = view.FindViewById<TextView>(Resource.Id.lblName);
holder.LblLocation = view.FindViewById<TextView>(Resource.Id.lblLocation);
view.Tag = holder;
}
IMenuItemsType item = Items[position];
if (item.GetMenuItemsType() == 0)
{
MenuHeaderItem _headerItem = (MenuHeaderItem)item;
view = inflater.Inflate(Resource.Layout.listview_header_item, null);
// user dont click header item
view.Clickable = false;
var headerName = view.FindViewById<TextView>(Resource.Id.txtHeader);
headerName.Text = _headerItem.HeaderText;
}
else if (item.GetMenuItemsType() == 1)
{
MenuContentSimpleItem _contentItem = (MenuContentSimpleItem)item;
if (!string.IsNullOrEmpty(_contentItem.Wiki))
{
holder.LblName.PaintFlags = PaintFlags.UnderlineText;
holder.LblName.SetTextColor(Color.Argb(255, 10, 150, 124));
holder.LblName.Click += LblName_Click;
}
else
{
holder.LblName.PaintFlags = PaintFlags.AntiAlias;
holder.LblName.SetTextColor(Color.Argb(255, 33, 33, 33));
holder.LblName.Click -= LblName_Click;
}
if (!string.IsNullOrEmpty(_contentItem.SubScript))
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
holder.LblName.SetText(Html.FromHtml($"{_contentItem.Title}<sub><small>{_contentItem.SubScript}</small></sub>", FromHtmlOptions.ModeLegacy), BufferType.Spannable);
else
#pragma warning disable CS0618 // Type or member is obsolete
holder.LblName.SetText(Html.FromHtml($"{_contentItem.Title}<sub><small>{_contentItem.SubScript}</small></sub>"), BufferType.Spannable);
#pragma warning restore CS0618 // Type or member is obsolete
}
else
{
holder.LblName.Text = _contentItem.Title;
}
holder.LblLocation.Text = _contentItem.Description;
holder.LblLocation.PaintFlags = PaintFlags.UnderlineText;
holder.LblLocation.Click += LblLocation_Click;
}
return view;
}
private void LblName_Click(object sender, System.EventArgs e)
{
Context1.StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse(new XML2CSharp("OtherRuins.xml").FromXml<Book>().Row.Where(x => x.Col1 == ((TextView)sender).Text).FirstOrDefault().Col4)));
}
private void LblLocation_Click(object sender, System.EventArgs e)
{
Intent mapIntent = new Intent(Intent.ActionView, Android.Net.Uri.Parse($"google.navigation:q={((TextView)sender).Text}, {new XML2CSharp("OtherRuins.xml").FromXml<Book>().Row.Where(x => x.Col2 == ((TextView)sender).Text).FirstOrDefault().Col3}"));
mapIntent.SetPackage("com.google.android.apps.maps");
Context1.StartActivity(mapIntent);
}
}
P.S.:
似乎 GetView
没有被调用是因为这个布局:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/search_container" />
<ListView
android:id="@+id/lstOtherRuins"
android:layout_margin="8dp"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:choiceMode="singleChoice"
android:layout_gravity="left|start" />
</LinearLayout>
如果我删除 LinearLayout
,那么它可以工作,但会产生一个新错误:
由于 LinerLayout
包含 ListView
,因此未调用 GetView
方法。我重写了布局,现在可以正常使用了。
other_ruins.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/search_container" />
<ListView
android:id="@+id/lstOtherRuins"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:nestedScrollingEnabled="true"
android:layout_margin="8dp"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:choiceMode="singleChoice"
android:layout_below="@id/toolbar_container"
android:layout_gravity="left|start" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:adSize="SMART_BANNER"
app:adUnitId="@string/banner_ad_unit_id" />
</LinearLayout>
此外,我需要通过添加 AppBarLayout
来更改容器,因为它被重叠了。
search_container.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<com.google.android.material.appbar.AppBarLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
app:theme="@style/ToolBarStyle"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary" />
<com.miguelcatalan.materialsearchview.MaterialSearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
</com.google.android.material.appbar.AppBarLayout>