ভিউবিআইআইডি-র ফলাফল দেওয়ার দরকার নেই?


152

সম্প্রতি আমি দেখতে পেয়েছি যে অ্যান্ড্রয়েডস্টুডিও আমাকে কিছু ক্লাস কাস্ট অপসারণ করার জন্য মনে করিয়ে দেয়। আমার মনে আছে যে পুরানো সময়ে, আমাদের ফাইন্ড ভিউআইআইডি-র ফলাফল দিতে হয়েছিল, তবে এখন এটি প্রয়োজনীয় নয়।

FindViewById এর ফলাফলটি এখনও দেখুন, তাই আমি জানতে চাই কেন আমাদের ক্লাস কাস্ট করার দরকার নেই?

আমি উল্লিখিত কোনও দলিল খুঁজে পাচ্ছি না, কেউ কি কোনও নথি খুঁজে পেতে পারেন?


7
কারণ এখন এটা <T extends View> T findViewById(int id)?
সেলভিন

ভিউ ক্লাসে নেই এমন কোনও ক্রিয়াকলাপের ক্ষেত্রে আপনার কাস্টিং দরকার, যেমন ইমেজভিউয়ের মতো, যদি আপনি সেটআইমেজ রিসোর্স ব্যবহার করতে চান, তবে আপনাকে চিত্রভিউ দিয়ে সন্ধান ভিউবিআইড কাস্ট করতে হবে
গগন দীপ

তবে "রিডানড্যান্ট" কাস্টিং অপসারণ করা হলে এক নজরে ভেরিয়েবল টাইপটি জানার জন্য আমি কিছুটা অসুবিধা বোধ করি।
ফল 10

উত্তর:


235

এপিআই 26 দিয়ে শুরু করে, findViewByIdএর রিটার্ন টাইপের জন্য অনুমান ব্যবহার করে, তাই আপনাকে আর কাস্ট করতে হবে না।

পুরানো সংজ্ঞা:

View findViewById(int id)

নতুন সংজ্ঞা:

<T extends View> T findViewById(int id)

সুতরাং যদি আপনার compileSdkবয়স কমপক্ষে 26 হয় তবে এর অর্থ হ'ল আপনি এটি ব্যবহার করতে পারেন :)


ধন্যবাদ, এবং অন্য একটি প্রশ্ন। আমি sdk26 এর জন্য sdk ম্যানেজারে উত্স খুঁজে পাচ্ছি না, তবে দয়া করে এই নতুন সংজ্ঞাটি কোথায় পাব?
এরিক ঝাও

17
যদি আমরা কাস্টটি অপসারণ করি তবে আমাদের অ্যাপ্লিকেশনগুলি এখনও নিম্ন ডিভাইসে চালানো যেতে পারে, তাই না?
ব্যবহারকারী 1032613

17
@ ব্যবহারকারী 1032613: হ্যাঁ অ্যাপসটি এখনও কোনও সমস্যা ছাড়াই নিম্ন ডিভাইসে কাজ করতে পারে।
আলিরেজা নুরালি

1
এটি যদি ভুল ধরণের হয় তবে কি এটি ব্যতিক্রম করবে?
ফবিমাস্টার

1
হিসাবে যদি লেআউট ফাইলের ভিউটি ভিন্ন ধরণের হয়? হ্যাঁ, অবশ্যই এটি একটি হবে ClassCastException
এডওয়ার্ড বি

13

এই নিবন্ধ অনুযায়ী :

ম্যানুয়াল castালাইয়ের প্রয়োজনীয়তা অপসারণ করতে নিম্নলিখিত ফাংশন জাভার জেনেরিকগুলি স্বয়ংক্রিয় টাইপের অনুক্রমের উপর নির্ভর করে:

protected <T extends View> T findViewById(@IdRes int id) {
    return (T) getRootView().findViewById(id);
}

11

পুরানো সংস্করণগুলিতে:

AutoCompleteTextView name = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);

এসডিকে 26 সহ অ্যান্ড্রয়েড স্টুডিও 3.0 থেকে:

AutoCompleteTextView name = findViewById(R.id.autoCompleteTextView);

16
এটি প্রশ্নের উত্তর সরবরাহ করে না।
বিজয় শর্মা

1

অ্যান্ড্রয়েড স্টুডিও কাস্টিং অপসারণের স্মরণ করিয়ে দেয়, যদি আপনি দৃশ্য শ্রেণি থেকে অনুলিপি বা কিছু সাধারণ পদ্ধতিগুলির মতো সাধারণ বৈশিষ্ট্যগুলি ব্যবহার করেন তবে অনক্লিক ()

উদাহরণ স্বরূপ:

((ImageView) findViewById(R.id.image_car)).setVisibility(View.VISIBLE);

এই ক্ষেত্রে আপনি কেবল লিখতে পারেন:

findViewById(R.id.image_car).setVisibility(View.VISIBLE);

2
আপনাকে এখনও প্রকারটি ঘোষণা করতে হবে, আপনাকে লিখতে হবে: FindViewById <আইজামভিউ> (R.id.image_car) .setVisibility (View.VISIBLE);
স্লিকলিটো

অ্যান্ড্রয়েড স্টুডিও আমাদের স্পষ্টত কাস্টিং অপসারণ করানোর জন্য স্মরণ করিয়ে দেয় কারণ এটি জাভার জেনেরিকের স্বয়ংক্রিয় টাইপ অনুমানের প্রয়োগে পরিবর্তিত হয়েছে - আপনি কোন পদ্ধতিটি ব্যবহার করছেন তাতে এর কোনও যোগসূত্র নেই।
জিরো ডিভাইডার

1

অ্যান্ড্রয়েড 0, ingালাই পরিষ্কার করুন

