【问题标题】:Why findFirstVisibleItemPosition doesn't work as expected?为什么 findFirstVisibleItemPosition 不能按预期工作?
【发布时间】:2017-07-18 16:44:58
【问题描述】:

我在这个问题上苦苦挣扎了很长时间,我试图用 recyclerview 替换我的列表视图,我的列表视图看起来像这样:-

<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"/>

现在当我打电话时

view.getFirstVisiblePosition(); 

在此列表视图中,我返回第一项的位置为零,并且由于我已给出顶部填充,因此它将一直仅返回零,直到第一项超出屏幕范围。

但是,当我尝试对 recyclerview 做同样的事情时,即使 recyclerview 的第一个项目仍然可见,它给我的 firstvisible 项目的值也不同,这是因为 recyclerview 认为 toppadding 现在是屏幕绑定我没有任何线索如何解决这个问题。 请帮忙。

这是我的代码。

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>

这是我的适配器类

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);
        }
    }
}

【问题讨论】:

  • 这完全是狂野的,行为是违反直觉的。您是否有参考表明这是正确的行为?看起来android:clipToPadding="false" 不被findFirstVisibleItemPosition() 认可。
  • 对不起,我没有任何参考资料,但从技术上讲,如果第一项仍然可见,那么为什么要跳转到第二项 android:clipToPadding="false" 在 listview 中得到尊重.可能我应该发布示例项目。

标签: android listview android-recyclerview


【解决方案1】:

在您找到更好的答案之前,您可以尝试以下代码。 int posfindFirstVisibleItemPosition() 报告的位置。此方法将返回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;
}

我似乎记得大填充会导致这些类型的滚动视图问题。

【讨论】:

  • 如果被接受,这是一个完美的答案,但如果它是带有两列的 gridlayoutmanager,我不知道如何处理它,因为它以 0、2、4 的顺序返回我,这显然是正确的,所以我划分了 position/2 但如果您也有任何使用 gridlayoutmanger 的解决方案,它几乎是完美的,请也为此更新它。
猜你喜欢
  • 2021-05-30
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多