एंड्रॉइड डिज़ाइन लाइब्रेरी - फ्लोटिंग एक्शन बटन पैडिंग / मार्जिन मुद्दे


109

मैं नई FloatingActionButton का उपयोग Google डिज़ाइन लाइब्रेरी से कर रहा हूं और मुझे कुछ अजीब तरह की पैडिंग / मार्जिन समस्याएं मिल रही हैं। यह छवि API 22 पर (डेवलपर लेआउट विकल्पों के साथ) है।

यहां छवि विवरण दर्ज करें

और एपीआई 17 से।

यहां छवि विवरण दर्ज करें

यह एक्सएमएल है

<android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_gravity="bottom|right"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="-32dp"
        android:src="@drawable/ic_action_add"
        app:fabSize="normal"
        app:elevation="4dp"
        app:borderWidth="0dp"
        android:layout_below="@+id/header"/>

एपीआई 17 में एफएबी इतना बड़ा पैडिंग / मार्जिन वार क्यों है?


1
मैं CoordinatorLayoutइसे लंबवत संरेखित करने और अतिरिक्त पैडलिंग प्री-लॉलीपॉप को संरेखित करने की सलाह देता हूं । आप इसे विघटित FAB स्रोतों से समझ सकते हैं, लेकिन मैं Google के लिए इसे ठीक करने की प्रतीक्षा करूँगा जैसे उन्होंने किया था CardView
डेरेलल

जवाबों:


129

अपडेट (अक्टूबर 2016):

सही समाधान अब app:useCompatPadding="true"अपने FloatingActionButton में डालना है । यह विभिन्न एपीआई संस्करणों के बीच पैडिंग को सुसंगत बनाएगा। हालांकि, यह अभी भी डिफ़ॉल्ट मार्जिन को थोड़ा कम करने के लिए लगता है, इसलिए आपको उन लोगों को समायोजित करने की आवश्यकता हो सकती है। लेकिन कम से कम एपीआई-विशिष्ट शैलियों के लिए आगे की आवश्यकता नहीं है।

पिछला उत्तर:

आप एपीआई-विशिष्ट शैलियों का उपयोग करके इसे आसानी से पूरा कर सकते हैं। अपने सामान्य में values/styles.xml, कुछ इस तरह रखो:

<style name="floating_action_button">
    <item name="android:layout_marginLeft">0dp</item>
    <item name="android:layout_marginTop">0dp</item>
    <item name="android:layout_marginRight">8dp</item>
    <item name="android:layout_marginBottom">0dp</item>
</style>

और उसके बाद मान- v21 / styles.xml के लिए, इसका उपयोग करें:

<style name="floating_action_button">
    <item name="android:layout_margin">16dp</item>
</style>

और अपने FloatingActionButton पर स्टाइल लागू करें:

<android.support.design.widget.FloatingActionButton
...
style="@style/floating_action_button"
...
/>

जैसा कि अन्य ने नोट किया है, एपीआई <20 में, बटन अपनी स्वयं की छाया प्रदान करता है, जो दृश्य की समग्र तार्किक चौड़ाई में जोड़ता है, जबकि एपीआई> = 20 में यह नए एलिवेशन मापदंडों का उपयोग करता है जो दृश्य चौड़ाई में योगदान नहीं करते हैं।