আইও 2017 সালে গুগল যে জিনিসগুলির ঘোষণা করে তার মধ্যে একটি হ'ল 'ফেলে দেওয়া' :) বলে। অ্যানড্রয়েড বিকাশকারীকে উইন্ডোজবিআইআইডি () এর জন্য একটি ম্যানুয়াল কাস্টিং করতে হবে না। উদাহরণস্বরূপ FindViewById () ব্যবহার করে কোনও পাঠ্য ভিউ পাওয়ার পুরানো উপায়টি এরকম কিছু হবে।

TextView txtDesc = (TextView) findViewById(R.id.textViewDesc);
txtDesc.setText(getString(R.string.info_angkot_description));

নতুন উপায়টি এটির মতো হবে

TextView txtDesc = findViewById(R.id.textViewDesc);
txtDesc.setText(getString(R.string.info_angkot_description));

এটি একটি সাধারণ পরিবর্তন। তবে একটি পাকা প্রোগ্রামারের জন্য, এর মতো একটি পরিষ্কার কোড আপনাকে খুব আনন্দিত করতে পারে এবং এটি আপনার কোডিং মেজাজে সহায়তা করে :)

এটি করতে সক্ষম হওয়ার জন্য আপনার প্রজেক্ট সংকলিত এসডিকে সংস্করণটি আপনার অ্যাপ্লিকেশন বিল্ডড্র্যাডলে 26 সংস্করণে সেট করতে হবে।

আপনি এখনও আগের এসডিকে সংস্করণটিকেও লক্ষ্য করে তুলতে পারেন, সুতরাং এটি একটি অ-প্রবেশমূলক পরিবর্তন।

এখন আসল সমস্যা, আপনি কীভাবে সেই পুরানো কোডটি পরিষ্কার করেন যা পুরো সময়টিতে .ালাই ব্যবহার করে। বিশেষত যখন আপনার কাছে শত শত ক্রিয়াকলাপের ফাইল থাকে। আপনি এটি ম্যানুয়ালি করতে পারেন, বা এটি করার জন্য কোনও ইন্টার্ন ভাড়া নিতে পারেন 😛 😛 তবে ভাগ্যক্রমে এই সমস্ত ইন্টার্নের জন্য, অ্যান্ড্রয়েড স্টুডিও ইতিমধ্যে এটিতে আমাদের সহায়তা করার জন্য প্রস্তুত।

যখন আপনি আপনার ক্যারেটটি রাখেন (বা রিডানড্যান্ট ingালাইতে ক্লিক করুন) অ্যান্ড্রয়েড স্টুডিও রিডানডেন্ট কাস্টিং পরিচালনা করার জন্য 2 বিকল্পের পরামর্শ দেবে।

প্রথমে এটি সেই অপ্রয়োজনীয় castালাই সরিয়ে ফেলার পরামর্শ দেবে বা আপনি ক্লিন আপ কোড নির্বাচন করতে পারেন। এটি সেই ফাইলের জন্য সমস্ত অপ্রয়োজনীয় removeালাই সরিয়ে ফেলবে। এটি আরও ভাল, তবে আমরা আরও চাই। আমরা প্রতিটি ফাইল খুলতে চাই না এবং এটি একে একে পরিষ্কার করতে চাই।

ইন্টেলিজিজ আইডিয়া বিশেষ করে তোলে এমন একটি জিনিস হ'ল এমন একটি বৈশিষ্ট্য যা অভিপ্রায় কর্ম বলে। আপনাকে যা করতে হবে তা হ'ল সিটিআরএল + শিফট + এ চাপুন এবং তারপরে ক্লিন টাইপ করুন। এবং কোড ক্লিন আপ অ্যাকশন নির্বাচন করুন এবং পুরো প্রকল্পের সুযোগটি নির্বাচন করুন। এই কয়েকটি সাধারণ পদক্ষেপের সাহায্যে আপনার কোড পুরো লট ক্লিনার হবে।

একটি গুরুত্বপূর্ণ বিষয় আপনি কিছু কোড সংস্করণ সিস্টেমের সাহায্যে এটি করেন। এইভাবে আপনি অভিপ্রায় ক্রিয়া দ্বারা যে পরিবর্তনগুলি করা হচ্ছে তার তুলনা করতে পারেন এবং যে কোনও ফাইল আপনি চান তা ফিরিয়ে দিতে পারেন।

মূল পোস্ট থেকে অনুলিপি করা:

https://medium.com/@abangkis/android-0-clean-up-casting-c30acec56cef


1
প্রশ্নটি ছিল why, নয় how:The result of findViewById is still View, so i want to know why we don't need to cast the class?
জিরো ডিভাইডার

"আপনাকে যা করতে হবে তা হ'ল সিটিআরএল + শিফট + এ চাপুন এবং তারপরে ক্লিন টাইপ করুন"। "টাইপ ক্লিন" বলতে কী বোঝ? আপনি যদি সেই সময়ে টাইপ করা শুরু করেন, আপনি পুরো ফাইলটি মুছে
ফেলবেন

0

এর উত্স কোডে ViewGroup, রিটার্ন আর্গুমেন্টের একটি কাস্ট রয়েছে। সুতরাং আর কাস্ট করার দরকার নেই:

@Nullable
public final <T extends View> T findViewById(@IdRes int id) {
    if (id == NO_ID) {
        return null;
    }
    return findViewTraversal(id);
}

@Override
protected <T extends View> T findViewTraversal(@IdRes int id) {
    if (id == mID) {
        return (T) this;  //###### cast to T
    }

    final View[] where = mChildren;
    final int len = mChildrenCount;

    for (int i = 0; i < len; i++) {
        View v = where[i];

        if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
            v = v.findViewById(id);

            if (v != null) {
                return (T) v; //###### cast to T
            }
        }
    }

    return null;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.