प्रोग्राम के दाईं ओर मार्जिन को बदलें?


172

क्या इस विशेषता को जावा कोड में गतिशील रूप से बदला जा सकता है?

android:layout_marginRight

मेरे पास एक है TextView, जिसे गतिशील रूप से बाईं ओर कुछ पिक्सेल को अपनी स्थिति बदलनी होगी।

इसे प्रोग्रामेटिक तरीके से कैसे करें?

जवाबों:


462

संपादित करें: ऐसा करने का एक अधिक सामान्य तरीका जो लेआउट प्रकार पर निर्भर नहीं करता है (इसके अलावा यह एक लेआउट प्रकार है जो मार्जिन का समर्थन करता है:

public static void setMargins (View v, int l, int t, int r, int b) {
    if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
        p.setMargins(l, t, r, b);
        v.requestLayout();
    }
}

आपको TextView के लिए डॉक्स की जांच करनी चाहिए । मूल रूप से, आप TextView के लेआउटप्रैम ऑब्जेक्ट को प्राप्त करना चाहते हैं, और हाशिये को संशोधित करना चाहते हैं, फिर इसे वापस TextView में सेट करें। यह एक रेखीयआउट में मानकर, कुछ इस तरह आज़माएँ:

TextView tv = (TextView)findViewById(R.id.my_text_view);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)tv.getLayoutParams();
params.setMargins(0, 0, 10, 0); //substitute parameters for left, top, right, bottom
tv.setLayoutParams(params);

मैं अभी इसका परीक्षण नहीं कर सकता हूं, इसलिए मेरी कास्टिंग थोड़ी दूर हो सकती है, लेकिन लेआउटपार्म्स को मार्जिन को बदलने के लिए संशोधित करने की आवश्यकता है।

ध्यान दें

यह मत भूलो कि यदि आपका TextView अंदर है, उदाहरण के लिए, एक RelativeLayout , एक को LinearLayout.LayoutParams के बजाय RelativeLayout.LayoutParams का उपयोग करना चाहिए


39
अन्य लोगों को इसके लिए देख रहे हैं के मामले में बस अपने जवाब में विस्तृत करने के लिए। यदि आप TextView को प्रोग्रामेटिक रूप से बना रहे हैं, तो आपको एक नया LinearLayout.LayoutParams ऑब्जेक्ट भी बनाने की आवश्यकता है, इसके बजाय .getLayoutParams () के माध्यम से बाहर निकलने की कोशिश कर रहा है;
अरेस

यह कमाल का काम करता है, और ऐसा लगता है जैसे यह पिक्सेल में मार्जिन सेट करता है। क्या इसे डीपी में सेट करना संभव है?
सररूपर्ट आठवीं


आपके नोट के अनुसार: मुझे संदेह है। यदि टेबुल्यू या बटन टेबल रो के अंदर है? फिर रिलेटिव लेआउट, टेबल लेआउट के बजाय मुझे क्या उपयोग करना चाहिए?
तेजस

1
नोट से संबंधित, आप केवल TV.getLayoutParams () ViewGroup.MarginLayoutParams को कास्ट कर सकते हैं। इस तरह से यह कोई बात नहीं क्या लेआउट, Parrent है जब तक कि यह मार्जिन लागू करता है
राडू Simionescu

17

लेआउटपार्म्स का उपयोग करें (जैसा कि पहले ही समझाया गया है)। हालाँकि सावधान रहें कि कौन सा लेआउटप्रेम चुनने के लिए। Https://stackoverflow.com/a/11971553/3184778 के अनुसार "आपको उस दृश्य का उपयोग करना होगा जो आपके द्वारा काम कर रहे दृश्य से संबंधित है, वास्तविक दृश्य से नहीं"

यदि उदाहरण के लिए TextView एक TableRow के अंदर है, तो आपको RelativeLayout या LinearLayout के बजाय TableRow.LayoutParams का उपयोग करने की आवश्यकता है


स्पष्टीकरण देने के लिए धन्यवाद!
स्कॉट बिग्स

1
यह वास्तव में बेकार है कि आपको मार्जिन सेट करने के लिए टेक्स्टबॉक्स गंतव्य को जानना होगा ... आपको लगता है कि एक समाधान होगा जो गंतव्य स्वतंत्र है।
TatiOverflow

10

सभी प्रकार के मार्जिन सेट करने के लिए इस फ़ंक्शन का उपयोग करें

      public void setViewMargins(Context con, ViewGroup.LayoutParams params,      
       int left, int top , int right, int bottom, View view) {

    final float scale = con.getResources().getDisplayMetrics().density;
    // convert the DP into pixel
    int pixel_left = (int) (left * scale + 0.5f);
    int pixel_top = (int) (top * scale + 0.5f);
    int pixel_right = (int) (right * scale + 0.5f);
    int pixel_bottom = (int) (bottom * scale + 0.5f);

    ViewGroup.MarginLayoutParams s = (ViewGroup.MarginLayoutParams) params;
    s.setMargins(pixel_left, pixel_top, pixel_right, pixel_bottom);

    view.setLayoutParams(params);
}