19
छोटी गाड़ी Android .. :(
अब्दुल्ला शोएब

3
हास्यास्पद बदसूरत लग रहा है, लेकिन ऐसा लगता है कि कोई अन्य समाधान नहीं है
ग्यारह

3
अच्छा जवाब, धन्यवाद। क्या मैं इसे संपादित करने और टैबलेट के लिए एक शैली भी जोड़ने का सुझाव दे सकता हूं? एपीआई के लिए = = 20, मार्जिन 24dp है; API <20 के लिए मैंने देखा कि आपको <आइटम नाम = "android: layout_marginRight"> 12dp </ आइटम> <आइटम नाम = "android: layout_marginBottom"> 6dp </ आइटम> की आवश्यकता है । मुझे उन्हें खुद से गणना करना पड़ा, क्योंकि मुझे अपने ऐप के लिए इसकी आवश्यकता थी। आप स्टाइल के बजाय डिमेंस रिसोर्स का भी उपयोग कर सकते हैं।
JJ86

elevationFAB पर आपके द्वारा निर्धारित के आधार पर मार्जिन संख्या भिन्न होगी ।
जेरेत मिलार्ड

उपयोगapp:useCompatPadding="true"
किशन वाघेला

51

फ़ाइलों के साथ styles.xmlया उसके साथ कोई अधिक फ़िदालिंग नहीं.java । मुझे इसे सरल बनाने दें।

आप एंड्रॉइड के विभिन्न संस्करणों में समान मार्जिनapp:useCompatPadding="true" बनाए रखने के लिए कस्टम मार्जिन का उपयोग और हटा सकते हैं

आपकी दूसरी तस्वीर में एफएबी पर जो अतिरिक्त मार्जिन / पैडिंग आपने देखी, वह प्री-लॉलीपॉप डिवाइसों पर इस कॉम्पेटपैडिंग के कारण है। यदि यह गुण सेट नहीं है, तो यह पूर्व-लॉलीपॉप उपकरणों पर लागू होता है और लॉलीपॉप + उपकरणों में नहीं

Android स्टूडियो कोड

अवधारणा के सुबूत

डिज़ाइन दृश्य


यदि पेरेंट लेआउट कार्ड व्यू है तो हमें फैब के लिए "card_view: useCompatPadding =" true "का उपयोग करने की आवश्यकता है।
अमित तुमकुर

यह 23.2 संस्करण के लिए समर्थन पुस्तकालय के उन्नयन के बाद मेरे लिए काम करता है। धन्यवाद!
पाब्लो

मुझे आपके PoC में मार्जिन दिख रहा है।
पेड्रो ओलिवेरा

@PedroOliveira हां, आपको Android के सभी संस्करणों में समान मार्जिन दिखाई देगा, जो वास्तव में उद्देश्य है।
सर्वनाबलागी रामचंद्रन

1
आप कह रहे हैं कि वह कस्टम मार्जिन को हटाने के लिए "xxx" का उपयोग कर सकता है, और फिर भी आपकी अवधारणा का प्रमाण सभी मार्जिन दिखाता है, जैसे ओपी ने पूछा क्यों।
पेड्रो ओलिवेरा

31

कुछ समय की खोज और परीक्षण के समाधान के बाद मैं अपनी समस्या को केवल मेरे xml लेआउट में इस पंक्ति को जोड़ने के साथ ठीक करता हूं:

app:elevation="0dp"
app:pressedTranslationZ="0dp"

और यह मेरा पूरा फ्लोट बटन लेआउट है

<android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="16dp"
        android:src="@drawable/ic_add"
        app:elevation="0dp"
        app:pressedTranslationZ="0dp"
        app:fabSize="normal" />

2
महान, मेरे लिए काम किया। न तो useCompatPaddingऔर न ही कुछ और ही परिणाम मिलता है।
bgplaya

1
मैंने इस उत्तर को विक्रम के
ingkevin

22

डिज़ाइन समर्थन लाइब्रेरी के भीतर एक समस्या है। लाइब्रेरी अपडेट होने तक इस समस्या को ठीक करने के लिए नीचे दी गई विधि का उपयोग करें। समस्या को हल करने के लिए अपनी गतिविधि या टुकड़े में इस कोड को जोड़ने का प्रयास करें। अपने xml को वही रखें। लॉलीपॉप पर और ऊपर कोई मार्जिन नहीं है लेकिन नीचे 16dp का मार्जिन है।

अद्यतन कार्य उदाहरण

XML - FAB एक RelativeLayout के भीतर है

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:layout_marginBottom="16dp"
    android:layout_marginRight="16dp"
    android:src="@mipmap/ic_add"
    app:backgroundTint="@color/accent"
    app:borderWidth="0dp"
    app:elevation="4sp"/>

जावा

FloatingActionButton mFab = (FloatingActionButton) v.findViewById(R.id.fab);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) mFab.getLayoutParams();
    p.setMargins(0, 0, dpToPx(getActivity(), 8), 0); // get rid of margins since shadow area is now the margin
    mFab.setLayoutParams(p);
}

