Android ListView在元素添加到绑定的ObservableCollection(Xamarin)后未更新
我在StackOverflow上发现了许多类似的问题,但似乎无法解决这个问题 我正在尝试将ObservableCollection绑定到ListView,以便当集合的内容更改时,ListView将自动更新。不幸的是,当元素被添加到集合中时(通过单击按钮),ListView没有被更新。如何使ListView反映集合的当前内容 注意:如果我使用Android ListView在元素添加到绑定的ObservableCollection(Xamarin)后未更新,android,listview,xamarin,observablecollection,Android,Listview,Xamarin,Observablecollection,我在StackOverflow上发现了许多类似的问题,但似乎无法解决这个问题 我正在尝试将ObservableCollection绑定到ListView,以便当集合的内容更改时,ListView将自动更新。不幸的是,当元素被添加到集合中时(通过单击按钮),ListView没有被更新。如何使ListView反映集合的当前内容 注意:如果我使用listView.RequestLayout()强制布局,那么列表视图将包含正确数量的项目。但是,它不一定包含正确的项目。例如,如果删除第一个项目并在末尾添加
listView.RequestLayout()强制布局,那么代码>列表视图将包含正确数量的项目。但是,它不一定包含正确的项目。例如,如果删除第一个项目并在末尾添加一个新项目,则强制布局没有效果。如果我在删除第一项后强制布局,然后在末尾添加一项后再次强制布局,则内容是正确的
活动代码
public class MainActivity : Activity
{
int count = 1;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
ObservableCollection<UserTask> allTasksCollection = new ObservableCollection<UserTask>();
while(count < 6)
{
allTasksCollection.Add(new UserTask("Task number " + count));
count++;
}
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Bind listview to all tasks
ListView listView = FindViewById<ListView>(Resource.Id.allTasksListView);
UserTaskListAdapter adapter = new UserTaskListAdapter(this, allTasksCollection);
listView.Adapter = adapter;
// Button click should add a new task and remove the first task.
Button button = FindViewById<Button>(Resource.Id.myButton);
button.Click += delegate {
allTasksCollection.Add(new UserTask("Task number " + count));
button.Text = string.Format("{0} tasks!", count++);
};
}
}
公共类main活动:活动
{
整数计数=1;
创建时受保护的覆盖无效(捆绑包)
{
base.OnCreate(bundle);
ObservableCollection allTasksCollection=新的ObservableCollection();
而(计数<6)
{
添加(新用户任务(“任务编号”+count));
计数++;
}
//从“主”布局资源设置视图
SetContentView(Resource.Layout.Main);
//将listview绑定到所有任务
ListView ListView=FindViewById(Resource.Id.allTasksListView);
UserTaskListAdapter=新的UserTaskListAdapter(此,allTasksCollection);
Adapter=适配器;
//单击按钮应添加新任务并删除第一个任务。
Button Button=FindViewById(Resource.Id.myButton);
按钮。单击+=委托{
添加(新用户任务(“任务编号”+count));
button.Text=string.Format(“{0}任务!”,count++);
};
}
}
适配器
public class UserTaskListAdapter : BaseAdapter<UserTask>
{
Activity context;
ObservableCollection<UserTask> list;
public UserTaskListAdapter(Activity _context, ObservableCollection<UserTask> _list)
: base()
{
this.context = _context;
this.list = _list;
}
public override int Count
{
get { return list.Count; }
}
public override long GetItemId(int position)
{
return position;
}
public override UserTask this[int index]
{
get { return list[index]; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
view = context.LayoutInflater.Inflate(Resource.Layout.UserTaskRowItem, parent, false);
UserTask item = this[position];
view.FindViewById<TextView>(Resource.Id.Title).Text = item.Name;
return view;
}
}
公共类UserTaskListAdapter:BaseAdapter
{
活动语境;
可观察收集清单;
public UserTaskListAdapter(活动_上下文,ObservableCollection _列表)
:base()
{
this.context=\u context;
this.list=\u list;
}
公共覆盖整数计数
{
获取{return list.Count;}
}
公共覆盖长GetItemId(int位置)
{
返回位置;
}
public override UserTask this[int index]
{
获取{返回列表[索引];}
}
公共覆盖视图GetView(int位置、视图转换视图、视图组父视图)
{
视图=转换视图;
如果(视图==null)
视图=context.LayoutInflater.Inflate(Resource.Layout.UserTaskRowItem,父项,false);
UserTask item=此[职位];
view.findviewbyd(Resource.Id.Title).Text=item.Name;
返回视图;
}
}
主XAML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/rootLayout">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/allTasksContainer">
<Button
android:id="@+id/myButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/allTasksListView" />
</LinearLayout>
</LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/linearLayoutHorizontal">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/CheckboxContainer">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/checkboxSelect" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/TextContainer">
<TextView
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Title" />
<TextView
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/DueDate" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
列表项XAML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/rootLayout">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/allTasksContainer">
<Button
android:id="@+id/myButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/allTasksListView" />
</LinearLayout>
</LinearLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/linearLayoutHorizontal">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/CheckboxContainer">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/checkboxSelect" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/TextContainer">
<TextView
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Title" />
<TextView
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/DueDate" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
看看INotifyPropertyChanged接口。它将警告listview,listview中的对象中的变量已更改
编辑:误读你的问题。我的错。尝试在适配器上调用NotifyDataSetChanged(),更新其项目后,Android中的AFAIK ListView不会观察到您的ObservableCollection上的更改: 请尝试以下代码:
button.Click += delegate {
allTasksCollection.Add(new UserTask("Task number " + count));
button.Text = string.Format("{0} tasks!", count++);
adapter.NotifyDataSetChanged();
};
您还可以尝试将litener添加到ObservableCollection,在适配器中,将构造函数更改为:
this.list.CollectionChanged += (sender,args) => { NotifyDataSetChanged(); };
是的,我认为集合中的对象最终必须实现INotifyPropertyChanged。但是,这对于从集合中添加/删除内容并不重要。。据我所知,ObservableCollection应该处理这个问题。@pulekies这是正确的。listview应该可以看到它们。稍后我会再看一遍,也许我能帮上忙。非常感谢@Hichaam!您提供的两种解决方案都提供了我想要的结果。我认为第二个可能是更好的解决方案,我会用它。很高兴它有帮助。