16

FloatingActionButton öğesini ekranın altına ayarlıyorum ve düğmeyi canlandırmak istiyorum.Android için Google+ uygulamasında FloatingActionButton nasıl eklenir?

yukarı kaydırma ederken gösterilir

  • aşağı kaydırma.

    Sanırım CoordinatorLayout ve AppBarLayout gerekli ancak bunu FloatingActionButton ile kullanmak için nasıl kullanılır?

  • +0

    Ayrıca BaseActivity google io zamanlama app bakmak ve buna göre fab canlandırabilirsiniz bulabilirsiniz. – Raghunandan

    cevap

    31

    Bunu varsayılandeğişen varsayılan FloatingActionButton kullanarak elde edebilirsiniz app:layout_behavior Kendi Behavior tanımlayabilirsiniz ile

    <android.support.design.widget.CoordinatorLayout  
         xmlns:android="http://schemas.android.com/apk/res/android" 
         xmlns:app="http://schemas.android.com/apk/res-auto" 
         android:id="@+id/main_content" 
         android:layout_width="match_parent" 
         android:layout_height="match_parent"> 
    
        <android.support.design.widget.AppBarLayout 
         android:id="@+id/appbar" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> 
    
         <android.support.v7.widget.Toolbar 
          android:id="@+id/toolbar" 
          android:layout_width="match_parent" 
          android:layout_height="?attr/actionBarSize" 
          android:background="?attr/colorPrimary" 
          app:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
          app:layout_scrollFlags="scroll|enterAlways" /> 
    
        </android.support.design.widget.AppBarLayout> 
    
        // Your layout, for example a RecyclerView 
        <RecyclerView 
         ..... 
         app:layout_behavior="@string/appbar_scrolling_view_behavior" /> 
    
        <android.support.design.widget.FloatingActionButton 
          android:id="@+id/fab" 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          android:layout_gravity="end|bottom" 
          android:layout_margin="@dimen/fab_margin" 
          android:src="@drawable/ic_done"  
          app:layout_behavior="com.support.android.designlibdemo.ScrollAwareFABBehavior" /> 
    
        </android.support.design.widget.CoordinatorLayout> 
    

    :

    Sen gibi bir düzen kullanabilirsiniz: 210 app:layout_behavior özelliğini kullanarak. onStartNestedScroll() ve onNestedScroll() yöntemleriyle kaydırma olaylarıyla etkileşime girebilirsiniz.

    Böyle bir Davranış kullanabilirsiniz. Orijinal kod here:

    public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior { 
        private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator(); 
        private boolean mIsAnimatingOut = false; 
    
        public ScrollAwareFABBehavior(Context context, AttributeSet attrs) { 
         super(); 
        } 
    
        @Override 
        public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child, 
                 final View directTargetChild, final View target, final int nestedScrollAxes) { 
         // Ensure we react to vertical scrolling 
         return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL 
           || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes); 
        } 
    
        @Override 
        public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child, 
               final View target, final int dxConsumed, final int dyConsumed, 
               final int dxUnconsumed, final int dyUnconsumed) { 
         super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); 
         if (dyConsumed > 0 && !this.mIsAnimatingOut && child.getVisibility() == View.VISIBLE) { 
          // User scrolled down and the FAB is currently visible -> hide the FAB 
          animateOut(child); 
         } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { 
          // User scrolled up and the FAB is currently not visible -> show the FAB 
          animateIn(child); 
         } 
        } 
    
        // Same animation that FloatingActionButton.Behavior uses to hide the FAB when the AppBarLayout exits 
        private void animateOut(final FloatingActionButton button) { 
         if (Build.VERSION.SDK_INT >= 14) { 
          ViewCompat.animate(button).scaleX(0.0F).scaleY(0.0F).alpha(0.0F).setInterpolator(INTERPOLATOR).withLayer() 
            .setListener(new ViewPropertyAnimatorListener() { 
             public void onAnimationStart(View view) { 
              ScrollAwareFABBehavior.this.mIsAnimatingOut = true; 
             } 
    
             public void onAnimationCancel(View view) { 
              ScrollAwareFABBehavior.this.mIsAnimatingOut = false; 
             } 
    
             public void onAnimationEnd(View view) { 
              ScrollAwareFABBehavior.this.mIsAnimatingOut = false; 
              view.setVisibility(View.GONE); 
             } 
            }).start(); 
         } else { 
          Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_out); 
          anim.setInterpolator(INTERPOLATOR); 
          anim.setDuration(200L); 
          anim.setAnimationListener(new Animation.AnimationListener() { 
           public void onAnimationStart(Animation animation) { 
            ScrollAwareFABBehavior.this.mIsAnimatingOut = true; 
           } 
    
           public void onAnimationEnd(Animation animation) { 
            ScrollAwareFABBehavior.this.mIsAnimatingOut = false; 
            button.setVisibility(View.GONE); 
           } 
    
           @Override 
           public void onAnimationRepeat(final Animation animation) { 
           } 
          }); 
          button.startAnimation(anim); 
         } 
        } 
    
        // Same animation that FloatingActionButton.Behavior uses to show the FAB when the AppBarLayout enters 
        private void animateIn(FloatingActionButton button) { 
         button.setVisibility(View.VISIBLE); 
         if (Build.VERSION.SDK_INT >= 14) { 
          ViewCompat.animate(button).scaleX(1.0F).scaleY(1.0F).alpha(1.0F) 
            .setInterpolator(INTERPOLATOR).withLayer().setListener(null) 
            .start(); 
         } else { 
          Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_in); 
          anim.setDuration(200L); 
          anim.setInterpolator(INTERPOLATOR); 
          button.startAnimation(anim); 
         } 
        } 
    } 
    
    +1

    "RecyclerView", "app: layout_behavior" özelliği için belirtilen bir dize kaynağına sahipken, "FloatingActionButton" özelliği bir değişmez, kodlanmış dize? İkisi de aynı Davranış sınıfına işaret etmeli mi? –

    +5

    'R.anim.fab_in' ve' R.anim.fab_out' bulmayı öğrenmek için lütfen yardım edebilir misiniz? Depoda işlenmemiş olduğunu düşünüyorum. –

    +0

    Dizin tüketimini nasıl düzeltebilirim? – Yaojin

    0

    Google'ın Tasarım Desteği Kitaplığı bunu yapacaktır. senin düzen dosyasına bu kodu uygulamak için

    Dene:

    <android.support.design.widget.FloatingActionButton 
         android:id="@+id/fab" 
         android:layout_width="wrap_content" 
         android:layout_height="wrap_content" 
         android:src="@drawable/ic_add_black" 
         android:layout_gravity="bottom|end" 
         app:elevation="6dp" 
         app:pressedTranslationZ="12dp"/> 
    

    Bu sizin build.gradle için compile 'com.android.support:design:22.2.0' eklemek önemlidir. Bu kitaplığı projenize eklemek için eclipse is another way kullanıyorsanız.

    Önemli kaynaklar: bu yazı itibarıyla
    Design Support Library (II): Floating Action Button
    Android Design Support Library
    Google Releasing A FABulous New Design Support Library [Updated]

    +0

    Bu bağlantı soruyu yanıtlayabilirken, cevabın temel kısımlarını buraya eklemek ve referans için bağlantı sağlamak daha iyidir. Bağlantılı sayfa değiştiğinde yalnızca bağlantı yanıtları geçersiz olabilir. – gnat

    +1

    Evet üzgünüm. Bunu gerçekten yapmak zorundaydım. Ben stackoverflow için yeniyim;) – 8m47x

    +2

    @ 8m47x, cevabınız için tanklar. Ama ben FloatingActionButton nasıl oluşturduğumu sormadım, bunu oluşturdum ve bunu kullandım, Sorum şu: Google + uygulaması FloatingActionButton'u nasıl canlandırabilir? –

    5

    , otomatik gizleme ve Tasarım Destek Kütüphanesinde FloatingActionButton gösteren idare edecek hiçbir yöntem vardır. Bunu biliyorum çünkü bu benim ilk görevim oldu.

    Düşünceleriniz, Snackbar oluşturulduğunda FloatingActionButton'u yukarı ve aşağı hareket ettirmek için kullanılır ve evet, CoordinatorLayout kullanıyorsanız işe yarayacaktır.

    İşte kodum. Bu this repo kapalı dayanmaktadır. Düğmeyi otomatik olarak hareket ettiren RecyclerView ve AbsListView dinleyicileri vardır. El ile düğmesini gizlemek için

    button.show(); 
    

    veya

    button.hide(); 
    

    yapabilir veya takvimi arayabilirsiniz:

    button.attachToListView(listView); 
    

    ve

    button.attachToRecyclerView(recyclerView); 
    

    ve üzerinde gizler aşağı kaydırın ve hiçbir f ile yukarı kaydırma yapın. daha fazla kod.

    Bu yardımcı olur umarız!

    AnimatedFloatingActionButton:

    public class AnimatedFloatingActionButton extends FloatingActionButton 
    { 
        private static final int TRANSLATE_DURATION_MILLIS = 200; 
        private final Interpolator mInterpolator = new AccelerateDecelerateInterpolator(); 
        private boolean mVisible; 
    
    public AnimatedFloatingActionButton(Context context, AttributeSet attrs) 
    { 
        super(context, attrs); 
        Log.i("Abscroll", "mVisible" + mVisible); 
    } 
    
    public void show() { 
        show(true); 
    } 
    
    public void hide() { 
        hide(true); 
    } 
    
    public void show(boolean animate) { 
        toggle(true, animate, false); 
    } 
    
    public void hide(boolean animate) { 
        toggle(false, animate, false); 
    } 
    
    private void toggle(final boolean visible, final boolean animate, boolean force) { 
        if (mVisible != visible || force) { 
         mVisible = visible; 
         int height = getHeight(); 
         if (height == 0 && !force) { 
          ViewTreeObserver vto = getViewTreeObserver(); 
          if (vto.isAlive()) { 
           vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
            @Override 
            public boolean onPreDraw() { 
             ViewTreeObserver currentVto = getViewTreeObserver(); 
             if (currentVto.isAlive()) { 
              currentVto.removeOnPreDrawListener(this); 
             } 
             toggle(visible, animate, true); 
             return true; 
            } 
           }); 
           return; 
          } 
         } 
         int translationY = visible ? 0 : height + getMarginBottom(); 
         Log.i("Abscroll", "transY" + translationY); 
         if (animate) { 
          this.animate().setInterpolator(mInterpolator) 
            .setDuration(TRANSLATE_DURATION_MILLIS) 
            .translationY(translationY); 
         } else { 
          setTranslationY(translationY); 
         } 
        } 
    } 
    
    private int getMarginBottom() { 
        int marginBottom = 0; 
        final ViewGroup.LayoutParams layoutParams = getLayoutParams(); 
        if (layoutParams instanceof ViewGroup.MarginLayoutParams) { 
         marginBottom = ((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin; 
        } 
        return marginBottom; 
    } 
    
    public void attachToListView(@NonNull AbsListView listView) 
    { 
        listView.setOnScrollListener(new AbsListViewScrollDetector() { 
         @Override 
         void onScrollUp() { 
          hide(); 
         } 
    
         @Override 
         void onScrollDown() { 
          show(); 
         } 
    
         @Override 
         void setScrollThreshold() { 
          setScrollThreshold(getResources().getDimensionPixelOffset(R.dimen.fab_scroll_threshold)); 
         } 
        }); 
    } 
    
    public void attachToRecyclerView(@NonNull RecyclerView recyclerView) { 
        recyclerView.addOnScrollListener(new RecyclerViewScrollDetector() { 
         @Override 
         void onScrollUp() { 
          hide(); 
         } 
    
         @Override 
         void onScrollDown() { 
          show(); 
         } 
    
         @Override 
         void setScrollThreshold() { 
          setScrollThreshold(getResources().getDimensionPixelOffset(R.dimen.fab_scroll_threshold)); 
         } 
        }); 
    } 
    } 
    

    AbsListViewScrollDetector:

    abstract class AbsListViewScrollDetector implements AbsListView.OnScrollListener { 
    private int mLastScrollY; 
    private int mPreviousFirstVisibleItem; 
    private AbsListView mListView; 
    private int mScrollThreshold; 
    
    abstract void onScrollUp(); 
    
    abstract void onScrollDown(); 
    
    abstract void setScrollThreshold(); 
    
    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 
    } 
    
    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
        if(totalItemCount == 0) return; 
        if (isSameRow(firstVisibleItem)) { 
         int newScrollY = getTopItemScrollY(); 
         boolean isSignificantDelta = Math.abs(mLastScrollY - newScrollY) > mScrollThreshold; 
         Log.i("Abscroll", "mLastScrollY " + mLastScrollY); 
         Log.i("Abscroll", "newScrollY " + newScrollY); 
         if (isSignificantDelta) { 
          Log.i("Abscroll", "sig delta"); 
          if (mLastScrollY > newScrollY) { 
           onScrollUp(); 
           Log.i("Abscroll", "sig delta up"); 
          } else { 
           onScrollDown(); 
           Log.i("Abscroll", "sig delta down"); 
          } 
         } 
         mLastScrollY = newScrollY; 
        } else { 
         if (firstVisibleItem > mPreviousFirstVisibleItem) { 
          onScrollUp(); 
          Log.i("Abscroll", "prev up"); 
         } else { 
          onScrollDown(); 
          Log.i("Abscroll", "prev down"); 
         } 
    
         mLastScrollY = getTopItemScrollY(); 
         mPreviousFirstVisibleItem = firstVisibleItem; 
        } 
    } 
    
    public void setScrollThreshold(int scrollThreshold) { 
        mScrollThreshold = scrollThreshold; 
        Log.i("Abscroll", "LView thresh " + scrollThreshold); 
    } 
    
    public void setListView(@NonNull AbsListView listView) { 
        mListView = listView; 
    } 
    
    private boolean isSameRow(int firstVisibleItem) { 
        return firstVisibleItem == mPreviousFirstVisibleItem; 
    } 
    
    private int getTopItemScrollY() { 
        if (mListView == null || mListView.getChildAt(0) == null) return 0; 
        View topChild = mListView.getChildAt(0); 
        return topChild.getTop(); 
    } 
    } 
    

    RecyclerViewScrollDetector:

    abstract class RecyclerViewScrollDetector extends RecyclerView.OnScrollListener { 
    private int mScrollThreshold; 
    
    abstract void onScrollUp(); 
    
    abstract void onScrollDown(); 
    
    abstract void setScrollThreshold(); 
    
    @Override 
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) { 
        boolean isSignificantDelta = Math.abs(dy) > mScrollThreshold; 
        if (isSignificantDelta) { 
         if (dy > 0) { 
          onScrollUp(); 
          Log.i("Abscroll", "Rview up"); 
         } else { 
          onScrollDown(); 
          Log.i("Abscroll", "RView down"); 
         } 
        } 
    } 
    
    public void setScrollThreshold(int scrollThreshold) { 
        mScrollThreshold = scrollThreshold; 
        Log.i("Abscroll", "RView thresh " + scrollThreshold); 
    } 
    } 
    
    +0

    KevCron, cevap için tanklar, ama ScrollView kullanın ve ben ScollListener sınıfı gibi yukarı ve aşağı kaydırma detecter için bir dinleyici yazmak, ama google + app güzel animasyon ve sorunsuz bir şekilde –

    +0

    @ 8m47x yok mu? 't, FloatingActionButton'da, kaydırma işleminde gizlemeyi kaldıracak hiçbir yöntemi yoktur. Google Dokümanları okuduysanız, henüz uygulamamıştır. –

    +0

    @MehrdadFaraji seninki düzgün değilse, benimkini kullanmanı öneririm, şimdi onu izliyorum ve mükemmel düzgün. Ya da kodunuzu gönderebilirsiniz ve neden düzgün olmadığını anlamak için inceleyebiliriz. –

    İlgili konular