তার পিতামাতার মাত্রার উপর ভিত্তি করে কোনও Android ভিউ কীভাবে আকার করবেন size


104

আমি এর প্যারেন্ট লেআউটের আকারের উপর ভিত্তি করে একটি দৃশ্যকে কীভাবে আকার দিতে পারি। উদাহরণস্বরূপ আমার কাছে এমন একটি রয়েছে RelativeLayoutযা পুরো স্ক্রিনটি পূর্ণ করে এবং আমি একটি শিশু দর্শন চাই, একটি বলি ImageView, পুরো উচ্চতা নিতে এবং 1/2 প্রস্থ নিতে চান?

আমি সব অগ্রাহ্য চেষ্টা করেছি onMeasure, onLayout, onSizeChanged, ইত্যাদি এবং আমি তা কাজে পাই নি ....


কনস্ট্রেন্টলয়েট ব্যবহার করে এটি করা সম্ভব, এটি পরীক্ষা করুন: stackoverflow.com/questions/37318228/…
আলী নেম

উত্তর:


124

আমি জানি না যে কেউ এখনও এই থ্রেডটি পড়ছেন বা না, তবে জেফের সমাধানটি আপনাকে কেবল সেখানে পৌঁছে দেবে (আক্ষরিক অর্থে)। তার onMeasure কী করবে তা হল অর্ধেক পিতামাতার অর্ধেক চিত্র প্রদর্শন করা। সমস্যাটি হ'ল সুপার.অনম্যাসার কল করার আগে setMeasuredDimensionআসল আকারের উপর ভিত্তি করে ভিউতে সমস্ত শিশুকে পরিমাপ করা হবে, তারপরে পুনরায় আকার দেওয়ার পরে কেবলমাত্র অর্ধেকটি কেটে দিন setMeasuredDimension

পরিবর্তে, আপনাকে কল করতে হবে setMeasuredDimension(অন-মেজার ওভাররাইডের জন্য প্রয়োজনীয় হিসাবে) এবং আপনার দর্শনটির LayoutParamsজন্য একটি নতুন সরবরাহ করতে হবে, তারপরে কল করুন super.onMeasure। মনে রাখবেন, আপনি আপনার LayoutParamsভিউর পিতামাতার ধরণ থেকে প্রাপ্ত, আপনার দেখার ধরণের নয়।

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
   int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
   int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
   this.setMeasuredDimension(parentWidth/2, parentHeight);
   this.setLayoutParams(new *ParentLayoutType*.LayoutParams(parentWidth/2,parentHeight));
   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

আমি বিশ্বাস করি কেবলমাত্র পিতামাতার LayoutParamsসাথে যদি আপনার সমস্যা হয় তবে পিতা-মাতা যদি হয় AbsoluteLayout(যা অবনমিত তবে এখনও কখনও কখনও দরকারী)।


12
আমার অভিজ্ঞতায়, এটি খুব কমই কাজ করে, esp। যখন পূরণ / ম্যাচ_পিতা বা ওজন চাওয়া হয়। সেট-মিউজার্ডডাইমেনশন (উদাহরণস্বরূপ MeasureSpec.makeMeasureSpec (newwidth, MeasureSpec.AT_MOST)) এর পরে বাচ্চাদের চেয়ে ভাল পরিমাপের চাইল্ডেন oke
এম শেনেক

1
না MeasureSpec.getSize(widthMeasureSpec)সত্যিই দিতে সঠিক parent's প্রস্থ? আমার জন্য এটি কেবল এলোমেলো প্রস্থগুলি দেয় যা প্রকৃত প্রস্থের সাথে বেশ কাছাকাছি, তবে সঠিক নয়।
কনসুমিয়ারার

1
@ এম। শ্যাঙ্ক এর কাছে আছে। ভারী লেআউটের ভিতরে আমার একটি ভিডিওভিউ রয়েছে। পর্দার আকারের শতাংশের জন্য আমার প্রস্থটি প্রয়োজন এবং আমার দিক অনুপাত বজায় রাখতে হবে। এটি ভিডিওটিকে প্রসারিত করে, তাই wrap_contentকরবে না। ভিসির উত্তর এই দৃশ্যের জন্য কাজ করে না, তবে @ এম। শ্যাঙ্কের মন্তব্যটি করেছে। এটি একটি অতিরিক্ত লেআউট পাসও সংরক্ষণ করে। আপনার দৃশ্যমানতার উত্তর হিসাবে এটি পোস্ট করা উচিত।
dokkaebi

7
কলে করবে না super.onMeasure()কেবল ওভাররাইড করুন এবং আগের কল প্রভাব খর্ব this.setMeasuredDimension()?
স্পিনার

1
আমি স্পষ্টও, যেমন @ স্পিনার উল্লেখ করেছেন, কেন কল করার super.onMeasure()আগে আগের গণনাগুলিকে ওভাররাইড করা হয়নি।
jwir3

39

