android - অ্যান্ড্রয়েড লেআউট ফোল্ডারে subfolders থাকতে পারে?
android-layout (12)
এই মুহূর্তে, আমি রেজ res/layout
ফোল্ডারের ভিতরে প্রতিটি XML লেআউট ফাইল সংরক্ষণ করছি, তাই ছোট প্রকল্পগুলি পরিচালনা করার পক্ষে এটি কার্যকর এবং সহজ, কিন্তু যখন বড় এবং ভারী প্রকল্পগুলির ক্ষেত্রে একটি কেস থাকে, তখন একটি অনুক্রম এবং উপ- ফোল্ডার লেআউট ফোল্ডার ভিতরে প্রয়োজন।
উদাহরণস্বরূপ
layout
-- layout_personal
-- personal_detail.xml
-- personal_other.xml
--layout_address
-- address1.xml
-- address2.xml
একই ভাবে, আমরা বড় অ্যাপ্লিকেশনের জন্য সাব-ফোল্ডার থাকতে চাই, তাই Android প্রকল্পের ভিতরে এমন কোন উপায় আছে?
আমি লেআউট ফোল্ডারের ভিতরে লেআউট-ব্যক্তিগত এবং layout_address সাব-ফোল্ডার তৈরি করতে সক্ষম, কিন্তু যখন R.layout ব্যবহার করে xml লেআউট ফাইলটি অ্যাক্সেস করার সময় আসে তখন সেই সময় কোনও XML এক্সটেনশন পপ-আপ নেই। মেনু।
ছোট সমস্যা
আমি এই প্রশ্নের উপরের উত্তর অনুসরণ করে subfolders অর্জন করতে পারবেন।
যাইহোক, প্রকল্পটি বড় হয়ে গেলে, আপনার অনেক উপ-ফোল্ডার থাকবে:
sourceSets {
main {
res.srcDirs =
[
'src/main/res/layouts/somethingA',
'src/main/res/layouts/somethingB',
'src/main/res/layouts/somethingC',
'src/main/res/layouts/somethingD',
'src/main/res/layouts/somethingE',
'src/main/res/layouts/somethingF',
'src/main/res/layouts/somethingG',
'src/main/res/layouts/somethingH',
'src/main/res/layouts/...many more',
'src/main/res'
]
}
}
একটি বড় সমস্যা নয়, কিন্তু:
- তালিকা খুব দীর্ঘ হয়ে ওঠে হিসাবে এটা সুন্দর না।
- আপনি একটি নতুন ফোল্ডার যোগ প্রত্যেক সময় আপনার
app/build.gradle
পরিবর্তন করতে হবে।
উন্নতি
তাই আমি সব নেস্টেড ফোল্ডার দখল করার জন্য একটি সহজ গ্রোভি পদ্ধতি লিখেছিলাম:
def getLayoutList(path) {
File file = new File(path)
def throwAway = file.path.split("/")[0]
def newPath = file.path.substring(throwAway.length() + 1)
def array = file.list().collect {
"${newPath}/${it}"
}
array.push("src/main/res");
return array
}
আপনার app/build.gradle
এ android {...}
ব্লকের বাইরে এই পদ্ধতিটি আটকান।
ব্যবহারবিধি
এই মত একটি কাঠামোর জন্য:
<project root>
├── app <---------- TAKE NOTE
├── build
├── build.gradle
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
এটি ভালো ব্যবহার করুন:
android {
sourceSets {
main {
res.srcDirs = getLayoutList("app/src/main/res/layouts/")
}
}
}
আপনি যদি এই মত একটি গঠন আছে:
<project root>
├── my_special_app_name <---------- TAKE NOTE
├── build
├── build.gradle
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
আপনি এটি ভালো ব্যবহার করবেন:
android {
sourceSets {
main {
res.srcDirs = getLayoutList("my_special_app_name/src/main/res/layouts/")
}
}
}
ব্যাখ্যা
getLayoutList()
একটি যুক্তি হিসাবে a relative path
লাগে। relative path
প্রকল্পের রুট আপেক্ষিক। তাই যখন আমরা "app/src/main/res/layouts/"
ইনপুট করি, এটি সমস্ত সাবফোল্ডারদের নাম অ্যারে হিসাবে ফেরত দেবে, যা ঠিক একই রকম হবে:
[
'src/main/res/layouts/somethingA',
'src/main/res/layouts/somethingB',
'src/main/res/layouts/somethingC',
'src/main/res/layouts/somethingD',
'src/main/res/layouts/somethingE',
'src/main/res/layouts/somethingF',
'src/main/res/layouts/somethingG',
'src/main/res/layouts/somethingH',
'src/main/res/layouts/...many more',
'src/main/res'
]
বোঝার জন্য মন্তব্য সহ স্ক্রিপ্ট এখানে:
def getLayoutList(path) {
// let's say path = "app/src/main/res/layouts/
File file = new File(path)
def throwAway = file.path.split("/")[0]
// throwAway = 'app'
def newPath = file.path.substring(throwAway.length() + 1) // +1 is for '/'
// newPath = src/main/res/layouts/
def array = file.list().collect {
// println "filename: ${it}" // uncomment for debugging
"${newPath}/${it}"
}
array.push("src/main/res");
// println "result: ${array}" // uncomment for debugging
return array
}
আশা করি এটা সাহায্য করবে!
@Eski এর শীর্ষ উত্তরটি ভাল, তবে কোড ব্যবহার করার জন্য মার্জিত নয়, তাই আমি সাধারণ ব্যবহারের জন্য ধীরে ধীরে একটি groovy স্ক্রিপ্ট লিখেছি। এটি সমস্ত বিল্ড টাইপ এবং পণ্য গন্ধের জন্য প্রয়োগ করা হয় এবং লেআউটের জন্য ব্যবহার করা যাবে না, আপনি অন্য কোনও সংস্থার প্রকারের জন্য যেমন দ্রবণযোগ্য হিসাবে যোগ করতে পারেন। এখানে কোডটি (প্রকল্প-স্তরের ধাপে ফাইলের android
ব্লকটিতে রাখুন):
sourceSets.each {
def rootResDir = it.res.srcDirs[0]
def getSubDirs = { dirName ->
def layoutsDir = new File(rootResDir, dirName)
def subLayoutDirs = []
if (layoutsDir.exists()) {
layoutsDir.eachDir {
subLayoutDirs.add it
}
}
return subLayoutDirs
}
def resDirs = [
"anims",
"colors",
"drawables",
"drawables-hdpi",
"drawables-mdpi",
"drawables-xhdpi",
"drawables-xxhdpi",
"layouts",
"valuess",
]
def srcDirs = resDirs.collect {
getSubDirs(it)
}
it.res.srcDirs = [srcDirs, rootResDir]
}
অনুশীলন কিভাবে করবেন?
উদাহরণস্বরূপ, আমি layout
জন্য activity
নামক resDirs
তৈরি করতে চাই, resDirs
পরিবর্তনশীল কোনও layouts
যেমন layouts
মতো স্ট্রিং যোগ করুন, তারপর লেআউট xml ফাইলটি res\layouts\activity\layout\xxx.xml
।
আমি resDirs
জন্য selectors
নামযুক্ত সাবফোল্ডার তৈরি করতে চাই, resDirs
পরিবর্তনশীল যেমন কোন resDirs
কোন স্ট্রিং যোগ করুন, তখন resDirs
এক্সএমএল ফাইলটি res\drawables\selectors\drawable\xxx.xml
।
layouts
এবং resDirs
মত ফোল্ডারের নাম resDirs
পরিবর্তনশীলতে সংজ্ঞায়িত করা হয়েছে, এটি কোনও স্ট্রিং হতে পারে। আপনার দ্বারা তৈরি সমস্ত সাবফোল্ডার যেমন activity
বা selectors
res
ফোল্ডার হিসাবে একই হিসাবে গণ্য করা হয়। তাই selectors
ফোল্ডারে, আমরা অতিরিক্ত drawable
ফোল্ডার তৈরি করতে এবং ড্র্যাগযোগ্য ফোল্ডারের মধ্যে এক্সএমএল ফাইলগুলি স্থাপন করতে হবে, তারপরে ধীরে ধীরে XML ফাইলগুলি সাধারণভাবে ড্র্যাগযোগ্য হিসাবে সনাক্ত করতে পারে।
আপনার প্রোজেক্টের প্রকৃত রিস ফোল্ডারের মতো একই স্তরটিতে একটি পৃথক রিস ফোল্ডার তৈরি করার মতো একটি উপায়, তারপরে আপনি এটি আপনার অ্যাপ্লিকেশন build.gradle এ ব্যবহার করতে পারেন
android {
//other stuff
sourceSets {
main.res.srcDirs = ['src/main/res', file('src/main/layouts').listFiles()]
}
}
তারপরে আপনার নতুন রিস ফোল্ডারের প্রতিটি সাবফোল্ডার আপনার প্রতিটি অ্যাপ্লিকেশনের প্রতিটি নির্দিষ্ট স্ক্রীন বা কিছু সম্পর্কিত কিছু হতে পারে এবং প্রতিটি ফোল্ডারে নিজস্ব layout
/ drawable
/ values
ইত্যাদি থাকবে যা জিনিসগুলিকে সংগঠিত করে এবং আপনাকে গ্রিড ফাইলটিকে ম্যানুয়ালি কিছু আপডেট করতে হবে না। এই অন্যান্য উত্তরগুলির প্রয়োজন হয় (প্রতিটি সময় যখন আপনি একটি নতুন সংস্থান ফোল্ডার যোগ করেন তখন আপনার ক্র্যাডল সিঙ্ক করুন যাতে এটি সম্পর্কে জানেন এবং আপনার XML ফাইলগুলি যুক্ত করার আগে প্রাসঙ্গিক সাবফোল্ডারদের যোগ করার বিষয়ে নিশ্চিত হন)।
আপনি ধীরে ধীরে এই কাজ করতে পারেন। আমি কিভাবে একটি ডেমো প্রকল্প দেখাচ্ছে করেছি।
ট্রিকটি মাল্টিপল রিসোর্স ফোল্ডারগুলি একত্রিত করার জন্য গ্রেডের ক্ষমতা ব্যবহার করতে এবং উৎস ফোল্ডারগুলির পাশাপাশি ন্যস্ত হওয়া সাবফোল্ডারদের উৎস সেটগুলিতে সেট করে।
Quirk হল যে আপনি ফোল্ডার এর শিশু সংস্থান ফোল্ডার ঘোষণা করার আগে আপনি একটি ধারক সম্পদ ফোল্ডার ঘোষণা করতে পারবেন না।
নিচে সোর্স সেটগুলি ডেমো থেকে build.gradle ফাইল থেকে অবরুদ্ধ। সাবফোল্ডার প্রথম ঘোষণা করা হয় যে লক্ষ্য করুন।
sourceSets {
main {
res.srcDirs =
[
'src/main/res/layouts/layouts_category2',
'src/main/res/layouts',
'src/main/res'
]
}
}
এছাড়াও, আপনার প্রকৃত সংস্থান ফাইলগুলির সরাসরি প্যারেন্ট (PNGs, xml লেআউট, ইত্যাদি) এখনও specification সাথে সামঞ্জস্য করতে হবে।
আমি মনে করি এই সমস্যাটির সবচেয়ে মার্জিত সমাধান (প্রদত্ত সাবফোল্ডারদের অনুমতি দেওয়া হয়নি) ফাইলের নামগুলি যে ফোল্ডারটি আপনি এটির ভিতরে রেখেছেন তার নামের সাথে পূর্বনির্ধারিত করা। উদাহরণস্বরূপ, যদি আপনার কোন ক্রিয়াকলাপের জন্য লেআউটগুলির একটি গুচ্ছ থাকে, ফ্র্যাগমেন্ট, অথবা "স্থানের" নামক সাধারণ দৃশ্যটি থাকে তবে আপনাকে অবশ্যই place_my_layout_name এর সাথে এটি পূর্বাবস্থায় ফিরিয়ে আনতে হবে। অন্তত এইভাবে তাদের এমনভাবে সংগঠিত করার সমস্যা সমাধান করে যে তারা IDE- র মধ্যে সহজে সন্ধান করতে পারে। এটি সবচেয়ে ভয়ঙ্কর সমাধান নয়, তবে এটির চেয়েও ভাল।
আমি শুধু সমস্যার জন্য মানুষ Eskis 'চমত্কার উত্তর সম্মুখের যোগ করতে চেয়েছিলেন। (দ্রষ্টব্য: এটি কেবলমাত্র 'প্রকল্প' ভিউয়ের অভ্যন্তরে পৃথক ডিরেক্টরিগুলির মত কাজ করবে এবং দুর্ভাগ্যবশত 'অ্যান্ড্রয়েড' দেখুন।)
নিম্নলিখিত সঙ্গে পরীক্ষা করা। BuildToolsVersion = 23.0.0 ক্রম 1.2.3 এবং 1.3.0
আমি ইতিমধ্যে একটি নির্মিত প্রকল্প সঙ্গে কাজ করতে খনি পেয়েছিলাম কিভাবে।
- আপনার লেআউট ডিরেক্টরি থেকে সমস্ত এক্সএমএল ফাইল অনুলিপি করুন, এবং ডেস্কটপে একটি ডিরেক্টরি বা ব্যাকআপের জন্য কিছু রাখুন।
- সম্পূর্ণ লেআউট ডিরেক্টরি মুছে ফেলুন (আপনি ধাপ 1 থেকে সবকিছু ব্যাক আপ নিশ্চিত !!!)
- ডান ডিরেক্টরি ডিরেক্টরি ক্লিক করুন এবং নতুন> ডিরেক্টরি নির্বাচন করুন।
- এই নতুন ডিরেক্টরি "লেআউট" নাম দিন। (আপনি যা চান তা হতে পারে তবে এটি একটি 'ফ্যাগমেন্ট' ডিরেক্টরি বা 'কার্যকলাপ' ডিরেক্টরি নয় যা পরে আসে)।
- নতুন "লেআউট" ডিরেক্টরিটি রাইট ক্লিক করুন এবং নতুন> ডিরেক্টরি নির্বাচন করুন। (এটিতে আপনার থাকা এক্সএমএল ফাইলের নাম হবে, উদাহরণস্বরূপ, 'টুকরা' এবং 'ক্রিয়াকলাপ')।
- 'ফ্যাগমেন্ট' বা 'ক্রিয়াকলাপ' ডিরেক্টরিটিতে ডান ক্লিক করুন (দ্রষ্টব্য: এটি একটি 'ফ্র্যাগমেন্ট' বা 'ক্রিয়াকলাপ' নয় যা আমি উদাহরণ হিসাবে ব্যবহার করছি) এবং নতুন> ডিরেক্টরিটি আবার নির্বাচন করুন এবং এই ডিরেক্টরিটি নাম দিন "লেআউট"। (দ্রষ্টব্য: এইটি অবশ্যই 'লেআউট' নামকরণ করা উচিত !!! খুব গুরুত্বপূর্ণ)।
- আপনি আপনার ডেস্কটপে তৈরি ব্যাকআপ থেকে নতুন 'লেআউট' ডিরেক্টরিের ভিতরে যে XML ফাইলগুলি চান তা রাখুন।
- আপনি চান হিসাবে অনেক কাস্টম ডিরেক্টরি জন্য পদক্ষেপ 5 - 7 পুনরাবৃত্তি করুন।
একবার এটি সম্পূর্ণ হয়ে গেলে, আপনার মডিউলগুলি gradle.build ফাইলটিতে যান এবং একটি সূত্র সেটিকে এইভাবে তৈরি করুন ... (নিশ্চিত করুন যে 'src / main / res / layouts' এবং 'src / main / res' সর্বদা নীচে দুটি !! !! ভালো লেগেছে আমি নিচে দেখছি)।
sourceSets { main { res.srcDirs = [ 'src/main/res/layouts/activities', 'src/main/res/layouts/fragments', 'src/main/res/layouts/content', 'src/main/res/layouts', 'src/main/res' ] } }
লাভ $$$$
কিন্তু গুরুত্ব সহকারে .. আমি কিভাবে এটা কাজ পেয়েছিলাম। কেউ যদি আমার কোন প্রশ্ন থাকে তবে আমাকে জানতে দাও .. আমি সাহায্য করার চেষ্টা করতে পারি।
ছবি শব্দ বেশী মূল্য।
একাধিক সংস্থান সেটের জন্য সমস্ত প্রস্তাব কাজ করতে পারে, সমস্যাটি হল যে অ্যানড্রইড স্টুডিও গ্র্যাডল প্লাগ-ইনের বর্তমান যুক্তিগুলি ন্যস্ত সম্পদ সংস্থার জন্য পরিবর্তিত হওয়ার পরে সংস্থান ফাইলগুলি আপডেট করবে না। বর্তমান বাস্তবায়ন startWith () ব্যবহার করে সংস্থান ডিরেক্টরিগুলি পরীক্ষা করার চেষ্টা করে, তাই নেস্টেড (যেমন src / main / res / layout / layouts এবং src / main / res / layout / layouts_category2) একটি ডিরেক্টরি গঠন যা src / main / res নির্বাচন করবে / লেআউট / ধারাবাহিকভাবে এবং পরিবর্তন আসলে আপডেট না। শেষ ফলাফল আপনি প্রতিবার প্রকল্প পুনর্নির্মাণ / পরিষ্কার করতে হবে।
আমি জিনিসপত্র সমাধান করতে সাহায্য করার জন্য https://android-review.googlesource.com/#/c/157971/ এ একটি প্যাচ জমা দিয়েছি।
এখন অ্যান্ড্রয়েড স্টুডিও এবং গ্র্যাডেলের সাহায্যে আপনার প্রোজেক্টে একাধিক সংস্থান ফোল্ডার থাকতে পারে। শুধুমাত্র আপনার বিন্যাস ফাইল কিন্তু সম্পদ কোন ধরনের সংগঠিত করার অনুমতি দেয়।
এটি ঠিক একটি উপ-ফোল্ডার নয়, তবে আপনার অ্যাপ্লিকেশনের অংশগুলি ভাগ করে নিতে পারে।
কনফিগারেশন এই মত:
sourceSets {
main {
res.srcDirs = ['src/main/res', 'src/main/res2']
}
}
ডকুমেন্টেশন চেক করুন।
যদি আপনি অনুমোদিত উত্তরের পদ্ধতিটি ব্যবহার করেন এবং এটিতে কিছুটা উন্নতি করতে চান তবে নিম্নের ধাপ সেটিংটি পরিবর্তন করুন:
sourceSets {
main {
res.srcDirs = [
file("src/main/res/layouts/").listFiles(),
"src/main/res/layouts",
"src/main/res"
]
}
}
সুতরাং যদি আপনি আরো ফোল্ডার এবং লেআউট যোগ করেন তবে আপনাকে এখানে ফিরে আসা এবং উৎস ফোল্ডারগুলির দীর্ঘ তালিকা যোগ করতে হবে না, ধীরে ধীরে আপনার জন্য সমস্ত ফোল্ডার পেতে দিন।
যদি আপনি একটি লিনাক্স বা একটি ম্যাক বক্সে উন্নয়নশীল হন, তাহলে সাবফোলারগুলি তৈরি করতে একটি কার্যকর কাজ হবে যা আপনার layoutfiles এর প্রতীকী লিঙ্কগুলি অন্তর্ভুক্ত করে। শুধু-গুলি সঙ্গে ln কমান্ড ব্যবহার করুন
ln-s PATH_TO_YOUR_FILE
এর সাথে সমস্যা, আপনার লেআউট ফোল্ডারটিতে এখনও সব .xml ফাইল রয়েছে। তবে আপনি উপ-ফোল্ডার ব্যবহার করে তাদের নির্বাচন করতে পারেন। এটি সবচেয়ে কাছের জিনিস যা আপনি চান।
আমি শুধু পড়ি, উইন্ডোজ এর সাথে এটি কাজ করতে পারে, যদি আপনি ভিস্তা বা পরে ব্যবহার করেন। এই mklink
কমান্ড আছে। শুধু এটা গুগল, এটা নিজেকে ব্যবহার না।
আরেকটি সমস্যা হল, যদি আপনার ফাইলটি খোলা থাকে এবং আবার এটি খুলতে চেষ্টা করে তবে প্লাগইনটি একটি নুল পয়েন্টার এক্সপেশেশন ছুড়ে ফেলে। কিন্তু এটা ঝুলন্ত না।
সম্ভব নয়, তবে লেআউট ফোল্ডারটি নাম অনুসারে সাজানো হয়। তাই, আমি আমার প্যাকেজ নামগুলির সাথে লেআউট ফাইলের নামগুলি পূর্বরূপ প্রেরণ করি। যেমন "কেনার" এবং "বাজানো" দুটি প্যাকেজের জন্য:
buying_bought_tracks.xml
buying_buy_tracks.xml
playing_edit_playlist.xml
playing_play_playlist.xml
playing_show_playlists.xml
ফোল্ডার প্যারামিটারটিকে একটি ফোল্ডারে রূপান্তর করে যা Bash Bash Flatten ফোল্ডার স্ক্রিপ্ট পরীক্ষা করে দেখুন