किसी दृश्य की पूर्ण स्थिति सेट करें


180

क्या Android में किसी दृश्य की पूर्ण स्थिति सेट करना संभव है? (मुझे पता है कि वहाँ एक है AbsoluteLayout, लेकिन यह पदावनत है ...)

उदाहरण के लिए, यदि मेरे पास 240x320px स्क्रीन है, तो मैं कैसे जोड़ सकता हूं ImageViewजो 20x20px है जैसे कि इसका केंद्र स्थिति (100,100) पर है?


3
यह भी देखें view.setTranslationX()याview.offsetLeftAndRight()
Drew LeSueur

मैंने अभी एक पुस्तकालय जारी किया है जो शायद यहाँ रुचि का हो। github.com/ManuelPeinado/ImageLayout
मैनुअल

1
यह बहुत मुश्किल है क्योंकि 99.9% समय पूर्ण स्थिति एंड्रॉइड पर एक बुरा विचार है। यदि आप एक ऐसा ऐप लिख रहे हैं जो कभी भी केवल एक भौतिक उपकरण पर चलाया जाएगा, तो यह काम कर सकता है, लेकिन यह आमतौर पर बनाने के लिए एक सुरक्षित धारणा नहीं है। उदाहरण के लिए, इसे Google Play पर अपलोड न करें। यह iOS पर ठीक काम करता है क्योंकि केवल कुछ मुट्ठी भर हार्डवेयर डिवाइस हैं, और आप प्रत्येक के लिए एक कस्टम स्टोरीबोर्ड बना सकते हैं।
edthethird

2
@edthethird, मेरे क्रॉस-प्लेटफ़ॉर्म ऐप में, मुझे स्क्रीन का आकार मिलता है और उस पर सब कुछ आधार है। मैं बस "अप्रचलित" AbsoluteLayout में बदल गया, और यह ठीक काम करता है।
विलियम जोकस

काफी उचित है, लेकिन यह है कि एक रिश्तेदार लेआउट या LinearLayout आप के लिए स्वचालित रूप से क्या करेंगे।
एडिथर्थ

जवाबों:


271

आप RelativeLayout का उपयोग कर सकते हैं। मान लें कि आप अपने लेआउट के अंदर 30x40 ImageView स्थिति (50,60) चाहते थे। आपकी गतिविधि में कहीं:

// Some existing RelativeLayout from your layout xml
RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout);

ImageView iv = new ImageView(this);

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);

और ज्यादा उदाहरण:

क्रमशः (30,60) और (80,90) पर दो 30x40 ImageView (एक पीला, एक लाल) स्थान:

RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout);
ImageView iv;
RelativeLayout.LayoutParams params;

iv = new ImageView(this);
iv.setBackgroundColor(Color.YELLOW);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);

iv = new ImageView(this);
iv.setBackgroundColor(Color.RED);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 80;
params.topMargin = 90;
rl.addView(iv, params);

एक 30x40 पीले ImageView पर (50,60) और दूसरा 30x40 लाल ImageView <80,90> पीले स्टाइल दृश्य के सापेक्ष :

RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout);
ImageView iv;
RelativeLayout.LayoutParams params;

int yellow_iv_id = 123; // Some arbitrary ID value.

iv = new ImageView(this);
iv.setId(yellow_iv_id);
iv.setBackgroundColor(Color.YELLOW);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);

iv = new ImageView(this);
iv.setBackgroundColor(Color.RED);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 80;
params.topMargin = 90;

// This line defines how params.leftMargin and params.topMargin are interpreted.
// In this case, "<80,90>" means <80,90> to the right of the yellow ImageView.
params.addRule(RelativeLayout.RIGHT_OF, yellow_iv_id);

rl.addView(iv, params);

1
मैं आज रात को वहाँ जाऊँगा, यह एक बहुत अच्छा विचार है, पता नहीं क्यों मैंने उसके बारे में नहीं सोचा। के रूप में मैं कई ImageViewडाल दिया है, यह एक का उपयोग करने के लिए बेहतर नहीं होगा FrameLayout?
सिपाही

