Recyclerview With Alphabet Index
Solution 1:
I believe this is the information you have been looking for as I have
You can check these libraries here:
danoz73/RecyclerViewFastScroller
as far as I remember he is the one who actually made the first alphabet indexer in recyclerview. I never made it work in my app because there was lots of problem customizing it.
AndroidDeveloperLB/LollipopContactsRecyclerViewFastScroller
the readme said hes got lots of optimizations made, So i think this is the best one i could use, but i havent made it work in my app for now.
code-computerlove/FastScrollRecyclerView
I think this is the design you want right? So either of these libs you used it should suffice your needs.
hope it helps
Solution 2:
If anyone would like to use the FastScrollRecyclerView mentioned above in Xamarin, I just ported the main classes (you'll still need to create the xml resource and prep your index etc etc - see the original repo for a guide, it's pretty simple).
I included the tweaks suggested in the issues page to improve the ScrollToPosition and index height (which also makes it work in landscape) and also switched out the Java Handler class for an async Task.Delay. It may still have issues, it's a straight port otherwise. Seems to be ok though. Hopefully I have saved someone some time :)
publicinterfaceIFastScrollRecyclerViewAdapter
{
Dictionary<string, int> GetMapIndex();
}
//
publicclassFastScrollRecyclerView : RecyclerView
{
publicconstint INDWIDTH = 25;
publicconstint INDHEIGHT = 18;
publicfloat ScaledWidth { get; set; }
publicfloat ScaledHeight { get; set; }
publicstring[] Sections { get; set; }
publicfloat Sx { get; set; }
publicfloat Sy { get; set; }
publicstring Section { get; set; }
publicbool ShowLetter { get; set; }
private ListHandler _listHandler;
privatebool _setupThings = false;
private Context _context;
publicFastScrollRecyclerView(Context context) : base(context)
{
_context = context;
}
publicFastScrollRecyclerView(Context context, IAttributeSet attrs) : base(context, attrs)
{
_context = context;
}
publicFastScrollRecyclerView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
_context = context;
}
publicoverridevoidOnDraw(Canvas c)
{
if (!_setupThings && GetAdapter() != null)
SetupThings();
base.OnDraw(c);
}
privatevoidSetupThings()
{
//create az text datavar sectionSet = ((IFastScrollRecyclerViewAdapter)GetAdapter()).GetMapIndex().Keys;
var listSection = new List<string>(sectionSet);
listSection.Sort();
Sections = newstring[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;
}
publicoverrideboolOnTouchEvent(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))
{
returnbase.OnTouchEvent(motionEvent);
}
else
{
//// We touched the index barfloat 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)))
{
returnbase.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))
{
returnbase.OnTouchEvent(motionEvent);
}
else
{
returntrue;
}
}
}
}
returntrue;
}
privateclassListHandler
{
FastScrollRecyclerView _parent;
publicListHandler (FastScrollRecyclerView parent)
{
_parent = parent;
}
publicasyncvoidDelayClear()
{
await Task.Delay(100);
_parent.ShowLetter = false;
_parent.Invalidate();
}
}
}
//
publicclassFastScrollRecyclerViewItemDecoration : ItemDecoration
{
private Context _context;
publicFastScrollRecyclerViewItemDecoration(Context context)
{
_context = context;
}
publicoverridevoidOnDrawOver(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 middleif (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);
}
}
}
}
Post a Comment for "Recyclerview With Alphabet Index"