【问题标题】:Positioning of FAB button in Material designMaterial design中FAB按钮的定位
【发布时间】:2015-01-08 14:58:48
【问题描述】:

我已经获取了 Google IO 应用程序源代码,并检查了它们如何将 FAB 按钮完美地放置在两个视图的中间(如所附屏幕截图所示)。奇怪的是没有按钮的垂直定位参数,只有heightwidth,在两个布局文件中,滚动到布局文件的最底部可以看到FAB的包含部分。

我错过了什么吗?谢谢。

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

FAB 布局:

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

【问题讨论】:

    标签: android material-design


    【解决方案1】:

    它确实在 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>
    

    在 SessionDetailActivity 中,您将在变量 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 将设置从其初始位置开始的平移

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

    【讨论】:

      猜你喜欢
      • 2015-06-26
      • 1970-01-01
      • 2019-08-24
      • 2017-10-27
      • 2014-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多