উত্তর:
View
ডকুমেন্টেশন অনুযায়ী
সনাক্তকারীর এই ভিউয়ের শ্রেণিবিন্যাসে অনন্য হতে হবে না। সনাক্তকারী একটি ধনাত্মক সংখ্যা হওয়া উচিত।
সুতরাং আপনি আপনার পছন্দ মতো কোনও ইতিবাচক পূর্ণসংখ্যা ব্যবহার করতে পারেন তবে এই ক্ষেত্রে সমতুল্য আইডির সাথে কিছু মতামত থাকতে পারে। আপনি যদি setTag
কিছু মূল বিষয়বস্তুতে কলকরণের শ্রেণিবিন্যাসের কিছু ভিউ সন্ধান করতে চান তবে তা কার্যকর হতে পারে।
findViewById
এটি খুঁজে পাওয়া প্রথমটি ফিরিয়ে দেবে।
setContentView()
এর, বলে একই আইডি নম্বরে তাদের আইডি সেট দিয়ে 10 মতামত দিন হয়েছে একই অনুক্রমের , তারপর একটি কল findViewById([repeated_id])
যে এক পুনরাবৃত্তি আইডি সহ প্রথম দৃশ্য সেট ফিরে আসবে। যে আমি বোঝানো কি.
১ level এবং ততোধিক স্তরের এপিআই স্তর থেকে আপনি কল করতে পারেন: দেখুন.জেনারেটভিউআইডি ()
তারপরে View.setId (int) ব্যবহার করুন ।
যদি আপনার অ্যাপ্লিকেশনটি এপিআই স্তরের চেয়ে 17 টির চেয়ে কম টার্গেট করা থাকে তবে ভিউকম্প্যাট.জেনারেটভিউ আইডি () ব্যবহার করুন
AtomicInteger
পদ্ধতি বাস্তবায়নের উপর নজর রাখুন ।
for(;;)
আমি এর আগে কখনও দেখিনি। এটাকে কী বলা হয়?
আপনি R.id
কোনও আইএমএল রিসোর্স ফাইল ব্যবহার করে ক্লাসে আইডি সেট করতে পারেন এবং সংকলনের সময় অ্যান্ড্রয়েড এসডিকে তাদের অনন্য মূল্য দিতে দিন।
res/values/ids.xml
<item name="my_edit_text_1" type="id"/>
<item name="my_button_1" type="id"/>
<item name="my_time_picker_1" type="id"/>
কোডটিতে এটি ব্যবহার করতে:
myEditTextView.setId(R.id.my_edit_text_1);
"int currentId = 1000; whateverView.setId(currentId++);
- যা প্রতিটি সময় currentId++
ব্যবহার করা হয় আইডিটি বাড়িয়ে তোলে, একটি অনন্য আইডি নিশ্চিত করে আমি সংরক্ষণ করতে পারি পরে অ্যাক্সেসের জন্য আমার অ্যারেলিস্টে আইডি।
<resources>
।
এছাড়াও আপনি নির্ধারণ করতে পারেন ids.xml
মধ্যে res/values
। আপনি অ্যান্ড্রয়েডের নমুনা কোডে একটি সঠিক উদাহরণ দেখতে পাবেন।
samples/ApiDemos/src/com/example/android/apis/RadioGroup1.java
samples/ApiDemp/res/values/ids.xml
এপিআই 17 যেহেতু, View
ক্লাসের একটি স্থির পদ্ধতি রয়েছে generateViewId()
যা এটি করবে
সেটআইডিতে ব্যবহারের জন্য উপযুক্ত মান উত্পন্ন করুন
এটি আমার পক্ষে কাজ করে:
static int id = 1;
// Returns a valid id that isn't in use
public int findId(){
View v = findViewById(id);
while (v != null){
v = findViewById(++id);
}
return id++;
}
findViewById()
একটি মন্থর অপারেশন। পদ্ধতির কাজ, কিন্তু কর্মক্ষমতা ব্যয়।
(এটি দ্বিধাগ্রস্থ উত্তর দেওয়ার জন্য একটি মন্তব্য ছিল তবে এটি অনেক দীর্ঘ হয়েছে ... হি)
অবশ্যই এখানে একটি স্ট্যাটিক প্রয়োজন হয় না। আপনি স্থিতিশীল পরিবর্তে, সংরক্ষণ করার জন্য SharedPreferences ব্যবহার করতে পারেন। যেভাবেই হোক, কারণটি হ'ল বর্তমান অগ্রগতিটি সংরক্ষণ করা যাতে জটিল লেআউটের জন্য এটি খুব ধীর না হয়। কারণ, বাস্তবে, এটির একবার ব্যবহার করার পরে এটি পরে দ্রুত হবে। যাইহোক, আমি এটি করার একটি ভাল উপায় বলে মনে করি না কারণ যদি আপনাকে আবার আপনার পর্দা পুনর্নির্মাণ করতে হয় তবে (বলুনonCreate
আবার বলা হয়), তবে আপনি সম্ভবত স্থিরতার প্রয়োজনীয়তা বাদ দিয়ে কোনওভাবেই শুরু থেকে শুরু করতে চান। সুতরাং, এটি স্থির পরিবর্তে একটি উদাহরণ পরিবর্তনশীল করুন।
এখানে একটি ছোট সংস্করণ দেওয়া হয়েছে যা কিছুটা দ্রুত চালিত হয় এবং এটি পড়তে আরও সহজ হতে পারে:
int fID = 0;
public int findUnusedId() {
while( findViewById(++fID) != null );
return fID;
}
উপরের এই ফাংশনটি পর্যাপ্ত হওয়া উচিত। কারণ, যতদূর আমি বলতে পারি, অ্যান্ড্রয়েড-উত্পাদিত আইডিগুলি বিলিয়নে রয়েছে, সুতরাং এটি সম্ভবত 1
প্রথমবারে ফিরে আসবে এবং সর্বদা বেশ দ্রুত হবে। কারণ, এটি বাস্তবে অব্যবহৃত কোনও সন্ধানের জন্য ব্যবহৃত আইডিটি শেষ করে দেবে না। তবে লুপটি হ'ল সেখানে এটি আসলে একটি ব্যবহৃত আইডি হবে।
তবে, আপনি যদি এখনও আপনার অ্যাপ্লিকেশনটির পরবর্তী বিনোদনগুলির মধ্যে অগ্রগতিটি সংরক্ষণ করতে চান এবং স্থিতিশীল ব্যবহার এড়াতে চান। এখানে SharedPreferences সংস্করণটি রয়েছে:
SharedPreferences sp = getSharedPreferences("your_pref_name", MODE_PRIVATE);
public int findUnusedId() {
int fID = sp.getInt("find_unused_id", 0);
while( findViewById(++fID) != null );
SharedPreferences.Editor spe = sp.edit();
spe.putInt("find_unused_id", fID);
spe.commit();
return fID;
}
অনুরূপ প্রশ্নের এই উত্তরটি আপনাকে অ্যান্ড্রয়েড সহ আইডি সম্পর্কে যা জানা দরকার তা আপনাকে জানাতে হবে: https://stackoverflow.com/a/13241629/693927
সম্পাদনা / ফিক্স: ঠিক বুঝতে পেরেছি যে আমি পুরোপুরি সংরক্ষণকে এগিয়ে নিয়েছি। আমি অবশ্যই মাতাল ছিলাম।
'কমপ্যাট' লাইব্রেরি এখন generateViewId()
17 স্তরের পূর্ববর্তী স্তরের জন্য পদ্ধতিটিকে সমর্থন করে ।
কেবল Compat
যে লাইব্রেরির একটি সংস্করণ রয়েছে তা নিশ্চিত করে নিন27.1.0+
উদাহরণস্বরূপ, আপনার build.gradle
ফাইলে, রাখুন:
implementation 'com.android.support:appcompat-v7:27.1.1
তারপরে আপনি ক্লাসের পরিবর্তে ক্লাস generateViewId()
থেকে নিম্নলিখিতটি অনুসরণ করতে পারেন:ViewCompat
View
//Will assign a unique ID
myView.id = ViewCompat.generateViewId()
শুভ কোডিং!
@Fantomlimb এর উত্তরে কেবল একটি সংযোজন,
যদিও View.generateViewId()
এপিআই স্তর> = 17 প্রয়োজন,
এই সরঞ্জামটি সমস্ত API এর সাথে তুলনামূলক।
বর্তমান এপিআই লেভেল অনুসারে,
এটি সিস্টেম এপিআই ব্যবহার করে বা আবহাওয়ার বিষয়ে সিদ্ধান্ত নেয়।
যাতে আপনি একই সময় ব্যবহার করতে পারেন ViewIdGenerator.generateViewId()
এবং View.generateViewId()
একই আইডি পাওয়ার বিষয়ে চিন্তা করবেন না
import java.util.concurrent.atomic.AtomicInteger;
import android.annotation.SuppressLint;
import android.os.Build;
import android.view.View;
/**
* {@link View#generateViewId()}要求API Level >= 17,而本工具类可兼容所有API Level
* <p>
* 自动判断当前API Level,并优先调用{@link View#generateViewId()},即使本工具类与{@link View#generateViewId()}
* 混用,也能保证生成的Id唯一
* <p>
* =============
* <p>
* while {@link View#generateViewId()} require API Level >= 17, this tool is compatibe with all API.
* <p>
* according to current API Level, it decide weather using system API or not.<br>
* so you can use {@link ViewIdGenerator#generateViewId()} and {@link View#generateViewId()} in the
* same time and don't worry about getting same id
*
* @author fantouchx@gmail.com
*/
public class ViewIdGenerator {
private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
@SuppressLint("NewApi")
public static int generateViewId() {
if (Build.VERSION.SDK_INT < 17) {
for (;;) {
final int result = sNextGeneratedId.get();
// aapt-generated IDs have the high byte nonzero; clamp to the range under that.
int newValue = result + 1;
if (newValue > 0x00FFFFFF)
newValue = 1; // Roll over to 1, not 0.
if (sNextGeneratedId.compareAndSet(result, newValue)) {
return result;
}
}
} else {
return View.generateViewId();
}
}
}
for (;;) { … }
অ্যান্ড্রয়েড উত্স কোড থেকে আসে।
generateViewId()
else { return View.generateViewId(); }
এটি 17 ডিভাইসের চেয়ে ছোট এপিআই স্তরের জন্য অসীম লুপে যাবে?
পরিবর্তনশীল আইডি ফর্ম এপিআই 17 ব্যবহারের উত্পন্ন করতে
যা ব্যবহারের জন্য উপযুক্ত মান উত্পন্ন করবে setId(int)
। এই মানটি অ্যাডের জন্য বিল্ড টাইমে উত্পন্ন আইডি মানগুলির সাথে সংঘর্ষ করবে না R.id
।
int fID;
do {
fID = Tools.generateViewId();
} while (findViewById(fID) != null);
view.setId(fID);
...
public class Tools {
private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
public static int generateViewId() {
if (Build.VERSION.SDK_INT < 17) {
for (;;) {
final int result = sNextGeneratedId.get();
int newValue = result + 1;
if (newValue > 0x00FFFFFF)
newValue = 1; // Roll over to 1, not 0.
if (sNextGeneratedId.compareAndSet(result, newValue)) {
return result;
}
}
} else {
return View.generateViewId();
}
}
}
আমি ব্যবহার করি:
public synchronized int generateViewId() {
Random rand = new Random();
int id;
while (findViewById(id = rand.nextInt(Integer.MAX_VALUE) + 1) != null);
return id;
}
এলোমেলো নম্বর ব্যবহার করে আমার সর্বদা প্রথম প্রয়াসে অনন্য আইডি পাওয়ার বিশাল সুযোগ থাকে।
public String TAG() {
return this.getClass().getSimpleName();
}
private AtomicInteger lastFldId = null;
public int generateViewId(){
if(lastFldId == null) {
int maxFld = 0;
String fldName = "";
Field[] flds = R.id.class.getDeclaredFields();
R.id inst = new R.id();
for (int i = 0; i < flds.length; i++) {
Field fld = flds[i];
try {
int value = fld.getInt(inst);
if (value > maxFld) {
maxFld = value;
fldName = fld.getName();
}
} catch (IllegalAccessException e) {
Log.e(TAG(), "error getting value for \'"+ fld.getName() + "\' " + e.toString());
}
}
Log.d(TAG(), "maxId="+maxFld +" name="+fldName);
lastFldId = new AtomicInteger(maxFld);
}
return lastFldId.addAndGet(1);
}
findViewById
কোনও গ্যারান্টি দেয় না কি একই আইডির সাথে একাধিক যদি থাকে তবে কোন ভিউটি ফিরে আসে? দস্তাবেজগুলি কিছুই উল্লেখ করে না।