वास्तव में यह काम करने लगता है, हालांकि, यह केवल तब काम कर रहा है जब इस तरह से एक तस्वीर जोड़ें। अगर मैं एक 2 को जोड़ने की कोशिश करता हूं, तो पहला गायब हो जाता है ...
सिपाही

1
दोनों चित्र एक दूसरे के ऊपर हैं। मैं समझाने के लिए अपने समाधान के लिए कुछ कोड जोड़ूंगा।
एंडी झांग

2
हाँ, मैंने पाया है कि कल भी अपने स्वयं के समाधान पर खुदाई करके। मैं भी फ्रेम के साथ सामान की कोशिश करो। मेरा वास्तविक मुद्दा यह है कि मेरे पास एक यादृच्छिक (x, y) स्थिति वाली 5 छवियां हैं, इसलिए मैं RelativeLayout.RIGHT_OF या ऐसा कुछ भी उपयोग नहीं कर सकता। अजीब बात यह है कि मैं 3 छवियों को ठीक से रखा जा सकता है, लेकिन उनमें से 2 काम नहीं कर रहे हैं ... मुझे समझ में नहीं आता ... मैं आज रात कुछ स्क्रीनशॉट और कुछ कोड के साथ अपने पोस्ट को अपडेट करूंगा।
सिपाही

9
AbsoluteLayout का उपयोग करने की तुलना में इस विधि का उपयोग करना क्यों बेहतर होगा? सिर्फ इसलिए कि निरपेक्षता को हटा दिया जाता है?
नाथन

66

सामान्य तौर पर, आप लेफ्टमार्जिन और टॉपमैरगिन विशेषताओं को निर्दिष्ट करके कंटेनर के रूप में फ्रेमलैट का उपयोग करके एक विशिष्ट स्थिति में एक दृश्य जोड़ सकते हैं

निम्न उदाहरण एक 20x20px ImageView स्थिति (100,200) में पूर्ण स्क्रीन कंटेनर के रूप में एक फ़्रेमलेआउट का उपयोग करेगा:

एक्सएमएल

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:background="#33AAFF"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</FrameLayout>

गतिविधि / टुकड़ा / कस्टम दृश्य

//...
FrameLayout root = (FrameLayout)findViewById(R.id.root);
ImageView img = new ImageView(this);
img.setBackgroundColor(Color.RED);
//..load something inside the ImageView, we just set the background color

FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(20, 20);
params.leftMargin = 100;
params.topMargin  = 200;
root.addView(img, params);
//...

यह चाल चलेगा क्योंकि मार्जिन को निरपेक्ष के रूप में इस्तेमाल किया जा सकता है (एक्स, वाई) एक रिलेटिवलैटआउट के बिना निर्देशांक:

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


2
प्रतिभाशाली! 500 के लायक! +1
लीसा ऐनी

16

बस ऊपर एंडी झांग के जवाब में जोड़ने के लिए, यदि आप चाहते हैं, तो आप rl.addView को परम दे सकते हैं, फिर बाद में इसमें बदलाव कर सकते हैं:

params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);

समान रूप से अच्छी तरह से लिखा जा सकता है:

params = new RelativeLayout.LayoutParams(30, 40);
rl.addView(iv, params);
params.leftMargin = 50;
params.topMargin = 60;

इसलिए यदि आप पैरामस वेरिएबल को बनाए रखते हैं, तो आप इसे आरएल में जोड़ने के बाद किसी भी समय iv के लेआउट को बदल सकते हैं।


यह नमूना प्यार करता था। क्या आप मुझे सुझाव दे सकते हैं कि xml लेआउट में छवि होने पर मैं x, y अक्ष कैसे सेट कर सकता हूं। (मैं छवि का आकार बदलने की कोशिश कर रहा हूं और मुझे किसी स्थान पर छवि सेट करने की आवश्यकता है)
G_S

