I am trying to get into Android app development with a small walk-duration per route app.
But a little glitch is stopping me from continuing.
I tried to google it many times with no result, here's the thing:
My RecyclerView
with onClick-expand cards
shows strange behavior of reloading the whole list as soon as I add too many items in it. Also it moves the whole list down somehow for a second.
As a reference here's my github project: https://github.com/TheInsayn/velocity
Here's how it should behave:
Imgur
but after I've added a 6th items it behaves like this:
Here's the code I've used for the adapter (especially onBindViewHolder
with isExpanded
):
I even used Google's reference-suggestion from I/O 2016. (I don't really want to use a 3rd party lib)
class RecyclerAdapterWalks extends RecyclerView.Adapter<RecyclerAdapterWalks.WalkCardHolder> {
private List<Walk> mWalkList;
private RecyclerView mRecyclerView;
private int mExpandedPosition = -1;
class WalkCardHolder extends RecyclerView.ViewHolder {
TextView mWalkRoute;
TextView mWalkDuration;
TextView mWalkDate;
TextView mWalkWeekday;
RelativeLayout mExpansion;
TextView mAverageTime;
WalkCardHolder(View view) {
super(view);
mWalkRoute = view.findViewById(R.id.txt_walk_route);
mWalkDuration = view.findViewById(R.id.txt_walk_duration);
mWalkDate = view.findViewById(R.id.txt_walk_date);
mWalkWeekday = view.findViewById(R.id.txt_walk_weekday);
mExpansion = view.findViewById(R.id.walk_card_expansion);
mAverageTime = view.findViewById(R.id.txt_walk_average);
}
}
RecyclerAdapterWalks(List<Walk> routes, RecyclerView rv) {
mWalkList = routes;
mRecyclerView = rv;
setHasStableIds(true);
}
@Override
public WalkCardHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_walk, parent, false);
return new WalkCardHolder(view);
}
@Override
public void onBindViewHolder(WalkCardHolder holder, int position) {
Walk walk = mWalkList.get(position);
holder.mWalkRoute.setText(walk.getRoute().getName());
holder.mWalkDuration.setText(DateFormat.format("mm:ss", new Date(walk.getDuration())));
holder.mWalkDate.setText(DateFormat.format("dd.MM.yyyy", walk.getDate()));
holder.mWalkWeekday.setText(DateFormat.format("EEEE", walk.getDate()));
//handle expansion in list
final boolean isExpanded = position == mExpandedPosition;
holder.mExpansion.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
holder.itemView.setActivated(isExpanded);
holder.itemView.setOnClickListener(v -> {
mExpandedPosition = isExpanded ? -1 : position;
TransitionManager.beginDelayedTransition(mRecyclerView);
notifyDataSetChanged();
});
if (isExpanded) {
Date avg = new Date(walk.getRoute().getAverageWalkTime(mRecyclerView.getContext()));
CharSequence min = DateFormat.format("m", avg);
CharSequence sec = DateFormat.format("s", avg);
String boldText = walk.getRoute().getName();
String timeStr = "average walk duration for " + boldText + ": ";
if (!min.equals("0")) timeStr += min + "m and ";
timeStr += sec + "s";
int idx = timeStr.indexOf(boldText);
SpannableString str = new SpannableString(timeStr);
str.setSpan(new StyleSpan(Typeface.BOLD), idx, idx + boldText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
holder.mAverageTime.setText(str);
}
}
@Override
public int getItemCount() {
return mWalkList.size();
}
I have CardView in a RecyclerView in a CoordinatorLayout in a FrameLayout in a RelativeLayout...
Does anybody have an idea what might cause this?
Sorry for the long post and thanks for any help. :)
Edit: using setHasStableIds(true)
in the Adapter's constructor seems to help a bit.
but now the Transition is far from smooth.
small list (worse):
Imgur
longer list (better):
Imgur