এক্সপ্লোর পরিচালনা XML- এ কাস্টম উপাদানগুলির জন্য FindViewById () নালাগুলি দেয়, অন্য উপাদানগুলির জন্য নয়


93

res/layout/main.xmlএই উপাদানগুলি এবং অন্যান্যগুলি সহ আমার একটি রয়েছে:

<some.package.MyCustomView android:id="@+id/foo" (some other params) />
<TextView android:id="@+id/boring" (some other params) />

আমার ক্রিয়াকলাপের অনক্রিটে, আমি এটি করি:

setContentView(R.layout.main);
TextView boring = (TextView) findViewById(R.id.boring);
// ...find other elements...
MyCustomView foo = (MyCustomView) findViewById(R.id.foo);
if (foo == null) { Log.d(TAG, "epic fail"); }

অন্যান্য উপাদানগুলি সাফল্যের সাথে পাওয়া fooগেলেও ফিরে আসে শূন্য। মাই কাস্টমভিউয়ের একটি কনস্ট্রাক্টর রয়েছে MyCustomView(Context c, AttributeSet a)এবং Log.d(...)সেই নির্মাণকারীর শেষে একটি "এপিক ব্যর্থ" এর ঠিক আগে লগকটে সফলভাবে উপস্থিত হয়।

fooনাল কেন ?

উত্তর:


184

কারণ কনস্ট্রাক্টরে আমার super(context)বদলে ছিল super(context, attrs)

উপলব্ধি করে, আপনি যদি আইডির মতো বৈশিষ্ট্যগুলিতে পাস না করেন তবে ভিউটির কোনও আইডি থাকবে না এবং সেই আইডিটি ব্যবহার করে খুঁজে পাওয়া যাবে না। :-)


4
আপনার নিজের প্রশ্নের উত্তর দিতে সক্ষম হতে সর্বদা :) আপনারও গ্রহণযোগ্য উত্তর হিসাবে চিহ্নিত করতে ভুলবেন না।
ম্যাটসি

প্রকৃতপক্ষে. এসও আমাকে অনুমতি দিলে তা করবে ("আপনি নিজের উত্তরটি 2 দিনের মধ্যে গ্রহণ করতে পারেন" ")
ক্রিস বয়েল

4
এছাড়াও, আপনার মতো লাইনের মতো (MyCustomView) foo = findViewById(R.id.foo);হওয়া উচিত নয় MyCustomView foo = (MyCustomView) findViewById(R.id.foo);?
জেরেমি লোগান

4
একই সমস্যা ছিল, আমার ক্ষেত্রে আমি সেট কনটেন্ট ভিউ () .. ভুলে গিয়েছিলাম .. এক্সডি
টম ব্রিটো

আছে: vogella.com এই ধরনের জিনিসগুলি জন্য একটি চমৎকার উদাহরণ vogella.com/articles/AndroidCustomViews/article.html
Wolkenjaeger

27

আমার একই সমস্যা কারণ আমার কাস্টম ভিউতে আমি কন্সট্রাক্টরকে ওভাররাইড করেছিলাম তবে সুপার কন্ট্রাক্টর উইট অ্যাটর্স প্যারামিটকে অনুরোধ করেছি। এটি কপি পেস্ট)

আমার আগের নির্মাণকারীর সংস্করণ:

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

এখন আমার আছে:

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

এবং যে কাজ করে!


একই সমস্যা এখানে। ঘটনাচক্রে এটি আমার জন্যও একটি অনুলিপি পেস্ট ত্রুটি ছিল।
কুর্টকোবাইন

একই জিনিস আমার ঘটেছে। স্ট্যাকওভারফ্লোতে সবচেয়ে সঠিক উত্তর। ফিরে এট্রিবিউটসেট অ্যাটর্স যুক্ত করার সময়, সবকিছু ঠিক আছে।
স্পাইক্যাং

আমি অনুমান করি আমরা সবাই কাস্টম ভিউ সহ একই টিউটোরিয়ালটি দেখেছিলাম;) এই ত্রুটিটি আমাকে 0,5 ঘন্টা অর্থহীন ডিবাগিংয়ে নিয়ে গিয়েছিল ...
KrwawyyFefir

