我正在嘗試構建一個RecyclerView列表,右下角是一個按字母順序排列的索引器。我有清單顯示完美,並能夠滾動。RecyclerView與字母索引
我想知道如果有人可以給我一些指導建設的字母索引。我相信我需要遍歷我的列表並確定使用的字母(我可以這樣做)。然後構建字母列表(對於索引器),然後在選擇字母時使用scrollToPosition(int position)移動到列表中的右側項目。
我無法解決的主要問題不是建立另一個列表,而是兩個列表之間的通信。任何幫助將不勝感激。
我正在嘗試構建一個RecyclerView列表,右下角是一個按字母順序排列的索引器。我有清單顯示完美,並能夠滾動。RecyclerView與字母索引
我想知道如果有人可以給我一些指導建設的字母索引。我相信我需要遍歷我的列表並確定使用的字母(我可以這樣做)。然後構建字母列表(對於索引器),然後在選擇字母時使用scrollToPosition(int position)移動到列表中的右側項目。
我無法解決的主要問題不是建立另一個列表,而是兩個列表之間的通信。任何幫助將不勝感激。
我相信這是你一直在尋找的,因爲我有
您可以檢查這些庫這裏的信息:
danoz73/RecyclerViewFastScroller
據我記得他是實際上是在recyclerview中製作第一個字母索引器的人。我從來沒有在我的應用中使用它,因爲定製它有很多問題。
AndroidDeveloperLB/LollipopContactsRecyclerViewFastScroller
自述說hes得到了很多做優化的,所以我覺得這是最好的一個我可以使用,但我還沒有取得它在我的應用程序的工作現在。
code-computerlove/FastScrollRecyclerView
我覺得這是你想要右側的設計?所以你使用的這些庫都應該滿足你的需求。
希望它有助於
如果有人想用以上Xamarin提到的FastScrollRecyclerView,我剛移植的主要類(你仍然需要創建XML資源和預習索引等等等等 - 見原始回購指南,這很簡單)。
我包括在問題頁面中提出的調整,以改善ScrollToPosition和索引高度(這也使它在橫向上工作),並切換爲異步Task.Delay的Java Handler類。它可能仍然有問題,否則它是一個直接的端口。似乎沒問題。希望我救了別人一些時間:)
public interface IFastScrollRecyclerViewAdapter
{
Dictionary<string, int> GetMapIndex();
}
//
public class FastScrollRecyclerView : RecyclerView
{
public const int INDWIDTH = 25;
public const int INDHEIGHT = 18;
public float ScaledWidth { get; set; }
public float ScaledHeight { get; set; }
public string[] Sections { get; set; }
public float Sx { get; set; }
public float Sy { get; set; }
public string Section { get; set; }
public bool ShowLetter { get; set; }
private ListHandler _listHandler;
private bool _setupThings = false;
private Context _context;
public FastScrollRecyclerView(Context context) : base(context)
{
_context = context;
}
public FastScrollRecyclerView(Context context, IAttributeSet attrs) : base(context, attrs)
{
_context = context;
}
public FastScrollRecyclerView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
_context = context;
}
public override void OnDraw(Canvas c)
{
if (!_setupThings && GetAdapter() != null)
SetupThings();
base.OnDraw(c);
}
private void SetupThings()
{
//create az text data
var sectionSet = ((IFastScrollRecyclerViewAdapter)GetAdapter()).GetMapIndex().Keys;
var listSection = new List<string>(sectionSet);
listSection.Sort();
Sections = new string[listSection.Count];
int i = 0;
foreach (var s in listSection)
{
Sections[i++] = s;
}
ScaledWidth = INDWIDTH * _context.Resources.DisplayMetrics.Density;
var divisor = sectionSet.Count == 0 ? 1 : sectionSet.Count;
ScaledHeight = Height/divisor ;// INDHEIGHT * _context.Resources.DisplayMetrics.Density;
Sx = Width - PaddingRight - (float)(1.2 * ScaledWidth);
Sy = (float)((Height - (ScaledHeight * Sections.Length))/2.0);
_setupThings = true;
}
public override bool OnTouchEvent(MotionEvent motionEvent)
{
if (_setupThings)
{
var adapter = GetAdapter() as IFastScrollRecyclerViewAdapter;
var x = motionEvent.GetX();
var y = motionEvent.GetY();
switch (motionEvent.Action)
{
case MotionEventActions.Down:
{
if (x < Sx - ScaledWidth || y < Sy || y > (Sy + ScaledHeight * Sections.Length))
{
return base.OnTouchEvent(motionEvent);
}
else
{
//// We touched the index bar
float yy = y - PaddingTop - PaddingBottom - Sy;
int currentPosition = (int)Math.Floor(yy/ScaledHeight);
if (currentPosition < 0) currentPosition = 0;
if (currentPosition >= Sections.Length) currentPosition = Sections.Length - 1;
Section = Sections[currentPosition];
ShowLetter = true;
int positionInData = 0;
if (adapter.GetMapIndex().ContainsKey(Section.ToUpper()))
{
positionInData = adapter.GetMapIndex()[Section.ToUpper()];
}
(GetLayoutManager() as LinearLayoutManager).ScrollToPositionWithOffset(positionInData, 20);
Invalidate();
}
break;
}
case MotionEventActions.Move:
{
if (!ShowLetter && (x < Sx - ScaledWidth || y < Sy || y > (Sy + ScaledHeight * Sections.Length)))
{
return base.OnTouchEvent(motionEvent);
}
else
{
float yy = y - Sy;
int currentPosition = (int)Math.Floor(yy/ScaledHeight);
if (currentPosition < 0) currentPosition = 0;
if (currentPosition >= Sections.Length) currentPosition = Sections.Length - 1;
Section = Sections[currentPosition];
ShowLetter = true;
int positionInData = 0;
if (adapter.GetMapIndex().ContainsKey(Section.ToUpper()))
positionInData = adapter.GetMapIndex()[Section.ToUpper()];
(GetLayoutManager() as LinearLayoutManager).ScrollToPositionWithOffset(positionInData, 20);
Invalidate();
}
break;
}
case MotionEventActions.Up:
{
_listHandler = new ListHandler(this);
_listHandler.DelayClear();
if (x < Sx - ScaledWidth || y < Sy || y > (Sy + ScaledHeight * Sections.Length))
{
return base.OnTouchEvent(motionEvent);
}
else
{
return true;
}
}
}
}
return true;
}
private class ListHandler
{
FastScrollRecyclerView _parent;
public ListHandler (FastScrollRecyclerView parent)
{
_parent = parent;
}
public async void DelayClear()
{
await Task.Delay(100);
_parent.ShowLetter = false;
_parent.Invalidate();
}
}
}
//
public class FastScrollRecyclerViewItemDecoration : ItemDecoration
{
private Context _context;
public FastScrollRecyclerViewItemDecoration(Context context)
{
_context = context;
}
public override void OnDrawOver(Canvas canvas, RecyclerView parent, State state)
{
base.OnDrawOver(canvas, parent, state);
float scaledWidth = ((FastScrollRecyclerView)parent).ScaledWidth;
float sx = ((FastScrollRecyclerView)parent).Sx;
float scaledHeight = ((FastScrollRecyclerView)parent).ScaledHeight;
float sy = ((FastScrollRecyclerView)parent).Sy;
string[] sections = ((FastScrollRecyclerView)parent).Sections;
string section = ((FastScrollRecyclerView)parent).Section;
bool showLetter = ((FastScrollRecyclerView)parent).ShowLetter;
// We draw the letter in the middle
if (showLetter & section != null && !section.Equals(""))
{
//overlay everything when displaying selected index Letter in the middle
Paint overlayDark = new Paint();
overlayDark.Color = Color.Black;
overlayDark.Alpha = 100;
canvas.DrawRect(0, 0, parent.Width, parent.Height, overlayDark);
float middleTextSize = _context.Resources.GetDimension(Resource.Dimension.fast_scroll_overlay_text_size);
Paint middleLetter = new Paint();
middleLetter.Color = new Color(ContextCompat.GetColor(_context, Resource.Color.primary));
middleLetter.TextSize = middleTextSize;
middleLetter.AntiAlias = true;
middleLetter.FakeBoldText = true;
middleLetter.SetStyle(Paint.Style.Fill);
int xPos = (canvas.Width - (int)middleTextSize)/2;
int yPos = (int)((canvas.Height/2) - ((middleLetter.Descent() + middleLetter.Ascent())/2));
canvas.DrawText(section.ToUpper(), xPos, yPos, middleLetter);
}
// // draw indez A-Z
Paint textPaint = new Paint();
textPaint.AntiAlias = true;
textPaint.SetStyle(Paint.Style.Fill);
for (int i = 0; i < sections.Length; i++)
{
if (showLetter & section != null && !section.Equals("") && section != null
&& sections[i].ToUpper().Equals(section.ToUpper()))
{
textPaint.Color = Color.White;
textPaint.Alpha = 255;
textPaint.FakeBoldText = true;
textPaint.TextSize = scaledWidth/2;
canvas.DrawText(sections[i].ToUpper(),
sx + textPaint.TextSize/2, sy + parent.PaddingTop
+ scaledHeight * (i + 1), textPaint);
textPaint.TextSize = scaledWidth;
canvas.DrawText("•",
sx - textPaint.TextSize/3, sy + parent.PaddingTop
+ scaledHeight * (i + 1) + scaledHeight/3, textPaint);
}
else
{
textPaint.Color = new Color(ContextCompat.GetColor(_context, Resource.Color.primary));
textPaint.Alpha = 200;
textPaint.FakeBoldText = false;
textPaint.TextSize = scaledWidth/2;
canvas.DrawText(sections[i].ToUpper(),
sx + textPaint.TextSize/2, sy + parent.PaddingTop
+ scaledHeight * (i + 1), textPaint);
}
}
}
}
更多真棒!男人你沒救了我。謝謝:) –
@BassemQoulta你的歡迎兄弟,我很高興它幫助:) – david
Xamarin的FastScrollRecyclerView端口:) – Ryan