在 NestedScrollView 中获取第一个可见视图

Get first visible view inside of NestedScrollView

我有下一个问题。

我正在尝试获取 NestedScrollView 中的第一个可见项。实际上,第一个也是唯一一个内部视图是 LinearLayout(因为滚动视图只能容纳一个直接子视图),但我试图在其中获取第一个可见项目。我搜索了很多但没有成功。

通过这种方法,我想避免在另一个 RecyclerView 中使用 RecyclerView。我发现这是一种不好的做法。

P.S。我不想使用 ListView 或 RecyclerView

提前致谢

对于此布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/nestedScrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/ly"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:text="text_1"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:text="text_2" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:text="text_3" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:text="text_4" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:text="text_5" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:text="text_6" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:text="text_7" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:text="text_8" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:text="text_9" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="100dp"
            android:text="text_10" />


    </LinearLayout>
</android.support.v4.widget.NestedScrollView>

并使用此代码

  public class MainActivity extends AppCompatActivity {

    NestedScrollView nestedScrollView;
    LinearLayout linearLayout;

    ArrayList<Integer> childrenY = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //find view
        nestedScrollView = (NestedScrollView) findViewById(R.id.nestedScrollView);
        linearLayout = (LinearLayout) nestedScrollView.getChildAt(0);


        //get Y Children and save
        for (int i = 0; i < linearLayout.getChildCount(); i++) {

            int childrenY = 0;
            for (int j = 0; j < i; j++) {
                TextView tv = (TextView) linearLayout.getChildAt(j);
                Log.i("--------", tv.getText().toString());
                childrenY += tv.getLayoutParams().height;
            }
            this.childrenY.add(childrenY);
        }

        //add Scroll Change Listener
        nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

                for (int i = 0; i < childrenY.size(); i++) {
                    if (scrollY < childrenY.get(i)) {
                        Log.i("++++++++++", ((TextView) linearLayout.getChildAt(i-1)).getText().toString());
                        return;
                    }
                }
            }
        });
    }
}

如果你想在 NestedScrollView 的内部 LinearLayout 中找到第一个可见项,你可以试试这个:

    if(nsv.getChildCount() > 0) {
        ViewGroup vg = (ViewGroup) nsv.getChildAt(0);
        for (int i = 0; i < vg.getChildCount(); i++) {
            if(vg.getChildAt(i).getVisibility()==View.VISIBLE)
                return vg.getChildAt(i);
        }
    }

    return null;

其中 nsv 是您的 NestedScrollView。

好的,我找到了解决方案:

        final Rect scrollBounds = new Rect();
        questionAndAnswerScroll.getHitRect(scrollBounds);
        questionAndAnswerScroll.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                for (int i = 0; i < questionAndAnswerHolder.getChildCount(); i++) {
                    View childView = questionAndAnswerHolder.getChildAt(i);
                    if (childView != null) {
                        if (childView.getLocalVisibleRect(scrollBounds)) {
                            //Here is the position of first visible view
                            positionToScroll = i;
                            break;
                        }
                    }
                }
            }
        });