এটি আমার জন্যও কাজ করেছিল! আমি বেশ কিছুক্ষণ এই লড়াই করেছি। ধন্যবাদ!
us_david

18

আমারও একই সমস্যা ছিল। আমার ভুলটি ছিল: আমি লিখেছি

        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View layout=inflater.inflate(R.layout.dlg_show_info, null);
        alertDlgShowInfo.setView(layout);
        TableRow trowDesc=(TableRow)findViewById(R.id.trowDesc);

এবং আমি যখন একটি এক্সএমএল ফাইল থেকে ভিউ "লোড" করতে একটি ইনফ্লেটার ব্যবহার করেছি, শেষ লাইনটি ভুল ছিল। এটি সমাধান করার জন্য, আমাকে লিখতে হয়েছিল:

TableRow trowDesc=(TableRow)layout.findViewById(R.id.trowDesc);

আমি আমার সমাধানটি লিখেছি, কারও ক্ষেত্রে যদি একই সমস্যা হয়।


বাবু, তুমি একটা জিনিয়ান এসও
IgorGanapolsky

এটি আমার জন্যও সমস্যা ছিল। বাহ, কী এক টুকরো ... আমাকে নিজেই এটি বের করতে কয়েক দিন লাগত। ধন্যবাদ!
poshaughnessy

18

বিভিন্ন কারণ মনে হয়। অনুরূপ সমস্যা সমাধানের জন্য আমি সদ্যগ্রহণের জন্য "ক্লিন ..." ব্যবহার করেছি। (ফাইন্ডভিউবিআইডি এর আগেও কাজ করেছিল এবং কোনও কারণে শূন্যে ফিরে আসতে শুরু করেছে।)


4
স্পষ্টতই, অন্তর্নিহিত সমস্যাটি হ'ল আর জাভা আইডিগুলি কোনওভাবে ভেঙে যায় বা সম্ভবত আপডেট হয় না। আমি এটি কেবল আইডি দিয়েই লক্ষ্য করি না, তবে অন্যান্য ক্ষেত্রে যেমন, একটি টেক্সটভিউতেও ভুল স্ট্রিং প্রদর্শিত হয় really তবে কেন এটি ঘটে তা সত্যই জানেন না।
জেলিফিশ

এটি আমাকে দীর্ঘদিনের জন্য দুঃখ দিচ্ছিল - একজন শুদ্ধ আমার পক্ষে এটি ঠিক করেছিল।
নিকোলাস এমটি এলিয়ট

4
পরিষ্কার, সত্যিই। বাহ, যে স্তন্যপান!
টিম বাথ

11

একই সমস্যা, তবে ভিন্ন সমাধান: আমি কল করিনি

setContentView(R.layout.main)

আগে আমি এখানে বর্ণিত মতামতটি খুঁজতে চেষ্টা করেছি


আমি মনে করি যদি আপনি বর্তমান সম্পর্কিত দৃষ্টিভঙ্গির পরিবর্তে অন্য ভিউতে কোনও উপাদান পেয়ে থাকেন তবে এটিই সমাধান।
স্টারকব

4

আপনার যদি একাধিক লেআউট সংস্করণ (স্ক্রিন ঘনত্বের উপর নির্ভর করে, এসডিকে সংস্করণগুলি) থাকে তবে নিশ্চিত হয়ে নিন যে এগুলির সমস্তটিতে আপনার সন্ধান করা উপাদান অন্তর্ভুক্ত রয়েছে।


2

আমার ক্ষেত্রে সন্ধান করুন ভিউআইআইডি নালাগুলি ফিরে আসছিল কারণ আমার কাস্টম ভিউটি মূল এক্সএমএলে এই জাতীয় কিছু দেখায়:

        <com.gerfmarquez.seekbar.VerticalSeekBar  
            android:id="@+id/verticalSeekBar"
            android:layout_width="wrap_content" 
            android:layout_height="fill_parent" 
            />