আপনি এটি একটি কাস্টম ভিউ তৈরি করে এবং onMeasure () পদ্ধতিটি ওভাররাইড করে সমাধান করতে পারেন। যদি আপনি সর্বদা আপনার এক্সএমএলে লেআউট_পথের জন্য "ফিল_প্যারেন্ট" ব্যবহার করেন তবে অনম্যাস্রে () পদ্ধতিতে প্রস্থমানের প্রস্থম্যাসস্পেক পরামিতিটি পিতামাতার প্রস্থ থাকতে হবে।

public class MyCustomView extends TextView {

    public MyCustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        this.setMeasuredDimension(parentWidth / 2, parentHeight);
    }
}   

আপনার এক্সএমএল দেখতে এমন কিছু লাগবে:

<LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <view
        class="com.company.MyCustomView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

2
@ জেফ => কেন প্যারেন্টউইথ / 2 ??
সা Saeedদ-আরজেড

6
@ লিওন_এসএফ: প্রশ্নটি তার জন্য জিজ্ঞাসা করছে: "পুরো উচ্চতা এবং প্রস্থের 1/2 অংশ"
এডগার্ট

28

আমি খুঁজে পেয়েছি যে পরিমাপের মাত্রাগুলি নিজেই নির্ধারণের সাথে গোলযোগ না করা ভাল। পিতামাতা এবং সন্তানের মতামতের মধ্যে আসলে কিছুটা আলোচনা চলছে এবং আপনি সমস্ত কোডটি আবার লিখতে চান না ।

আপনি যা করতে পারেন তা হল পরিমাপের স্পেসগুলিকে সংশোধন করা, তারপরে তাদের সাথে সুপার কল করুন। আপনার দৃষ্টিভঙ্গি কখনই জানতে পারবেন না যে এটি তার পিতামাতার কাছ থেকে একটি পরিবর্তিত বার্তা পেয়েছে এবং আপনার জন্য সমস্ত কিছুর যত্ন নেবে:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
    int myWidth = (int) (parentHeight * 0.5);
    super.onMeasure(MeasureSpec.makeMeasureSpec(myWidth, MeasureSpec.EXACTLY), heightMeasureSpec);
}

16

আপনি যখন এক্সএমএলে একটি বিন্যাস সংজ্ঞা এবং দর্শনটি সংজ্ঞায়িত করেন, আপনি সামগ্রী মোড়ানো হতে পারে, বা প্যারেন্টটি পূরণ করতে আপনি একটি বিন্যাসের প্রস্থ এবং উচ্চতা নির্দিষ্ট করতে পারেন। অঞ্চলটির অর্ধেক অংশ গ্রহণ করা কিছুটা শক্ত, তবে অন্য অর্ধেকের কাছে যদি আপনি কিছু চেয়েছিলেন তবে নীচের মতো কিছু করতে পারতেন।

   <LinearLayout android:layout_width="fill_parent"
                android:layout_height="fill_parent">
        <ImageView android:layout_height="fill_parent"
                 android:layout_width="0dp"
                 android:layout_weight="1"/>
        <ImageView android:layout_height="fill_parent"
                 android:layout_width="0dp"
                 android:layout_weight="1"/>
   </LinearLayout>

দুটি জিনিসকে একই ওজন দেওয়ার অর্থ তারা পর্দার একই অনুপাত গ্রহণ করতে প্রসারিত করবে। বিন্যাস সম্পর্কিত আরও তথ্যের জন্য, দেব ডকসটি দেখুন।


আমি এটির প্রস্তাব দিচ্ছি না, তবে ... হ্যাক হিসাবে, যদি আপনি উপরোক্ত পদ্ধতির ব্যবহার করেন তবে আপনি সেই ভিউগুলির মধ্যে একটিকে "ডামি" তৈরি করতে পারেন এবং অ্যান্ড্রয়েড সেট করতে পারেন: দৃশ্যমানতা = "অদৃশ্য" অর্ধেক অঞ্চলটি পূরণ করতে
রিকনটফ্রেড

অর্ধেক অঞ্চল ব্যবহারের উদ্দেশ্য কী? আপনি কি অন্য অর্ধেক কিছু প্রদর্শন করার পরিকল্পনা করছেন? অবশিষ্ট অঞ্চলটি নিয়ে আপনি যা করেন তা সর্বোত্তম পদ্ধতির অবহিত করবে
রিকনটফ্রেড

এটি অবশ্যই # 1 হওয়া উচিত - আপনি যদি এটি আপনার এক্সএমএল করতে পারেন তবে এটি আপনার জাভাতে কেন করবেন?
fandang

9

আমি বিশ্বাস করি যে মায়রাস এক্সএমএল-পদ্ধতির ঝরঝরে আসতে পারে। তবে এটি কেবলমাত্র ওয়েটসাম সেট করে একটি ভিউ সহ আরও নির্ভুল করা সম্ভব। আমি এটিকে আর হ্যাক বলব না তবে আমার মতে সর্বাধিক সরল পদ্ধতি:

