C# ListView刷新GetView()

C# ListView刷新GetView(),c#,android,listview,xamarin,C#,Android,Listview,Xamarin,在我的应用程序中,我有一个带有“节”的列表视图。对于每个项目,我都添加了一个字母,但它们仅在以该字母开头的第一个单词中可见。它工作正常,但是如果我在我的ListView中向下滚动,顺序就会改变,这意味着该字母将进入下一个项目 例如: A -- - Alligator - Ant - Antelope - Ape 但当我向下滚动时,会发生以下情况: - Aligator A -- - Ant - Antelope - Ape 添加我在GetView()中实现的字母的函数 我

在我的应用程序中,我有一个带有“节”的列表视图。对于每个项目,我都添加了一个字母,但它们仅在以该字母开头的第一个单词中可见。它工作正常,但是如果我在我的ListView中向下滚动,顺序就会改变,这意味着该字母将进入下一个项目

例如:

A
--

 - Alligator
 - Ant
 - Antelope
 - Ape
但当我向下滚动时,会发生以下情况:

 - Aligator

A
--
 - Ant
 - Antelope
 - Ape
添加我在GetView()中实现的字母的函数

我怎样才能解决这个问题? 我读到ListView在滚动时正在刷新,如何禁用刷新?还是有其他办法解决这个问题

protected string old_char = "";
        public override View GetView(int position, View convertView, ViewGroup parent)
        {
                var item = sw_items [position];
                View view;

          convertView = null;

                view = (convertView ??
                    this.context.LayoutInflater.Inflate (Resource.Layout.ItemLayout,
                  parent,
                  false)) as LinearLayout;

                var txtTitle = view.FindViewById<TextView> (Resource.Id.txtTitle);
                txtTitle.SetText (sw_items [position].name, TextView.BufferType.Normal);

                var alfabet = view.FindViewById<TextView> (Resource.Id.alfabet);
                var linAlfabet = view.FindViewById<LinearLayout> (Resource.Id.Lin_Alfabet);

          if (convertView == null) {  
            string cnv_char = item.name [0].ToString ().ToUpper ();
            alfabet.Text = cnv_char;
            if (cnv_char != old_char) {
              alfabet.Visibility = ViewStates.Visible;
              linAlfabet.Visibility = ViewStates.Visible;
            } else {
              alfabet.Visibility = ViewStates.Gone;
              linAlfabet.Visibility = ViewStates.Gone;
            }

            //saving previous char
            old_char = cnv_char;
          }

                return view;


        }

      }
受保护字符串old_char=”“;
公共覆盖视图GetView(int位置、视图转换视图、视图组父视图)
{
var项目=sw_项目[位置];
视图;
convertView=null;
视图=(转换视图??
this.context.LayoutInflater.充气(Resource.Layout.ItemLayout,
父母亲
假)作为线性布局;
var txtTitle=view.findviewbyd(Resource.Id.txtTitle);
txtTitle.SetText(sw_items[position].name,TextView.BufferType.Normal);
var alfabet=view.findviewbyd(Resource.Id.alfabet);
var linAlfabet=view.findviewbyd(Resource.Id.Lin\u Alfabet);
如果(convertView==null){
字符串cnv_char=item.name[0].ToString().ToUpper();
alfabet.Text=cnv_char;
if(cnv_char!=旧_char){
alfabet.Visibility=ViewStates.Visible;
LinalLabet.Visibility=ViewState.Visible;
}否则{
alfabet.Visibility=ViewStates.Gone;
linalLabet.Visibility=ViewStates.Gone;
}
//保存上一个字符
旧字符=cnv字符;
}
返回视图;
}
}

我做错了什么?

ListView重用堆栈中的视图来替换向上滚动以再次将其置于底部的视图

请尝试在代码中添加以下语句,然后再添加为:-

convertView=null

在它检查


如果(convertView==null)

修订版

首先
getView()
实现的基本方案如下

if (convertView == null) {
    // the system does not want me to recycle a view object, so create a new one
    LayoutInflater inflater = (LayyoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = inflater.inflate(R.layout.your_layout_file, parent, false);
}
// here, set up the convertView object, no matter whether it was recycled or not
...
return convertView;
考虑到您发布的代码片段,您可能需要做的就是:1。删除
convertVire=nullYatin建议的语句和2。如果(convertView==null){
包括关闭
}
字符串cnv\u字符周围的
则删除周围的
。。。old_char=cnv_char
块。确保为
convertView
正确设置所有内容,因为不能保证它是新对象

其次,您的代码依赖于以特定顺序调用
getView()
,但事实并非如此。目前,您需要将
old_char
设置为最后一项的起始字母(按照它们在列表中的显示顺序)。这不是Guaranteed


我建议您使用
position
参数访问列表的上一个条目(当然,第一个条目除外),并检查是否存在差异,如果没有前置项或以不同的字母开头,则显示当前项的起始字母。

将其添加到getView()中值得注意的是,这种建议的方法——忽略视图的循环——绝对不是Android对
getView()的期望
实现,而且它也不会为应用程序节省任何精力——设置现有对象的效率如何低于设置新创建的对象?此外,您的解决方案只有在原始海报出现特定的实现错误时才能解决问题,而这并不能保证。如果你先问他,如果你指出你的解决方案不是Android-ish,那就太好了。添加你在适配器上使用的代码。不幸的是,我不知道如何在我的代码中实现这一点。@Luk那么你能描述一下你在尝试遵循这个方案时面临的问题吗?我使用的是C#,你发布的是Java。这就是为什么我不能实现这个,好吧。考虑到您发布的代码片段,您可能需要做的就是:1。删除
convertVire=nullYatin建议的语句和2。如果(convertView==null){
包括关闭
}
字符串cnv\u字符周围的
则删除周围的
。。。old_char=cnv_char
block,你应该没事。我按照你的步骤做了,但现在我又回到了以前的情况。