এবং আমি জানতে পেরেছিলাম যে আমি যখন এক্সএমএনএলএস স্টাফ যুক্ত করি তখন এটি এর মতো কাজ করে:

        <com.gerfmarquez.seekbar.VerticalSeekBar  
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/verticalSeekBar"
            android:layout_width="wrap_content" 
            android:layout_height="fill_parent" 
            />


1

আমার জন্য, যখন আমি প্রকল্পের সেটিংসে জাভা বিল্ড পাথের উত্সটিতে রেজ ফোল্ডারটি যুক্ত করেছি তখন সমস্যার সমাধান হয়েছিল।


1

এক্সএমএল লেআউটটির মাধ্যমে আমি একটি কাস্টম ভিউ যুক্ত করেছি এবং তারপরে অ্যাপ্লিকেশনটিতে অন্য কোথাও একটি কলব্যাক সংযুক্ত করার চেষ্টা করেছি ... আমি একই সমস্যাটিতে এসেছি

আমি একটি কাস্টম ভিউ তৈরি করেছি এবং আমার "লেআউট_মাইন.এক্সএমএল" এ যুক্ত করেছি

public class MUIComponent extends SurfaceView implements SurfaceHolder.Callback {
    public MUIComponent (Context context, AttributeSet attrs ) {
        super ( context, attrs );
    }
    // ..
}

এবং মূল ক্রিয়াকলাপে আমি কিছু কলব্যাক সংযুক্ত করতে এবং এক্সএমএল থেকে ইউআই উপাদানগুলির রেফারেন্স পেতে চেয়েছিলাম।

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ...

        MUIInitializer muiInit = new MUIInitializer();
        muiInit.setupCallbacks(this);
        muiInit.intializeFields(this);
    }       
}

ইনিডিলাইজারটি অভিনব কিছু করছে না তবে কাস্টম ভিউতে (এমইউআইকিউম্পোনেন্ট) বা অন্যান্য নন-কাস্টম ইউআই উপাদানগুলিতে এটি পরিবর্তন করার চেষ্টা করেছিল তবে অ্যাপ্লিকেশনটিতে উপস্থিত হচ্ছিল না।

public class MUIInitializer {

    // ...

    public void setupCallbacks ( Activity mainAct ) {


        // This does NOT work properly
        // - The object instance returned is technically an instance of my "MUICompnent" view
        //   but it is a *different* instance than the instance created and shown in the UI screen
        // - Callbacks never get triggered, changes don't appear on UI, etc.
        MUIComponent badInst = (MUIComponent) mainAct.findViewById(R.id.MUIComponent_TESTSURF);


        // ...
        // This works properly

        LayoutInflater inflater = (LayoutInflater) mainAct.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View inflatedLayout = inflater.inflate ( R.layout.activity_main, null );

        MUIComponent goodInst = (MUIComponent) inflatedLayout.findViewById(R.id.MUIComponent_TESTSURF);


        // Add callbacks
        // ...
    }

}

"ব্যাডইনস্ট" এবং "গুডইনস্ট" এর মধ্যে পার্থক্যটি হ'ল:

  • BadInst ক্রিয়াকলাপের ফাইন্ড ভিউবাইআইডি ব্যবহার করে
  • গুডইনস্টটি লেআউটটিকে স্ফীত করে এবং সন্ধানের জন্য স্ফীত লেআউটটি ব্যবহার করে

ভিনসেন্টের একই সমাধান রয়েছে ... এবং তার উত্তরের সংক্ষিপ্ততা তার বদলে ... +1 তার পরিবর্তে :)
DevByStarlight

1