मुझे डर है कि मैं यह नहीं समझ पाया कि आप क्या पूछ रहे हैं। क्या आप किसी लेआउट से संबंधित लेआउटप्रैमम्स ऑब्जेक्ट को एक्सेस करने की कोशिश कर रहे हैं जिसे एक्सएमएल लेआउट का उपयोग करके पोस्ट किया गया है? मुझे यकीन नहीं है कि यह कैसे किया जाता है। यह उत्तर देने के लिए एक नया प्रश्न सेट करने के लायक हो सकता है, अगर आपको उत्तर कहीं और नहीं मिल रहा है।
एक्सक्यूबुलेंट

कृपया इस प्रश्न पर एक नज़र डालें stackoverflow.com/questions/12028404/…
G_S

5

कोड में किसी भी पिक्सेल मान को हार्डकोड किए बिना एक अधिक क्लीनर और गतिशील तरीका।

मैं एक संवाद (जिसे मैं मक्खी पर फुलाता हूं) को क्लिक किए गए बटन के ठीक नीचे रखना चाहता था।

और इसे इस तरह हल किया:

    // get the yoffset of the position where your View has to be placed 
    final int yoffset = < calculate the position of the view >

    // position using top margin
    if(myView.getLayoutParams() instanceof MarginLayoutParams) {
        ((MarginLayoutParams) myView.getLayoutParams()).topMargin = yOffset;
    }

हालाँकि आपको यह सुनिश्चित करना होगा कि माता-पिता का लेआउट myViewइसका एक उदाहरण है RelativeLayout

अधिक पूर्ण कोड:

    // identify the button
    final Button clickedButton = <... code to find the button here ...>

    // inflate the dialog - the following style preserves xml layout params
    final View floatingDialog = 
        this.getLayoutInflater().inflate(R.layout.floating_dialog,
            this.floatingDialogContainer, false);

    this.floatingDialogContainer.addView(floatingDialog);

    // get the buttons position
    final int[] buttonPos = new int[2];
    clickedButton.getLocationOnScreen(buttonPos);        
    final int yOffset =  buttonPos[1] + clickedButton.getHeight();

    // position using top margin
    if(floatingDialog.getLayoutParams() instanceof MarginLayoutParams) {
        ((MarginLayoutParams) floatingDialog.getLayoutParams()).topMargin = yOffset;
    }

इस तरह आप अभी भी अपने XML कोड में उन पिक्सल्स / डीपीएस को हार्डकोड करने के बजाय, लेआउट एक्सएमएल फाइलों का उपयोग करके सेट किए गए किसी भी लेआउट पैरामीटर को समायोजित करने के लिए लक्ष्य दृश्य की उम्मीद कर सकते हैं।


1

स्क्रीनशॉट चेक करें

अपनी इच्छा X & Y बिंदु पर कोई भी दृश्य रखें

लेआउट फ़ाइल

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.test.MainActivity" >

    <AbsoluteLayout
        android:id="@+id/absolute"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <RelativeLayout
            android:id="@+id/rlParent"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <ImageView
                android:id="@+id/img"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/btn_blue_matte" />
        </RelativeLayout>
    </AbsoluteLayout>

</RelativeLayout>

जावा क्लास

public class MainActivity extends Activity {

    private RelativeLayout rlParent;
    private int width = 100, height = 150, x = 20, y= 50; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AbsoluteLayout.LayoutParams param = new AbsoluteLayout.LayoutParams(width, height, x, y);
        rlParent = (RelativeLayout)findViewById(R.id.rlParent);
        rlParent.setLayoutParams(param);
    }
}

किया हुआ


0

बस अगर यह किसी की मदद कर सकता है, तो आप नीचे के रूप में इस एनिमेटर ViewPropertyAnimator को भी आज़मा सकते हैं

myView.animate().x(50f).y(100f);

myView.animate().translateX(pixelInScreen) 