Pp को px में कनवर्ट करें

public static int dpToPx(Context context, float dp) {
    // Reference http://stackoverflow.com/questions/8309354/formula-px-to-dp-dp-to-px-android
    float scale = context.getResources().getDisplayMetrics().density;
    return (int) ((dp * scale) + 0.5f);
}

चूसने की मिठाई

यहां छवि विवरण दर्ज करें

प्री लॉलीपॉप

यहां छवि विवरण दर्ज करें


यह सही उत्तर होना चाहिए। हालाँकि, यह 100% समस्या को ठीक नहीं करता है क्योंकि पैडिंग भी अस्वाभाविक है।
जॉनीलम्बदा

@ जॉननीलांबा मुझे ऐसा नहीं लगता। RelativeLayout.LayoutParamsके लिए नहीं डाला जा सकता LayoutParamsहै FloatingActionButtonऔर मैं पूर्व लॉलीपॉप पर 16dp के किसी भी मार्जिन को नहीं देखता हूं। FloatingActionButtonप्री लॉलीपॉप की चौड़ाई 56dp के बजाय 84dp है और इसकी ऊंचाई 98dp है।
मार्कस रूबी

@MarkusRubey मैं अपने जवाब को एक कार्यशील उदाहरण और प्री लॉलीपॉप और लॉलीपॉप संस्करण को प्रदर्शित करने वाली छवियों के साथ अपडेट करूंगा।
यूजीन एच

1
@MarkusRubey - यूजीन के मामले में यह एक प्रकार का View.getLayoutParamsरिटर्न है । LayoutParamsViewRelativeLayout.LayoutParams
जॉनीलांबाडा

1
@EugeneH मैंने RelativeLayout.ayoutParams को ViewGroup.MarginLayoutParams में बदल दिया। यह कोड को कई और मामलों में काम करेगा और उस समस्या को ठीक करता है जो MarkusRubey लाता है।
जॉनीलम्बदा

8

प्री लॉलीपॉप पर FloatingActionButtonअपनी खुद की छाया खींचने के लिए जिम्मेदार है। इसलिए छाया के लिए जगह बनाने के लिए दृश्य थोड़ा बड़ा होना चाहिए। एक सुसंगत व्यवहार प्राप्त करने के लिए आप ऊंचाई और चौड़ाई के अंतर को ध्यान में रखते हुए मार्जिन सेट कर सकते हैं। मैं वर्तमान में निम्न वर्ग का उपयोग कर रहा हूं :

import android.content.Context;
import android.content.res.TypedArray;
import android.support.design.widget.FloatingActionButton;
import android.util.AttributeSet;
import android.view.ViewGroup.MarginLayoutParams;

import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.LOLLIPOP;

import static android.support.design.R.styleable.FloatingActionButton;
import static android.support.design.R.styleable.FloatingActionButton_fabSize;
import static android.support.design.R.style.Widget_Design_FloatingActionButton;
import static android.support.design.R.dimen.fab_size_normal;
import static android.support.design.R.dimen.fab_size_mini;

public class CustomFloatingActionButton extends FloatingActionButton {

    private int mSize;

    public CustomFloatingActionButton(Context context) {
        this(context, null);
    }

