Why is findFirstVisibleItemPosition not working as expected?
I have been struggling with this problem for a long time, I am trying to replace my list with recyclerview and my list looks like this: -
<ListView
android:id="@+id/browser_sub_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:clipToPadding="false"
android:drawSelectorOnTop="true"
android:paddingTop="340dp"/>
Now when I call
view.getFirstVisiblePosition();
In this list, I am returning the position of the first element, which is zero, and since I gave top padding, so it will continue to only return zero until the first element is associated with screens.
But when I try to do the same with the recyclerview, even if the first item of the recyclerview is still visible, it gives me different values โโof the firstvisible item, and this is because the recyclerview thinks that toppadding as an anchored screen now I have no hint how to solve this problem. Please, help.
Here is my code.
MainActivity.Java
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private TheAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
ArrayList<String> items = new ArrayList<>();
for (int i = 0; i < 300; i++) {
items.add("This is item:-" + i);
}
adapter = new TheAdapter(items);
mRecyclerView.setAdapter(adapter);
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
Log.d("DISTANCE", "" + linearLayoutManager.findFirstVisibleItemPosition());
}
});
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:clipToPadding="false"
android:paddingTop="340dp"
android:layout_height="match_parent"
/>
</RelativeLayout>
this is my adapter class
class TheAdapter extends RecyclerView.Adapter<TheAdapter.ItemHolder> {
public TheAdapter(ArrayList<String> data) {
mData = data;
}
private ArrayList<String> mData;
@Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ItemHolder(view);
}
@Override
public void onBindViewHolder(ItemHolder holder, int position) {
holder.mTextView.setText(mData.get(position));
}
@Override
public int getItemCount() {
return mData == null ? 0 : mData.size();
}
public class ItemHolder extends RecyclerView.ViewHolder {
private TextView mTextView;
public ItemHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(R.id.textTitle);
}
}
}
source to share
Until you find a better answer, you can try the following code. int pos
is the position reported findFirstVisibleItemPosition()
. This method will return the topmost visible position at RecyclerView
.
public int findRealFirstVisibleItemPosition(int pos) {
View view;
final LinearLayoutManager linearLayoutManager =
(LinearLayoutManager) mRecyclerView.getLayoutManager();
while (pos > 0) {
view = linearLayoutManager.findViewByPosition(pos - 1);
if (view == null) {
break;
}
pos = pos - 1;
}
return pos;
}
I seem to remember that a lot of padding causes these types of scrollview issues.
source to share