خانه » آموزش برنامه نویسی اندروید » درک بهتر LayoutInflater.inflate()

درک بهتر LayoutInflater.inflate()

در برنامه نویسی اندروید از LayoutInflater.inflate() در موارد بساری استفاده می کنیم از جمله ، ساخت View  برای Fragment در onCreateView ، ساخت View برای لیست آداپتر ها ، ساخت View در customView ها ، ساخت و اضافه کردن View به View دیگر در جایی از کد ، و یا حتی دیالوگ ها . اما شاید شما هم مثل من تا به امروز دقیق مفهوم پارامتر های ورودی اون رو نمیدونستید 😀

در این مقاله قصد دارم در مورد ۲ پارامتر ورودی آن ViewGroup parent, boolean attachToRoot ، صحبت کنم.

اگر attachToRoot مقدار true بگیرد ، ویو ساخته شده به parent افزوده می شود (به عنوان child) ، و اگر attachToRoot مقدار false بگیرد به parent افزوده نمی شود ، با این حال اگر قصد داریم تا View را به parent اضافه کنید ، بهتر است به جای null در صورت وجود parent را مشخص کنید.

وقتی که مقدار true هست ، باید به مکان مورد نظر که به آن اضافه می شود توجه کرد ، مثلا اگر ViewGroup مورد نظر که به عنوان parent در نظر گرفته می شود Linear باشد ، باید به gravity و padding ها توجه کرد ( چون داخل آن قرار می گیرند) و همچنین اگر RelativeLayout هست باید به نحوه قرارگرفتن آن در صفحه توجه کرد.

 

attachToRoot Set to True

فرض کنید قصد داریم که دکمه ای را توسط Infalter به بخشی از صفحه اضافه کنیم ، کد زیر Button مورد نظر ما می باشد که در یک فایل XML ذخیره شده است.

<Button xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/custom_button">
</Button>

واسه اینکه این دکمه رو به یک Layout دیگه اضافه کنیم به راحتی میتونیم از کد زیر استفاده کنیم :

inflater.inflate(R.layout.custom_button, mLinearLayout, true);

با این کد دکمه ما به mLinearLayout افزوده می شود و در این حالت ، LayoutParams های Button ما از LinearLayout استفاده می کنند.

inflater.inflate(R.layout.custom_button, mLinearLayout);

همچنین می توان از کد بالا هم استفاده کرد ( در صورتی که پارامتر سوم وارد نشود ، در صورت null نبودن parent ، به صورت پیشفرض attachToRoot مقدار true می گیرد.

برای مشخص کردن View در CustomView نیز می توان به همین روش رفتار کرد و view مورد نظر را با تگ <merge> به LinearLayout اضافه کرد:

public class MyCustomView extends LinearLayout {
    ...
    private void init() {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        inflater.inflate(R.layout.view_with_merge_tag, this);
    }
}

attachToRoot Set to False

چه زمانی false قرار می دهیم ؟ به مثال زیر توجه کنید:

Button button = (Button) inflater.inflate(R.layout.custom_button, mLinearLayout, false);
mLinearLayout.addView(button);

در این مثال ، Button رو توسط infalter ساخته اما مقدار false به او دادیم !!

سپس در خط بعدی اون رو توسط addView به mLinearLayout اضافه کردیم. ( با این وجود که attachToRoot مقدار false دادیم ولی parent رو مقدار دادیم !! چرا ؟  چون در این حالت LayoutParams ها منطبق با mLinearLayout می شوند در غیر این صورت (اگر null بدهیم) LayoutParams ها خراب خواهند شد)

در مواردی این چنینی ، تا حد امکان parent را در صورت موجود بودن مشخص کنید 

نمونه دیگر در لیست ویو ها ، به دلیل اینکه View را باید return کنیم ، نمی توانیم مقدار attachToRoot را true بدهیم ، ولی باید parent را حتما مشخص کنیم در غیر این صورت مقادیر LayoutParams به هم میریزد و اتفاق های عجیب غریب می افتد:

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(getActivity());
    View view = inflater.inflate(android.R.layout.list_item_recyclerView, parent, false);
    return new ViewHolder(view);
}

خود من بارها شده که بعد از طراحی xml برای آیتم های لیست ، به این نتیجه رسیدم که هرچقدر padding و margin به اولین View داخل Xml میدم ، ظاهرا پاک می شود ، و این به دلیل بی توجهی به این مورد بوده.

در مواردی مانند دیالوگ ها چاره ای جز null کردن parent نداریم ، چون هیچ ViewGroup موجود نمی باشد :

AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mContext);
View customView = inflater.inflate(R.layout.custom_alert_dialog, null);
...
dialogBuilder.setView(customView);
dialogBuilder.show();

 

 

منبع : https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/

برچسب ها:
پست قبلی
پست بعدی

درباره ایلیا عابدینی

برنامه نویس اندروید و کارشناس مهندسی پزشکی، نفر سوم مسابقه برنامه نویسی اندروید http://www.schallenge.ir ، از سال 92 برنامه نویسی اندروید رو شروع کردم و در حال حاضر در شرکت عصر دانش در حال توسعه اپلیکیشن تجارت پی می باشدم ، این وبلاگ رو ساختم تا تجربیات روزانه و مفید خودم رو داخل اون بزارم. رزومه : iact.ir/cv

دیدگاهتان را ثبت کنید

آدرس ایمیل شما منتشر نمی شود.علامت دارها لازمند. *

*

رفتن به بالا