    public CustomFloatingActionButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs, FloatingActionButton, defStyleAttr,
                Widget_Design_FloatingActionButton);
        this.mSize = a.getInt(FloatingActionButton_fabSize, 0);
        a.recycle();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (SDK_INT < LOLLIPOP) {
            int size = this.getSizeDimension();
            int offsetVertical = (h - size) / 2;
            int offsetHorizontal = (w - size) / 2;
            MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();
            params.leftMargin = params.leftMargin - offsetHorizontal;
            params.rightMargin = params.rightMargin - offsetHorizontal;
            params.topMargin = params.topMargin - offsetVertical;
            params.bottomMargin = params.bottomMargin - offsetVertical;
            setLayoutParams(params);
        }
    }

    private final int getSizeDimension() {
        switch (this.mSize) {
            case 0: default: return this.getResources().getDimensionPixelSize(fab_size_normal);
            case 1: return this.getResources().getDimensionPixelSize(fab_size_mini);
        }
    }
}

अपडेट: Android समर्थन लाइब्रेरी v23 का नाम बदलकर fab_size dimens:

import static android.support.design.R.dimen.design_fab_size_normal;
import static android.support.design.R.dimen.design_fab_size_mini;

मैंने अभी अपने प्रोजेक्ट को AndroidX में रिफ्लेक्ट किया है और मैं आपके उदाहरण से 3rd कंस्ट्रक्टर बनाने में असमर्थ हूं। मैं AndroidX पुस्तकालयों का उपयोग कैसे कर सकता हूं?
अलोन शालिडर

5

V23.1.0 को अपडेट करने और आयात में कुछ समायोजन करने के बाद मार्कस के जवाब ने मेरे लिए अच्छा काम किया (हाल ही के ग्रेड प्लगइन के साथ हम डिजाइन लाइब्रेरी के आर के बजाय हमारे ऐप आर का उपयोग करते हैं)। यहाँ v23.1.0 के लिए कोड है:

// Based on this answer: https://stackoverflow.com/a/30845164/1317564
public class CustomFloatingActionButton extends FloatingActionButton {
    private int mSize;

    public CustomFloatingActionButton(Context context) {
        this(context, null);
    }

    public CustomFloatingActionButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    @SuppressLint("PrivateResource")
    public CustomFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.FloatingActionButton, defStyleAttr,
                R.style.Widget_Design_FloatingActionButton);
        mSize = a.getInt(R.styleable.FloatingActionButton_fabSize, 0);
        a.recycle();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            int size = this.getSizeDimension();
            int offsetVertical = (h - size) / 2;
            int offsetHorizontal = (w - size) / 2;
            ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) getLayoutParams();
            params.leftMargin = params.leftMargin - offsetHorizontal;
            params.rightMargin = params.rightMargin - offsetHorizontal;
            params.topMargin = params.topMargin - offsetVertical;
            params.bottomMargin = params.bottomMargin - offsetVertical;
            setLayoutParams(params);
        }
    }

    @SuppressLint("PrivateResource")
    private int getSizeDimension() {
        switch (mSize) {
            case 1:
                return getResources().getDimensionPixelSize(R.dimen.design_fab_size_mini);
            case 0:
            default:
                return getResources().getDimensionPixelSize(R.dimen.design_fab_size_normal);
        }
    }
}

मैं इस उदाहरण का उपयोग करने के लिए AndroidX को रीफ़ैक्‍ट करने के बाद प्रतीत नहीं कर सकता - तीसरा निर्माणकर्ता अब संकलित नहीं करता है। क्या आप जानते हैं कि क्या गलत है?
अलोन शालिडर

3

लेआउट फ़ाइल में विशेषता ऊंचाई को 0. पर सेट किया गया है क्योंकि यह डिफ़ॉल्ट ऊंचाई लेता है।

app:elevation="0dp"

अब गतिविधि में एपीआई स्तर 21 से अधिक की जाँच करें और यदि आवश्यक हो तो ऊंचाई सेट करें।

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    fabBtn.setElevation(10.0f);
}

आप उपयोग कर रहे हैं compat पुस्तकालय उपयोग setCompatElevation । और सीधे पिक्सल के बजाय डिप्स का उपयोग करना बेहतर होगा।
इग्वेकिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.