xamarin - 滚动索引方法没有持续触发
问题描述
在 Xamarin.Forms 和 Xamarin.Android 项目中,我为 ListView 创建了一个自定义呈现器和适配器。适配器实现 BaseAdapter 和 ISectionIndexer。此控件的自定义呈现使用 FastScroll 功能,在 Android 中,当您点击此滚动时,会出现一个带有索引字母的气泡。这很好用,但我的想法是有一种方法可以在释放滚动后捕获所选索引并且滚动“气泡”消失。我认为使用以下类(在 GetSectionForPosition 方法中)可以实现:
public class ListViewconIndexAdapter : BaseAdapter<string>, ISectionIndexer
{
string[] items;
Activity context;
string[] sections;
Java.Lang.Object[] sectionsObjects;
Dictionary<string, int> alphaIndex;
public ListViewconIndexAdapter(Activity context, string[] items) : base()
{
this.context = context;
this.items = items;
alphaIndex = new Dictionary<string, int>();
for (int i = 0; i < items.Length; i++)
{
var key = items[i][0].ToString();
if (!alphaIndex.ContainsKey(key))
alphaIndex.Add(key, i);
}
sections = new string[alphaIndex.Keys.Count];
alphaIndex.Keys.CopyTo(sections, 0);
sectionsObjects = new Java.Lang.Object[sections.Length];
for (int i = 0; i < sections.Length; i++)
{
sectionsObjects[i] = new Java.Lang.String(sections[i]);
}
}
public override Java.Lang.Object GetItem(int position)
{
return position;
}
public override long GetItemId(int position)
{
return position;
}
public override string this[int position]
{
get { return items[position]; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (view == null)
view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = items[position];
return view;
}
//Fill in cound here, currently 0
public override int Count
{
get { return items.Length; }
}
// -- ISectionIndexer --
public int GetPositionForSection(int section)
{
return alphaIndex[sections[section]];
}
public int GetSectionForPosition(int position)
{ // this method isn't called in this example, but code is provided for completeness
int prevSection = 0;
for (int i = 0; i < sections.Length; i++)
{
if (GetPositionForSection(i) > position)
{
break;
}
prevSection = i;
}
Console.WriteLine(prevSection);
Console.WriteLine(sections[prevSection]);
//Toast.MakeText(context, sections[prevSection], ToastLength.Short).Show();
Xamarin.Forms.MessagingCenter.Send<object,string>(this, "CambioSeccion", sections[prevSection]);
return prevSection;
}
}
我将那些 Console.writeline 用于检查索引字母,而 Message send 是一种将其发送回 PCL/NET Standard 代码(以显示 DisplayAlert 或其他内容)的方式。 但问题是方法触发不一致,例如,有时您快速向下滚动到“C”,但控制台在将其释放后不打印任何内容,但在您离开它的地方再次触摸它后,它会触发。但有时它像我想要的那样工作,它在选定索引处释放滚动后打印。
解决方案
ListView
有两个不同的滚动监听器,AbsListView.IOnScrollListener
并且AbsListView.IOnScrollChangeListener
(这个是在 API 23 中添加的)和一个触摸监听器(AbsListView.IOnTouchListener
)
我认为根据您的用例,您正在寻找OnScrollStateChanged
并且当它进入空闲状态并且您没有触摸列表视图时,做一些事情(反之亦然)。
示例(当然根据您的需要进行调整):
public class MyScrollListener : Java.Lang.Object, AbsListView.IOnTouchListener, AbsListView.IOnScrollListener, AbsListView.IOnScrollChangeListener //(API23)
{
bool touching;
bool scrolling;
public void OnScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
}
public void OnScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY)
{
}
public void OnScrollStateChanged(AbsListView view, [GeneratedEnum] ScrollState scrollState)
{
switch(scrollState)
{
case ScrollState.Idle:
if (!touching)
{
scrolling = false;
GetSelection();
}
break;
default:
scrolling = true;
break;
}
}
public bool OnTouch(View v, MotionEvent e)
{
switch (e.Action)
{
case MotionEventActions.Up:
touching = false;
if (!scrolling)
GetSelection();
break;
default:
touching = true;
break;
}
return true;
}
void GetSelection()
{
// touch and srolling is done, do something
}
}
用法:
var scrollListener = new MyScrollListener();
listView.SetOnTouchListener(scrollListener);
listView.SetOnScrollListener(scrollListener);
listView.SetOnScrollChangeListener(scrollListener); // API23
推荐阅读
- c# - 为什么我的 !ban 命令不起作用(找不到用户)DISCORD.NET / C#
- javascript - if-else 语句在 javascript/html 中不起作用
- python - 从一个 Socket 接收两个函数
- python - 在python中使用正则表达式获取特定文本的左右文本
- r - 未找到函数中的 R 对象
- java - 使用正则表达式查找 Json 值:匹配字符串,然后是任意数量的字符,然后是第二个匹配字符串之后的值
- java - Android/Java:如何从 Canvas 中提取位图?
- python - 如何在 Linux Ubuntu 16.04 中使用 Pip3 安装 Python 3.6 模块?
- javascript - 如何在变量中引用站点上的键入文本
- javascript - 为什么 JavaScript 函数返回未定义?