How can I fetch dx that exist in RecyclerView directly? - android

I am currently experiencing an issue with scrolling my news ticker, similar to those found on news channels. To resolve this issue, I am using the following function to move the news ticker:
rv.smoothScrollBy(0, 0, new LinearInterpolator(), 10000);
-- The first parameter: I am currently unable to determine the correct value for this parameter.
-- The second parameter: As my RecyclerView orientation is horizontal (LinearLayoutManager), I am keeping it set to 0.
-- The third parameter: I do not require any additional effects, so I am using the LinearInterpolator.
-- The fourth parameter: I wish to move from the first scroll position to the last scroll position within the RecyclerView in 10 seconds, regardless of the text length.
Here is what I did to fetch dx
rv1.setAdapter(new CustomAdapter(MainActivity.this, strings));
rv1.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!recyclerView.canScrollHorizontally(1))
Log.w("ABC", "dx is " + dx);
}
});
rv1.smoothScrollBy(100000000, 0);
Is there a way to determine the value for the first parameter without resorting to the workaround I have currently implemented? Specifically, can I fetch the value directly without having to move the scroll to the last position by adding a large number and then determine the dx value?

Related

Very large data makes my application very slow while using ScrollView

I am writing an android application which the whole page is scrollable.
So I've tried to use NestedScrollView but the views of recycle view are created too slow since the data is very large (e.g. more than 1000 records and can be up to 10000 records) then It make my application crashed.
So I am using the code below to fix above problem.
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!recyclerView.canScrollVertically(1))
onScrolledToBottom();
}
});
It can help to reduce the time but the problem changes to be the screen cannot scroll for the whole page.
How can deal with this issue?
ID: < input box >
item1
item2
item3
item4
item5
item6
...
item1000
Pagination is build specifically for this.
You can have a repository which would serve you data .
class YourRepository{
/**
* Offset would indicate the starting index of data that you need
* Count indicates the amount of data you need
**/
List<Data> getData(int count, int offset){}
}
With this api in place, you can use Jetpack Paging library pretty effectively.
https://developer.android.com/topic/libraries/architecture/paging

How to find out which item on focus after scrolling the RecyclerView Android?

How do I get the position of a list item that's on focus after scrolling the RecyclerView? Will this work?
recyclerview1.addOnScrollListener(new RecyclerView.OnScrollListener())
If yes, then how?
Yes there are two ways of doing this.
One using onBindViewHolder , in onBindViewHolder add
Log.d("onBindViewHolder", "position =>"+position);
count++; //for the position
but remember in this way count call several time for each news and you must count only in first call.
Other way around is using layoutManagers i.e LinearLayoutManager or GridLayoutManager by doing this
int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
int lastVisiblePosition = layoutManager.findLastVisibleItemPosition();
OR for scrollListener you can do this
recycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//you can use other methods as per your requirements
Toast.makeText(mContext, "Scrolled to"+layoutManager.findLastCompletelyVisibleItemPosition(), Toast.LENGTH_SHORT).show();
})
Hope this helps you.
I just faced this problem, and i got I put the recyclerView in scrollView So please never put the recyclerview inside the scrollView that may also cause mLayoutManager.findFirstVisibleItemPosition() that always return a fixed value. and also check recyclerview.setNestedScrollingEnabled(false);

Outputting data from the database to the android table with a fixed column

How to output data from a DB in the android table so that the first column at horizontal was fixed (the table rather wide)?
I created 2 ListView: one (lvBrigade) for the first column, the second (lvMain) for the rest of the table (it has a horizontal scroll bar). Each lvBrigade item is 1 TextView. Each lvMain item is a few TextView's. To synchronize the scrolling, I call the listener using the setOnScrollChangeListener method and then obtaining the scrollY coordinate (in this case, the scrollY) of one ListView, I set the scroll coordinate to the second ListView. Of course, it does not work for me. Maybe it can be implemented somehow with the help of other View-elements?
Here the code:
lvMain.setOnScrollChangeListener(new View.OnScrollChangeListener() {
#Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
lvBrigade.scrollTo(0, scrollY);
}
});
I also tried the listeners OnScrollListener and OnTouchListener and also 0 reactions - ListViews do not cling to each other.

scrollBy doesn't work properly in nested recyclerview

