Cardview ScrollX/ScrollY 在 ScrollView 中为 0

Cardview ScrollX/ScrollY are 0 in ScrollView

我试图通过垂直 LinearLayout 滚动到 CardView 的顶部,它是 ScrollView 的孙子。

布局如下:

<ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/scroll_view" android:fillViewport="true">
  <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/background_color">
    <!-- Quality of Life -->
    <android.support.v7.widget.CardView android:id="@+id/cardViewQOL" android:layout_margin="8sp" android:layout_marginBottom="8sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" cardview:cardElevation="4sp"
      cardview:cardCornerRadius="5sp" cardview:contentPaddingTop="10sp" cardview:contentPaddingBottom="10sp" cardview:contentPaddingRight="10sp" cardview:contentPaddingLeft="10sp">
      <include layout="@layout/qualityoflife" android:layout_width="fill_parent" android:layout_height="fill_parent" />
    </android.support.v7.widget.CardView>
    <!-- Goals -->
    <android.support.v7.widget.CardView android:id="@+id/cardViewGoals" android:layout_margin="8sp" android:layout_marginBottom="8sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" cardview:cardElevation="4sp"
      cardview:cardCornerRadius="5sp" cardview:contentPaddingTop="10sp" cardview:contentPaddingBottom="10sp" cardview:contentPaddingRight="10sp" cardview:contentPaddingLeft="10sp">
      <include layout="@layout/goals" android:layout_width="fill_parent" android:layout_height="fill_parent" />
    </android.support.v7.widget.CardView>
    <!-- Daily routines -->
    <android.support.v7.widget.CardView android:id="@+id/cardViewDH" android:layout_margin="8sp" android:layout_marginBottom="8sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" cardview:cardElevation="4sp"
      cardview:cardCornerRadius="5sp" cardview:contentPaddingTop="10sp" cardview:contentPaddingBottom="10sp" cardview:contentPaddingRight="10sp" cardview:contentPaddingLeft="10sp">
      <include layout="@layout/dailyroutines" android:layout_width="fill_parent" android:layout_height="fill_parent" />
    </android.support.v7.widget.CardView>
    <!-- Weekly routines -->
    <android.support.v7.widget.CardView android:id="@+id/cardViewWH" android:layout_margin="8sp" android:layout_marginBottom="8sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" cardview:cardElevation="4sp"
      cardview:cardCornerRadius="5sp" cardview:contentPaddingTop="10sp" cardview:contentPaddingBottom="10sp" cardview:contentPaddingRight="10sp" cardview:contentPaddingLeft="10sp">
      <include layout="@layout/weeklyroutines" android:layout_width="fill_parent" android:layout_height="fill_parent" />
    </android.support.v7.widget.CardView>
    <!-- Monthly routines -->
    <android.support.v7.widget.CardView android:id="@+id/cardViewMH" android:layout_margin="8sp" android:layout_marginBottom="4sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" cardview:cardElevation="4sp"
      cardview:cardCornerRadius="5sp" cardview:contentPaddingTop="10sp" cardview:contentPaddingBottom="10sp" cardview:contentPaddingRight="10sp" cardview:contentPaddingLeft="10sp">
      <include layout="@layout/monthlyroutines" android:layout_width="fill_parent" android:layout_height="fill_parent" />
    </android.support.v7.widget.CardView>
    <android.support.v7.widget.CardView android:id="@+id/cardViewExperiences" android:layout_margin="8sp" android:layout_marginBottom="8sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal"
      cardview:cardElevation="4sp" cardview:cardCornerRadius="5sp" cardview:contentPaddingTop="10sp" cardview:contentPaddingBottom="10sp" cardview:contentPaddingRight="10sp" cardview:contentPaddingLeft="10sp">
      <include layout="@layout/experiences" android:layout_width="fill_parent" android:layout_height="fill_parent" />
    </android.support.v7.widget.CardView>
    <android.support.v7.widget.CardView android:id="@+id/cardViewConfigNeeded" android:layout_margin="8sp" android:layout_marginBottom="8sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal"
      cardview:cardElevation="4sp" cardview:cardCornerRadius="5sp" cardview:contentPaddingTop="10sp" cardview:contentPaddingBottom="10sp" cardview:contentPaddingRight="10sp" cardview:contentPaddingLeft="10sp" android:visibility="gone">
      <include layout="@layout/configneeded" android:layout_width="fill_parent" android:layout_height="wrap_content" />
    </android.support.v7.widget.CardView>
  </LinearLayout>
</ScrollView>

这是我的代码:

CardView dailyHabits = FindViewById<CardView>(Resource.Id.cardViewDH);
int y = dailyHabits.Top;
ScrollView scrollView = FindViewById<ScrollView>(Resource.Id.scroll_view);
scrollView.Post(() => scrollView.SmoothScrollTo(0, y));

结果是滚动结束在下一个cardview的顶部,这很奇怪...

我注意到 CardView.ScrollX/ScrollY 为 0。我想这是正常行为,因为 CardView 不是 ScrollView 的直接子级。这就是我使用 CardView 顶部 x 坐标的原因。

如果你想在Linearlayout中实现滚动CardView,我建议你可以使用android.support.v7.widget.RecyclerView来实现,这里是示例github,你可以看看:

https://github.com/xamarin/monodroid-samples/tree/master/android5.0/RecyclerViewer

如果不了解 Xamarin,但让我用本机解释可能的解决方案 Android。

如果我们将您的代码按如下方式放入 onCreate 方法中,我们将根本无法滚动:

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

    CardView dailyHabits = findViewById(R.id.cardViewDH);
    final int y = dailyHabits.getTop();
    final ScrollView scrollView = findViewById(R.id.scroll_view);
    scrollView.post(new Runnable() {
        @Override
        public void run() {
            scrollView.smoothScrollTo(0, y);
        }
    });
}

问题是我们在绘制 cardview 之前获取了 top 值,结果为 0。您可以将树观察器添加到布局或更新代码如下:

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

    final ScrollView scrollView = findViewById(R.id.scroll_view);
    final CardView dailyHabits = findViewById(R.id.cardViewDH);
    dailyHabits.post(new Runnable() {   // could be scrollView
        @Override
        public void run() {
            int y = dailyHabits.getTop();
            scrollView.smoothScrollTo(0, y);
        }
    });
}

现在您应该在应用程序启动时将所需的滚动条滚动到所需的卡片视图的顶部。

至于你的代码,为了达到同样的效果,可能会变成这样:

CardView dailyHabits = FindViewById<CardView>(Resource.Id.cardViewDH);
ScrollView scrollView = FindViewById<ScrollView>(Resource.Id.scroll_view);
scrollView.Post(() => scrollView.SmoothScrollTo(0, dailyHabits.Top));