How to load the Listview smoothly in android
I will describe you how to get such issue that you have. Possibly this will help you.
So, in list adapter you have such code:
public View getView(int position, View contentView, ViewGroup arg2)
{
ViewHolder holder;
if (contentView == null) {
holder = new ViewHolder();
contentView = inflater.inflate(R.layout.my_magic_list,null);
holder.label = (TextView) contentView.findViewById(R.id.label);
contentView.setTag(holder);
} else {
holder = (ViewHolder) contentView.getTag();
}
holder.label.setText(getLabel());
return contentView;
}
As you can see, we set list item value only after we have retrieved holder.
But if you move code into above if statement:
holder.label.setText(getLabel());
so it will look after like below:
if (contentView == null) {
holder = new ViewHolder();
contentView = inflater.inflate(R.layout.my_magic_list,null);
holder.label = (TextView) contentView.findViewById(R.id.label);
holder.label.setText(getLabel());
contentView.setTag(holder);
}
you will have your current application behavior with list item duplication.
Possibly it will help.
Make ListView Scroll Smoothly
You should use recyclerView
instead. It is a more advanced and flexible version of ListView. Go through https://developer.android.com/guide/topics/ui/layout/recyclerview for guide.
If you want to stick with ListView then in order to improve the performance you should recycle/reuse the views that are no longer visible to the user.
public View getView(final int i, View convertView, ViewGroup viewGroup) {
Holder holder = null;
if(convertView == null){
convertView = inflater.inflate(R.layout.contact_inflater, null);
final Holder holder = new ContactAdapter.Holder();
holder.ivPhoto = (ImageView) convertView.findViewById(R.id.ivImage);
holder.tvFullName = (TextView) convertView.findViewById(R.id.tvName);
holder.tvPhoneNumber = (TextView) convertView.findViewById(R.id.tvPhoneNo);
holder.button = (Button) convertView.findViewById(R.id.ivButton);
convertView.setTag(holder)
}
else{
holder = (Holder)convertView.getTag()
}
holder.tvFullName.setText(Contact.get(i).get(0));
holder.tvPhoneNumber.setText(Contact.get(i).get(1));
Picasso.with(context)
.load(Contact.get(i).get(2))
.into(holder.ivPhoto);
return convertView;
}
Listview - How do I do a smooth scroll to top from the 10th item?
See this answer.
Quote:
First call smothScrollToPositionFromTop(position) and then, when
scrolling has finished, call setSelection(position). The latter call
corrects the incomplete scrolling by jumping directly to the desired
position. Doing so the user still has the impression that it is being
animation-scrolled to this position.
How to smooth the movement of a list item at a specific position
Try this:
@Override
public void onScrollStateChanged(final AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE) {
View firstView = view.getChildAt(0);
Rect rect = new Rect(0, 0, firstView.getWidth(), firstView.getHeight());
view.getChildVisibleRect(firstView, rect, null);
int position = view.getFirstVisiblePosition();
if (rect.height() < (firstView.getHeight() / 2)) {
position++;
}
final int finalPosition = position;
view.postDelayed(new Runnable() {
@Override
public void run() {
view.smoothScrollToPositionFromTop(finalPosition, 0, 500);
}
}, 1);
}
}
Updated:
Above code has a constant settling time (500ms). Below code has a constant snap speed (0.2 pixel/ms, it means scroll up/down a pixel takes 5ms).
final static int SCROLL_TIME_PER_PIXEL = 5; // Time(ms) to snap a pixel.
@Override
public void onScrollStateChanged(final AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE) {
View firstView = view.getChildAt(0);
Rect rect = new Rect(0, 0, firstView.getWidth(), firstView.getHeight());
view.getChildVisibleRect(firstView, rect, null);
int position = view.getFirstVisiblePosition();
int offset = rect.height();
if (rect.height() < (firstView.getHeight() / 2)) {
position++;
} else offset = firstView.getHeight() - rect.height();
final int finalPosition = position; // Snap to position.
final int finalOffset = offset; // Snap distance in pixels.
view.postDelayed(new Runnable() {
@Override
public void run() {
view.smoothScrollToPositionFromTop(finalPosition, 0, finalOffset * SCROLL_TIME_PER_PIXEL);
}
}, 1);
}
}
Use Loader to load listview data in backgroud for smooth scrolling
To improve speed of your listview your must complete next steps:
Use ViewHolder patter because view.findViewById is slow operation.
You can load all needed typeface before. Your every time load same typefaces. For example
Typeface.createFromAsset(context.getAssets(), "Roboto_Light.ttf")
You can load all zodiac icon before because i think that zodiac icon has limit count
if photo is big image than you can load image from another thread.
I think it is enough.
Related Topics
Splash Screen While Loading a Url in a Webview in Android App
How to Set Build and Version Number of Flutter App
Startactivityforresult from Activitygroup
Attempt to Reopen an Already-Closed Object SQLitedatabase
Objectanimator Animate Linearlayout Width
How to Set Camera Image Orientation
How to Create a Floating Action Button (Fab) in Android, Using Appcompat V21
Howto Do a Simple Ftp Get File on Android
CSS3 Animation Flicker on Android 2.2 (Webkit-Transform:Translate(..) Scale(..) at The Same Time)
Why Does Calling Getwidth() on a View in Onresume() Return 0
Signing an APK with an Upload Key Provided by Google Play
How Open New Activity Clicking an Item in Listview
A Pre-Populated Database Does Not Work at API 28 Throws "No Such Table" Exception
Android Layout with Square Buttons
Difference Between Android Dimension: Pt and Dp
Value <Br of Type Java.Lang.String Cannot Be Converted to JSONobject on Android