在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来检查索引字母,并且消息发送是一种将其发送回PCL / NET Standard代码(以显示DisplayAlert或类似内容)的方式。 但是问题是方法触发不一致,例如,有时您快速向下滚动到“ C”,但在将其释放后,Console无法打印任何内容,但是在您离开的位置再次触摸它之后它,它启动。但是有时它会像我想要的那样工作,在释放选定索引处的滚动条后会打印出来。
答案 0 :(得分:0)
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