Smooth scrolling in scrollView
You have added ScrollView
inside RelativeLayout
, what I suggest is that you should place RelativeLayout
inside ScrollView
tag. Please go through below code,
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/top_string"
android:textColor="@android:color/white"
android:textSize="16dp"
android:textScaleX="1.5"
/>
<ImageView
android:id="@+id/img"
android:layout_width="300dp"
android:layout_height="150dp"
android:src="@drawable/dg_truck_main"
android:layout_gravity="center_horizontal"
android:background="@android:color/holo_blue_light"
android:layout_marginTop="10dp"
android:layout_centerHorizontal="true"
android:layout_below="@id/text_view"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/top_string2"
android:textColor="@android:color/white"
android:textSize="16dp"
android:textScaleX="1.5"
android:layout_marginTop="50dp"
android:layout_below="@id/img"
/>
</RelativeLayout>
</RelativeLayout>
</ScrollView>
RecyclerView - How to smooth scroll to top of item on a certain position?
RecyclerView
is designed to be extensible, so there is no need to subclass the LayoutManager
(as droidev suggested) just to perform the scrolling.
Instead, just create a SmoothScroller
with the preference SNAP_TO_START
:
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(context) {
@Override protected int getVerticalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_START;
}
};
Now you set the position where you want to scroll to:
smoothScroller.setTargetPosition(position);
and pass that SmoothScroller to the LayoutManager:
layoutManager.startSmoothScroll(smoothScroller);
Smooth scrolling in Android
I have no experience with OpenGL nor accelerometer, but swipe (called fling in Android's API) is not hard to achieve. First thing you need when making such a custom View
, is implementing a GestureDetector
and call its onTouchEvent()
in your view's onTouchEvent()
GestureDetector mGD = new GestureDetector(getContext(),
new SimpleOnGestureListener() {
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// beware, it can scroll to infinity
scrollBy((int)distanceX, (int)distanceY);
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float vX, float vY) {
mScroller.fling(getScrollX(), getScrollY(),
-(int)vX, -(int)vY, 0, (int)mMaxScrollX, 0, (int)mMaxScrollY);
invalidate(); // don't remember if it's needed
return true;
}
@Override
public boolean onDown(MotionEvent e) {
if(!mScroller.isFinished() ) { // is flinging
mScroller.forceFinished(true); // to stop flinging on touch
}
return true; // else won't work
}
});
@Override
public boolean onTouchEvent(MotionEvent event) {
return mGD.onTouchEvent(event);
}
While OnGestureListener.onScroll()
calls directly View.scrollBy()
, for the onFling()
method you'll need a Scroller
.
Scroller
is a simple object that, as reference says, encapsulates scrolling. It can be used for continuous scrolling or to react to flings. Scroller.fling() begin a "simulation" of fling scroll inside itself, and by watching it you can copy its smoothness with a continuous redrawing animation:
@Override
protected void onDraw(Canvas canvas) {
// ....your drawings....
// scrollTo invalidates, so until animation won't finish it will be called
// (used after a Scroller.fling() )
if(mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
}
}
that is, until animation is running, calculate the point we reached and scroll there.
As a last note: remember to return true
in your OnGestureListener.onDown()
, even if you don't want to do anything on down, or it won't work.
And be careful, because Scroller
in Android 2.2 has a bug for which the fling animation will not actually end even if it reaches the limits you passed as arguments (yet computed offset respects them, so it won't actually move).
How to make RecyclerView scroll smoothly?
The typical source of "jerky" scrolling in Android is the app taking too much time on the main application thread updating the UI. In the case of RecyclerView
, this would mean taking too much time in onBindViewHolder()
or possibly in onCreateViewHolder()
. Those each need to return in sub-millisecond times, meaning you cannot do disk I/O or network I/O in them.
think I found the problem. I am using holder.photo.setImageBitmap(BitmapFactory.decodeFile(itemList.get(position).getAbsolutePath())); on onBindViewHolder() and the image file is around 100kb each with about a dozen images in the list
Yes, that will be doing disk I/O and image decoding on the main application thread. That will be slow enough to cause jank in the UI (i.e., "jerky" scrolling).
Consider using an image loading library, like Picasso or Universal Image Loader, as they can populate your ImageView
from the bitmap asynchronously.
This sample app uses Universal Image Loader to help populate the contents of a RecyclerView
(with GridLayoutManager
), with the data source being the available videos on the device.
smooth scrolling for recyclerview
Its because your recycler view is inside a nested Scroll view.
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycle2"
android:nestedScrollingEnabled="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
also in your code do this to support older devices :
recyclerView.setNestedScrollingEnabled(false);
Auto smooth scrolling in Recycler view
I found this method and it works for me:
recyclerView.smoothScrollBy(dx, dy, new LinearInterpolator(), time);
Recyclerview inside ScrollView not scrolling smoothly
Try doing:
RecyclerView v = (RecyclerView) findViewById(...);
v.setNestedScrollingEnabled(false);
As an alternative, you can modify your layout using the support design library. I guess your current layout is something like:
<ScrollView >
<LinearLayout >
<View > <!-- upper content -->
<RecyclerView > <!-- with custom layoutmanager -->
</LinearLayout >
</ScrollView >
You can modify that to:
<CoordinatorLayout >
<AppBarLayout >
<CollapsingToolbarLayout >
<!-- with your content, and layout_scrollFlags="scroll" -->
</CollapsingToolbarLayout >
</AppBarLayout >
<RecyclerView > <!-- with standard layoutManager -->
</CoordinatorLayout >
However this is a longer road to take, and if you are OK with the custom linear layout manager, then just disable nested scrolling on the recycler view.
Edit (4/3/2016)
The v 23.2
release of the support libraries now includes a factory “wrap content” feature in all default LayoutManager
s. I didn’t test it, but you should probably prefer it to that library you were using.
<ScrollView >
<LinearLayout >
<View > <!-- upper content -->
<RecyclerView > <!-- with wrap_content -->
</LinearLayout >
</ScrollView >
LazyColumnFor is not smooth scrolling
Currently (version 1.0.0-alpha02
) Jetpack Compose has 2 Composable functions for loading image resources:
imageResource()
: this Composable function, load an image resource synchronously.loadImageResource()
: this function loads the image in a background thread, and once the loading finishes, recompose is scheduled and this function will return deferred image resource withLoadedResource
orFailedResource
So your lazyColumn
is not scrolling smoothly since you are loading images synchronously.
So you should either use loadImageResource()
or a library named Accompanist
by Chris Banes, which can fetch and display images from external sources, such as network, using the Coil image loading library.
UPDATE:
Using CoilImage
:
First, add Accompanist Gradle dependency, then simply use CoilImage
composable function:
CoilImage(data = R.drawable.header)
Using loadImageResource()
:
val deferredImage = loadImageResource(
id = R.drawable.header,
)
val imageModifier = Modifier.preferredHeight(150.dp).fillMaxWidth()
.clip(shape = RoundedCornerShape(8.dp))
deferredImage.resource.resource?.let {
Image(
asset = it,
modifier = imageModifier
)
}
Note: I tried both ways in a LazyColumnFor
, and although loadImageResource()
performed better than imageResource()
but still it didn't scroll smoothly.
So I highly recommend using CoilImage
Note 2: To use Glide or Picasso, check this repository by Vinay Gaba
Related Topics
Android Take Screen Shot Programmatically
How to Crop an Image in Android
Parse JSON Array Without Key in Android
How to List Files in an Android Directory
How to Set Custom Font for a Whole Application in Android
How to Create Preference Activity and Preference Fragment on Android
Android: How to Get Value of an Attribute in Code
How to Add "Go Back" Function in Webview Inside Fragment
Custom Info Window Adapter with Custom Data in Map V2
Facebook - "Cannot Query Users by Their Username" Solution
How to Always Run a Service in the Background
Set Dynamic Base Url Using Retrofit 2.0 and Dagger 2