I have a vertically scrolling RecyclerView with horizontally scrolling inner RecyclerViews just like this.
With this implementation, users can scroll each horizontal recyclerview synchronously. However, when a user scroll vertically to the parent recyclerView, a new horizontal recyclerview which has just attached on window doesn't display on same scroll x position. This is normal. Because it has just created.
So, I had tried to scroll to the scrolled position before it was displayed. Just like this:
Note: this is in adapter of the parent recyclerview whose orientation is vertical.
#Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
super.onViewAttachedToWindow(holder);
CellColumnViewHolder viewHolder = (CellColumnViewHolder) holder;
if (m_nXPosition != 0) {
// this doesn't work properly
viewHolder.m_jRecyclerView.scrollBy(m_nXPosition, 0);
}
}
As you can see, scrollBy doesn't effect for row 10, row 11, row 12 and row 13 After that, I debugged the code to be able find out find out what's happening. When I set scroll position using scrollBy, childCount() return zero for row 10, row 11, row 12 and row 13 So they don't scroll. But why ? and Why others work ?
How can I fix this ?
Is onViewAttachedToWindow right place to scroll new attached recyclervViews ?
Note: I have also test scrollToPosition(), it doesn't get any problem like this. But I can't use it at my case. Because users can scroll to the any x position which may not the exact position. So I need to set scroll position using x value instead of the position.
Edit: You can check The source code
I found a solution that is use scrollToPositionWithOffset method instead using scrollBy. Even if both of two scroll another position, they have really different work process in back side.
For example: if you try to use scrollBy to scroll any pixel position and your recyclerView had not been set any adapter which means there is no any data to display and so it has no any items yet, then scrollBy doesn't work. RecyclerView uses its layoutManager's scrollBy method. So in my case, I am using LinearLayoutManager to the horizontal recyclerViews.
Lets see what it's doing :
int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getChildCount() == 0 || dy == 0) {
return 0;
}
mLayoutState.mRecycle = true;
ensureLayoutState();
final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START;
final int absDy = Math.abs(dy);
updateLayoutState(layoutDirection, absDy, true, state);
final int consumed = mLayoutState.mScrollingOffset
+ fill(recycler, mLayoutState, state, false);
if (consumed < 0) {
if (DEBUG) {
Log.d(TAG, "Don't have any more elements to scroll");
}
return 0;
}
final int scrolled = absDy > consumed ? layoutDirection * consumed : dy;
mOrientationHelper.offsetChildren(-scrolled);
if (DEBUG) {
Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled);
}
mLayoutState.mLastScrollDelta = scrolled;
return scrolled;
}
As you can see scrollBy ignores the scroll intentions if there is no any child at that time.
if (getChildCount() == 0 || dy == 0) {
return 0;
}
On the other hand scrollToPosition can work perfectly even if there is no any set data yet.
According to the Pro RecyclerView slide, the below sample works perfectly. However you can not do that with scrollBy.
void onCreate(SavedInstanceState state) {
....
mRecyclerView.scrollToPosition(selectedPosition);
mRecyclerView.setAdapter(myAdapter);
}
As a result, I have changed little thing to use scrollToPositionWithOffset().
Before this implementation I was calculating the exact scroll x position as a pixel.
After that, when the scroll came idle state, calculating the first complete visible position to the first parameter of the scrollToPositionWithOffset().
For second parameter which is the offset, I am getting the value using view.getLeft() function which helps to get left position of this view relative to its parent.
And it works perfectly!!

Reycler view and custom parallax effect

I create parallax effect moving the image background depends on location of first element of recycler view only.
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if ((holder = recyclerView.findViewHolderForAdapterPosition(0)) != null) {
int offset = recyclerView.findViewHolderForAdapterPosition(0).itemView.getTop() / 10;
backgroundPhoto.setTop(offset);
}
The problem is : when the first item of recycler(header) scroll off the screen, background picture somehow jump ot initial position.
Once the view is scrolled off the screen the RecyclerView might still be able to access it but it's getTop() value will have some random value or 0 which will cause your parallax effect to jump.
You could keep a field in your class which saves the currently "scrolled distance" and add dx to it in the onScrolled(...) callback and use this value to calculate the parallax offset.

Categories

Resources