I've grabbed Google IO app source code and check how they perfectly place the FAB button in the middle of two views (as in the attached screenshot). It's strange that there's no vertical positioning params of the button, there are just height
, width
, as in the two layout files, scroll to the very bottom of the layout file to see the include part of FAB.
Am I missing anything? Thanks.
<com.google.samples.apps.iosched.ui.widget.ObservableScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:iosched="http://schemas.android.com/apk/res-auto"
xmlns:plus="http://schemas.android.com/apk/lib/com.google.android.gms.plus"
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:fillViewport="true"
android:background="#fff">
<FrameLayout
android:id="@+id/scroll_view_child"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false">
<!-- Background photo -->
<FrameLayout android:id="@+id/session_photo_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/session_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
</FrameLayout>
<LinearLayout android:id="@+id/details_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:paddingTop="16dp"
android:paddingRight="@dimen/keyline_1"
android:paddingBottom="@dimen/session_details_extra_space_bottom"
android:clipToPadding="false">
<com.google.samples.apps.iosched.ui.widget.MessageCardView
android:id="@+id/live_now_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
iosched:messageText="@string/session_live_now_message"
iosched:button1text="@string/no_thanks"
iosched:button2text="@string/watch_now"
iosched:button2tag="WATCH_NOW"
iosched:button2emphasis="true"
iosched:emphasisColor="@color/theme_accent_2"
iosched:cardBackgroundColor="#fff"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginBottom="16dp"
android:visibility="gone"
/>
<com.google.samples.apps.iosched.ui.widget.MessageCardView
android:id="@+id/give_feedback_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
iosched:messageText="@string/session_give_feedback_message"
iosched:button1text="@string/no_thanks"
iosched:button2text="@string/give_feedback"
iosched:button2tag="GIVE_FEEDBACK"
iosched:button2emphasis="true"
iosched:cardBackgroundColor="#fff"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginBottom="16dp"
android:visibility="gone"
/>
<TextView android:id="@+id/time_hint"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginBottom="8dp"
style="@style/SessionTimeHint" />
<TextView android:id="@+id/session_abstract"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginBottom="16dp"
style="@style/TextBody"
/>
<com.google.android.gms.plus.PlusOneButton
android:id="@+id/plus_one_button"
style="@style/SessionDetailPlusOne"
android:clickable="true"
android:focusable="true"
plus:annotation="inline"
plus:size="standard"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
/>
<HorizontalScrollView android:id="@+id/session_tags_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:scrollbars="none"
android:requiresFadingEdge="horizontal"
android:fadingEdgeLength="16dp"
android:layout_marginBottom="16dp">
<LinearLayout android:id="@+id/session_tags"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="32dp" />
</HorizontalScrollView>
<LinearLayout android:id="@+id/session_speakers_block"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/element_spacing_normal">
<TextView android:layout_width="match_parent"
android:id="@+id/session_speakers_header"
android:clickable="true"
android:focusable="true"
android:layout_height="wrap_content"
android:text="@string/session_speakers"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
style="@style/SessionDetailSectionHeader" />
</LinearLayout>
<LinearLayout android:id="@+id/session_requirements_block"
android:orientation="vertical"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginTop="@dimen/element_spacing_normal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<TextView android:layout_width="match_parent"
android:id="@+id/session_requirements_header"
android:layout_height="wrap_content"
android:text="@string/session_requirements"
style="@style/SessionDetailSectionHeader" />
<TextView android:id="@+id/session_requirements"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/element_spacing_normal"
android:layout_marginBottom="@dimen/element_spacing_normal"
style="@style/TextBody" />
</LinearLayout>
<LinearLayout android:id="@+id/related_videos_block"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/element_spacing_normal"
android:visibility="gone">
<TextView android:layout_width="match_parent"
android:id="@+id/related_videos_header"
android:layout_height="wrap_content"
android:text="@string/related_videos"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
style="@style/SessionDetailSectionHeader" />
</LinearLayout>
<TextView android:id="@+id/session_links_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:text="@string/session_links"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginTop="@dimen/element_spacing_normal"
style="@style/SessionDetailSectionHeader"
android:visibility="gone"/>
<LinearLayout android:orientation="vertical"
android:id="@+id/links_container"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView style="@style/EmptyText"
android:id="@android:id/empty"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/empty_session_detail"
android:gravity="center"
android:visibility="gone" />
</LinearLayout>
<!-- Title/subtitle bar (floating; position determined at run time as the content view scrolls) -->
<LinearLayout
android:id="@+id/header_session"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical"
android:paddingBottom="16dp">
<include layout="@layout/toolbar_actionbar" />
<!-- Session title -->
<TextView android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginBottom="0dp"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginRight="@dimen/keyline_1"
android:text="@string/placeholder_session_title"
android:id="@+id/session_title"
android:maxLines="4"
android:ellipsize="end"
android:textSize="@dimen/text_size_large"
android:lineSpacingMultiplier="1.1"
android:textStyle="@integer/font_textStyle_medium"
android:fontFamily="@string/font_fontFamily_medium"
android:textColor="@color/body_text_1_inverse"
android:textAlignment="viewStart" />
<!-- Session subtitle -->
<TextView android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginRight="@dimen/keyline_1"
android:text="@string/placeholder_session_subtitle"
android:id="@+id/session_subtitle"
android:maxLines="2"
android:ellipsize="end"
android:textSize="16sp"
android:textColor="@color/body_text_2_inverse"
android:textAlignment="viewStart" />
</LinearLayout>
<!-- FAB -->
<include layout="@layout/include_add_schedule_fab" />
</FrameLayout>
</com.google.samples.apps.iosched.ui.widget.ObservableScrollView>
The FAB layout:
<com.google.samples.apps.iosched.ui.widget.AddToScheduleFABFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/add_schedule_button"
android:layout_width="@dimen/add_to_schedule_button_height_no_padding"
android:layout_height="@dimen/add_to_schedule_button_height_no_padding"
android:layout_marginLeft="@dimen/keyline_1"
android:visibility="invisible"
android:clickable="true"
android:focusable="true"
android:elevation="@dimen/fab_elevation"
android:background="@drawable/add_schedule_fab_ripple_background_off"
android:stateListAnimator="@anim/add_schedule_fab_state_list_anim"
android:contentDescription="@string/add_to_schedule">
<ImageView android:id="@+id/add_schedule_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@drawable/add_schedule_button_icon_unchecked"
android:contentDescription="@null"
android:layout_gravity="center" />
</com.google.samples.apps.iosched.ui.widget.AddToScheduleFABFrameLayout>
it does have margin left at include_add_schedule_fab
<com.google.samples.apps.iosched.ui.widget.CheckableFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/add_schedule_button"
android:layout_width="@dimen/add_to_schedule_button_height"
android:layout_height="@dimen/add_to_schedule_button_height"
android:layout_marginLeft="@dimen/keyline_1_minus_8dp"
android:visibility="invisible"
android:clickable="true"
android:focusable="true"
android:background="@drawable/add_schedule_fab_background"
android:contentDescription="@string/add_to_schedule">
<ImageView android:id="@+id/add_schedule_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@drawable/add_schedule_button_icon_unchecked"
android:contentDescription="@null"
android:layout_gravity="center" />
</com.google.samples.apps.iosched.ui.widget.CheckableFrameLayout>
in the SessionDetailActivity you will get the height in the variable mAddScheduleButtonHeightPixels
ViewTreeObserver vto = mScrollView.getViewTreeObserver();
if (vto.isAlive()) {
vto.addOnGlobalLayoutListener(mGlobalLayoutListener);
}
private ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mAddScheduleButtonHeightPixels = mAddScheduleButton.getHeight();
recomputePhotoAndScrollingMetrics();
}
};
onScrollChanged will set the translation from its initial position
@Override
public void onScrollChanged(int deltaX, int deltaY) {
// Reposition the header bar -- it's normally anchored to the top of the content,
// but locks to the top of the screen on scroll
int scrollY = mScrollView.getScrollY();
float newTop = Math.max(mPhotoHeightPixels, scrollY);
mHeaderBox.setTranslationY(newTop);
mAddScheduleButton.setTranslationY(newTop + mHeaderHeightPixels - mAddScheduleButtonHeightPixels / 2);
...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.