2
अतिरिक्त 0.5f क्यों?
behelit

2
@behelit मुझे पता है कि यह देर से है, लेकिन किसी को भी देखने के लिए ... जब आप एक फ्लोट को इंट में डालते हैं, तो फ्लोट राउंड होता है। 0.0 -> 0.4 राउंड से 0 जबकि 0.5 -> 0.9 राउंड से 1. यह अंतिम इन्टस में असंगतता पैदा कर सकता है। इसे रोकने के लिए, 0.5 जोड़ना सुनिश्चित करता है कि सभी गोलाई 1. क्यों है? कहते हैं कि आपका फ्लोट 0.3: 0.3 + 0.5 = 0.8 है जो यूपी से लेकर 1. तक है। आपका कहना है कि फ्लोट 0.8: 0.8 + 0.5 = 1.3 है, जो 1 से 4 से चलता है। अब आप अंतिम राउंडिंग के अपने ज्ञान में सुरक्षित हो सकते हैं (ध्यान दें: हम नकारात्मक
अंतर

7

अपडेट: Android KTX

कोर KTX मॉड्यूल आम पुस्तकालयों कि एंड्रॉयड ढांचे, का हिस्सा हैं के लिए एक्सटेंशन प्रदान करता है androidx.core.viewउन के बीच में।

dependencies {
    implementation "androidx.core:core-ktx:{latest-version}"
}

निम्नलिखित विस्तार कार्य हाशिये से निपटने के लिए आसान हैं:

में सेट सभी कुल्हाड़ियों के हाशिये ViewGroupकी MarginLayoutParams। (आयाम पिक्सेल में दिए जाने हैं, यदि आप dp के साथ काम करना चाहते हैं तो अंतिम खंड देखें)

inline fun MarginLayoutParams.setMargins(@Px size: Int): Unit
// E.g. 16px margins
val params = (myView.layoutParams as ViewGroup.MarginLayoutParams)
params.setMargins(16)

में अपडेट मार्जिन ViewGroupकी ViewGroup.MarginLayoutParams

inline fun MarginLayoutParams.updateMargins(
    @Px left: Int = leftMargin, 
    @Px top: Int = topMargin, 
    @Px right: Int = rightMargin, 
    @Px bottom: Int = bottomMargin
): Unit
// Example: 8px left margin 
params.updateMargins(left = 8)

अपडेट में रिश्तेदार मार्जिन ViewGroupकी MarginLayoutParams(शुरू / अंत के बजाय छोड़ दिया / सही)।

inline fun MarginLayoutParams.updateMarginsRelative(
    @Px start: Int = marginStart, 
    @Px top: Int = topMargin, 
    @Px end: Int = marginEnd, 
    @Px bottom: Int = bottomMargin
): Unit
// E.g: 8px start margin 
params.updateMargins(start = 8)

निम्नलिखित विस्तार गुण वर्तमान मार्जिन प्राप्त करने के लिए आसान हैं:

inline val View.marginBottom: Int
inline val View.marginEnd: Int
inline val View.marginLeft: Int
inline val View.marginRight: Int
inline val View.marginStart: Int
inline val View.marginTop: Int
// E.g: get margin bottom
val bottomPx = myView1.marginBottom
  • dpइसके बजाय का उपयोग करना px:

यदि आप dp(घनत्व-स्वतंत्र पिक्सेल) के साथ काम करना चाहते हैं px, तो आपको उन्हें पहले परिवर्तित करना होगा। आप निम्न विस्तार संपत्ति के साथ आसानी से कर सकते हैं:

val Int.px: Int
    get() = (this * Resources.getSystem().displayMetrics.density).toInt()

तब आप पिछले एक्सटेंशन फ़ंक्शन को कॉल कर सकते हैं जैसे:

params.updateMargins(start = 16.px, end = 16.px, top = 8.px, bottom = 8.px)
val bottomDp = myView1.marginBottom.dp

पुराना उत्तर:

कोटलिन में आप एक विस्तार समारोह की घोषणा कर सकते हैं जैसे:

fun View.setMargins(
    leftMarginDp: Int? = null,
    topMarginDp: Int? = null,
    rightMarginDp: Int? = null,
    bottomMarginDp: Int? = null
) {
    if (layoutParams is ViewGroup.MarginLayoutParams) {
        val params = layoutParams as ViewGroup.MarginLayoutParams
        leftMarginDp?.run { params.leftMargin = this.dpToPx(context) }
        topMarginDp?.run { params.topMargin = this.dpToPx(context) }
        rightMarginDp?.run { params.rightMargin = this.dpToPx(context) }
        bottomMarginDp?.run { params.bottomMargin = this.dpToPx(context) }
        requestLayout()
    }
}

fun Int.dpToPx(context: Context): Int {
    val metrics = context.resources.displayMetrics
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), metrics).toInt()
}

तो आप इसे कॉल कर सकते हैं जैसे:

myView1.setMargins(8, 16, 34, 42)

या:

myView2.setMargins(topMarginDp = 8) 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.