এটি পরিধানের জন্য একটি কাস্টম উপাদান দিয়ে আমার সাথে ঘটেছিল, তবে এটি সাধারণ পরামর্শের অংশ। আপনি যদি কোনও স্টাব ব্যবহার করছেন (যেমন আমি ব্যবহার করছিলাম WatchViewStub) তবে আপনি findViewById()যে কোনও জায়গায় কল রাখতে পারবেন না । স্টাবের ভিতরে থাকা সমস্ত কিছু অবশ্যই প্রথমে ফুলে উঠবে, যা কেবল পরে ঘটে না setContentView()। সুতরাং, এটি হওয়ার জন্য অপেক্ষা করতে আপনার এই জাতীয় কিছু লেখা উচিত:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_wear);
    final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
    stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
        @Override
        public void onLayoutInflated(WatchViewStub stub) {
            myCustomViewInst = (MyCustomView) findViewById(R.id.my_custom_view);
            ...

0

আমার সমস্যা টাইপ ছিল। আমি লিখেছিলাম android.id(বিন্দু) পরিবর্তে android:id। : পি

দৃশ্যত আমার কাস্টম উপাদান এক্সএমএল মধ্যে সিনট্যাক্স চেক নেই। :(


0

একই সমস্যা ছিল।

কয়েকটা বাচ্চা নিয়ে আমার লেআউট ছিল। তাদের একজনের নির্মাণকারীর কাছ থেকে আমি অন্য সন্তানের কাছে রেফারেন্স (কনটেক্সট.ফাইন্ডভিউবিআইআইডি ব্যবহার করে) পাওয়ার চেষ্টা করছিলাম। এটি কাজ করছিল না কারণ দ্বিতীয় সন্তানের বিন্যাসে আরও সংজ্ঞায়িত করা হয়েছিল।

আমি এটি এর মতো সমাধান করেছি:

setContentView(R.layout.main);
MyView first = findViewById(R.layout.first_child);
first.setSecondView(findViewById(R.layout.second_child));

বাচ্চাদের ক্রমটি বিপরীত থাকলে এটিও কার্যকর হবে তবে আমার ধারণা এটি সাধারণত উপরের মতো করা উচিত।


4
সাধারণভাবে আপনি findViewByIdক এর কন্সট্রাক্টর ব্যবহার করবেন না View, বরং আরম্ভের কোডটি ভিতরে রাখবেন OnFinishInflate?
সঞ্জয় মনোহর

0

findViewById()পদ্ধতি কখনও কখনও ফেরৎ nullযখন বিন্যাস রুট কোন হয়েছে android:idঅ্যাট্রিবিউট। এক্সএলএমএল ফাইলের লেআউট উত্পন্ন করার জন্য গ্রহপ উইজার্ড android:idমূল উপাদানটির জন্য স্বয়ংক্রিয়ভাবে বৈশিষ্ট্য উত্পন্ন করে না ।


0

আমার ক্ষেত্রে দৃশ্যটি পিতামাতার মধ্যে ছিল না এমন দৃষ্টিতে নয় যা আমি এটিকে কল করার চেষ্টা করছিলাম So সুতরাং সন্তানের দৃশ্যে আমাকে ফোন করতে হয়েছিল:

RelativeLayout relLayout = (RelativeLayout) this.getParent();
View view1 = relLayout.findViewById(R.id.id_relative_layout_search);

0

'ক্লিন' বিকল্পটি আমার পক্ষে কাজ করেছিল।

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

একবার আমি আমার ওয়ার্কস্টেশনে এনটিপি সেটিংস ঠিক করে দিলে, সমস্যাটি আর কখনও ঘটেনি। যথাযথ এনটিপি সেটিংস ছাড়াই, ঘড়িগুলি দ্রুত প্রবাহিত হওয়ায় এটি প্রতি কয়েক ঘন্টার মধ্যে ঘটে।


উপরের উত্তরের মন্তব্যে এটি যুক্ত করা উচিত
ট্রুং নগুইন

0

উত্তরের জন্য সন্ধানের জন্য আরও একটি তুচ্ছ ভুল যুক্ত করতে:

আপনি আসলে সঠিক লেআউট XML ফাইল সম্পাদনা করছেন তা পরীক্ষা করুন ...


0

আমার একই সমস্যা ছিল কারণ আমি আমার সমস্ত লেআউট ফোল্ডারে ভিডি আইডি আপডেট করতে ভুলে গিয়েছি।

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