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