anon
anon

Reputation:

Cardview ScrollX/ScrollY are 0 in ScrollView

I'm trying to scroll to the top of a CardView that is a grand child of a ScrollView through a vertical LinearLayout.

Here is the layout:

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

Here is my code:

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

The result is that The scroll ends on the top of the next cardview, which is weird...

I've noticed that CardView.ScrollX/ScrollY are 0. I suppose this is the normal behavior as CardView is not a direct child of the ScrollView. This is why I'm using the top x coordinate of the CardView.

Upvotes: 4

Views: 514

Answers (2)

Mehmed
Mehmed

Reputation: 3040

If don't know Xamarin but let me explain the probable solution in native Android.

If we put your code in onCreate method as follows, we would get no scroll at all:

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

The problem is that we get the top value of the cardview before it is drawn which results in 0. You can either add a tree observer to the layout or update the code as follows:

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

Now you should get the desired scroll to the top of desired cardview at app launch.

As for your code, it may be turned into this to get the same effect:

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

Upvotes: 2

Cherry Bu - MSFT
Cherry Bu - MSFT

Reputation: 10346

If you want to implement scroll CardView in Linearlayout, I suggest you can use android.support.v7.widget.RecyclerView to to this, here is the sample in github, you can take a look:

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

Upvotes: 0

Related Questions