<LinearLayout android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:weightSum="1">
    <ImageView android:layout_height="fill_parent"
               android:layout_width="0dp"
               android:layout_weight="0.5"/>
</LinearLayout>

এটির মতো আপনি যে কোনও ওজন ব্যবহার করতে পারেন, উদাহরণস্বরূপ 0.6 (এবং কেন্দ্রীকরণ) হ'ল আমি ওজনগুলি বোতামগুলির জন্য ব্যবহার করতে চাই।


3

এটা চেষ্টা কর

int parentWidth = ((parentViewType)childView.getParent()).getWidth();
int parentHeight = ((parentViewType)childView.getParent()).getHeight();

তারপরে আপনি চিলিভিউর পরামিতিগুলি সেট করার জন্য লিনিয়ারলআউট.লায়আউটপ্যারাম ব্যবহার করতে পারেন

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(childWidth,childLength);
childView.setLayoutParams(params);

2

আপনি এখন PercentRelativeLayout ব্যবহার করতে পারেন। পরিস্ফুটন! সমস্যা সমাধান.


2
পারসেন্ট্রেলেটিভলআউটকে এপিআই স্তরের 26.0.0-beta1 এ অবমূল্যায়ন করা হয়েছিল।
dzikovskyy

"এপিআই স্তরে" আপনার অর্থ কী? আপনি কি লাইব্রেরি সংস্করণ নম্বর বোঝাতে চান? পিআরএল সমর্থন লাইব্রেরিতে রয়েছে, কোনও এপিআই স্তর নেই।
অ্যান্ড্রয়েডজি

এপিআই স্তরের দ্বারা আমি অ্যান্ড্রয়েডের সংস্করণ বুঝি। এখান থেকে ডেভেলপার.অ্যান্ড্রয়েড . com/references/android/support/percent/… থেকে তথ্য ।
এআইপিএল

আপনি এখনও এই ক্লাসটি ব্যবহার করতে পারেন যদি না কোনও কারণে আপনার 26.0.0 বা উচ্চতর সংস্করণ প্রয়োজন হয়।
androidguy

1

রোমান, আপনি যদি জাভা কোডটিতে আপনার বিন্যাস করতে চান (ভিউগ্রুপ বংশধর), এটি সম্ভব। কৌশলটি হ'ল আপনাকে onMeasure এবং onLayout উভয় পদ্ধতিই প্রয়োগ করতে হবে। OnMeasure- কে প্রথমে ডাকা হয় এবং আপনাকে সেখানে সংক্ষিপ্তসারটি "পরিমাপ" করতে হবে (কার্যকরভাবে এটি পছন্দসই মানটির আকার দিতে হবে)। অন-লেআউট কলটিতে আপনাকে এটি আবার আকার করতে হবে। আপনি যদি এই সিকোয়েন্সটি করতে ব্যর্থ হন বা আপনার onMeasure কোড শেষে setMeasuredDimension () কল করতে ব্যর্থ হন, আপনি ফলাফল পাবেন না। কেন এইরকম জটিল এবং ভঙ্গুর উপায়ে ডিজাইন করা হয়েছে তা আমার বাইরে।


1

অন্য দিকটি যদি খালি থাকে। আমি অনুমান করি যে সবচেয়ে সহজ উপায় হ'ল খালি ভিউ (উদাহরণস্বরূপ একটি লিনিয়ার লেআউট) যুক্ত করা হবে তারপরেই উভয় মতামতের প্রশস্ততা পূরণ করতে পিতা-মাতার এবং তাদের উভয় ওজনকে 1 এ সেট করুন।

এটি লিনিয়ারআলআউটে কাজ করে ...


0

এটি এরকম কিছু:

<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.company.myapp.ActivityOrFragment"
    android:id="@+id/activity_or_fragment">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/linearLayoutFirst"
    android:weightSum="100">   <!-- Overall weights sum of children elements -->

    <Spinner
        android:layout_width="0dp"   <!-- It's 0dp because is determined by android:layout_weight -->
        android:layout_weight="50"
        android:layout_height="wrap_content"
        android:id="@+id/spinner" />

</LinearLayout>


<LinearLayout
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:layout_below="@+id/linearLayoutFirst"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:id="@+id/linearLayoutSecond">

    <EditText
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="75"
        android:inputType="numberDecimal"
        android:id="@+id/input" />

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="0dp"
        android:layout_weight="25"
        android:id="@+id/result"/>

</LinearLayout>
</RelativeLayout>

0

আমি দীর্ঘদিন ধরে এই প্রশ্নটির সাথে লড়াই করে যাচ্ছি, আমি আমার ড্রয়ারলআউটের ড্রয়ারের প্রস্থটি পরিবর্তন করতে চাই, এটি তার পিতামাতার দ্বিতীয় সন্তান। সম্প্রতি আমি এটি বের করেছিলাম, তবে আরও ভাল ধারণা আছে কিনা তা জানি না।

override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
    super.onLayout(changed, l, t, r, b)
    (getChildAt(1).layoutParams as LayoutParams).width = measuredWidth/2
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.