नोट: यह पिक्सेल दृश्य के सापेक्ष नहीं है। यह पिक्सेल स्क्रीन में पिक्सेल स्थिति है।

Bpr10 जवाब के लिए क्रेडिट


-1

विशिष्ट स्थान पर दृश्य सेट करने के लिए नीचे दिए गए कोड की कोशिश करें: -

            TextView textView = new TextView(getActivity());
            textView.setId(R.id.overflowCount);
            textView.setText(count + "");
            textView.setGravity(Gravity.CENTER);
            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
            textView.setTextColor(getActivity().getResources().getColor(R.color.white));
            textView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // to handle click 
                }
            });
            // set background 
            textView.setBackgroundResource(R.drawable.overflow_menu_badge_bg);

            // set apear

            textView.animate()
                    .scaleXBy(.15f)
                    .scaleYBy(.15f)
                    .setDuration(700)
                    .alpha(1)
                    .setInterpolator(new BounceInterpolator()).start();
            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
                    FrameLayout.LayoutParams.WRAP_CONTENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT);
            layoutParams.topMargin = 100; // margin in pixels, not dps
            layoutParams.leftMargin = 100; // margin in pixels, not dps
            textView.setLayoutParams(layoutParams);

            // add into my parent view
            mainFrameLaout.addView(textView);

-1

Xamarin के लिए मेरा कोड , मैं इस उद्देश्य के लिए फ्रेमलैट का उपयोग कर रहा हूं और निम्नलिखित मेरा कोड है:

               List<object> content = new List<object>();

        object aWebView = new {ContentType="web",Width="300", Height = "300",X="10",Y="30",ContentUrl="http://www.google.com" };
        content.Add(aWebView);
        object aWebView2 = new { ContentType = "image", Width = "300", Height = "300", X = "20", Y = "40", ContentUrl = "https://www.nasa.gov/sites/default/files/styles/image_card_4x3_ratio/public/thumbnails/image/leisa_christmas_false_color.png?itok=Jxf0IlS4" };
        content.Add(aWebView2);
        FrameLayout myLayout = (FrameLayout)FindViewById(Resource.Id.frameLayout1);
        foreach (object item in content)
        {

            string contentType = item.GetType().GetProperty("ContentType").GetValue(item, null).ToString();
            FrameLayout.LayoutParams param = new FrameLayout.LayoutParams(Convert.ToInt32(item.GetType().GetProperty("Width").GetValue(item, null).ToString()), Convert.ToInt32(item.GetType().GetProperty("Height").GetValue(item, null).ToString()));
            param.LeftMargin = Convert.ToInt32(item.GetType().GetProperty("X").GetValue(item, null).ToString());
            param.TopMargin = Convert.ToInt32(item.GetType().GetProperty("Y").GetValue(item, null).ToString());

            switch (contentType) {
                case "web":{
                        WebView webview = new WebView(this);

                        //webview.hei;
                        myLayout.AddView(webview, param);
                        webview.SetWebViewClient(new WebViewClient());
                        webview.LoadUrl(item.GetType().GetProperty("ContentUrl").GetValue(item, null).ToString());

                        break;
                    }
                case "image":
                    {
                        ImageView imageview = new ImageView(this);

                        //webview.hei;
                        myLayout.AddView(imageview, param);
                        var imageBitmap =  GetImageBitmapFromUrl("https://www.nasa.gov/sites/default/files/styles/image_card_4x3_ratio/public/thumbnails/image/leisa_christmas_false_color.png?itok=Jxf0IlS4");
                        imageview.SetImageBitmap(imageBitmap);


                        break;
                    }

            }

        }

यह मेरे लिए उपयोगी था क्योंकि मुझे उनकी उपस्थिति के आधार पर एक दूसरे को ओवरलैप करने के लिए देखने की संपत्ति की आवश्यकता थी, जैसे कि विचार एक दूसरे के ऊपर ढेर हो जाते हैं ।

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