অনক্রিট () এ নুলপয়েন্টারএক্সেপশন অ্যাক্সেসের ভিউ


114

স্ট্যাকওভারফ্লোতে প্রায়শই পোস্ট করা সমস্যার জন্য এটি একটি আধ্যাত্মিক প্রশ্ন।

আমি একটি টিউটোরিয়াল অনুসরণ করছি আমি একটি উইজার্ড ব্যবহার করে একটি নতুন ক্রিয়াকলাপ তৈরি করেছি। আমার ক্রিয়াকলাপের সাথে প্রাপ্ত NullPointerExceptionকোনও পদ্ধতিতে কল করার চেষ্টা করার সময় আমি পাই ।ViewfindViewById()onCreate()

ক্রিয়াকলাপ onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    View something = findViewById(R.id.something);
    something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment()).commit();
    }
}

লেআউট এক্সএমএল ( fragment_main.xml):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="packagename.MainActivity$PlaceholderFragment" >

    <View
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:id="@+id/something" />

</RelativeLayout>

উত্তর:


70

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

দৃশ্যটি খণ্ড লেআউটে রয়েছে ( fragment_main.xml) এবং ক্রিয়াকলাপের বিন্যাসে ( activity_main.xml) নয়। onCreate()ক্রিয়াকলাপের ভিউ হায়ারার্কিতে এটি সন্ধানের জন্য আজীবন চক্রের প্রথম দিকে এবং একটি nullফিরে আসে। এনপিইর nullকারণগুলির জন্য কোনও পদ্ধতি চালু করা ।

পছন্দসই সমাধান হ'ল স্ফীতিত টুকরা বিন্যাসে onCreateView()কল findViewById()করে কোডটি খণ্ডটিতে স্থানান্তর করা rootView:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
  View rootView = inflater.inflate(R.layout.fragment_main, container,
      false);

  View something = rootView.findViewById(R.id.something); // not activity findViewById()
  something.setOnClickListener(new View.OnClickListener() { ... });

  return rootView;
}

পার্শ্ব নোট হিসাবে, খণ্ড লেআউটটি ক্রমশ ক্রিয়াকলাপের ভিয়ারের অংশ হিসাবে এবং ক্রিয়াকলাপের সাথে আবিষ্কারযোগ্য হবে findViewById()তবে কেবল খণ্ডের লেনদেন চালানো হবে। মুলতুবি থাকা খণ্ডের লেনদেনগুলি super.onStart()পরে সম্পাদিত হয় onCreate()


FindViewById অংশটিঅ্যাক্টিভিটি তৈরি করা উচিত।
জার ই আহমের

@ নেপস্টার এটি হতে পারে তবে তা করার দরকার নেই।
লাল্টো

কিছু সময় ক্রিয়াকলাপটি এখনও খণ্ডে সংযুক্ত হয়নি।
জার ই আহমর

1
@ নেপস্টার এবং সে কারণেই ক্রিয়াকলাপে কল findViewById()করা rootViewএবং না করা।
লাল্টো

10

OnStart()পদ্ধতি চেষ্টা করুন এবং কেবল ব্যবহার করুন

View view = getView().findViewById(R.id.something);

অথবা getView().findViewByIdপদ্ধতি ব্যবহার করে কোনও দৃশ্য ঘোষণা করুনonStart()

শ্রোতার দ্বারা ক্লিক করে ঘোষণা করুন anyView.setOnClickListener(this);


আমার জন্য এটি দরকারী ছিল কারণ আমি একটি খণ্ডের অনক্রিটভিউয়ের অভ্যন্তরে একটি ভাইবোন ভিউ অ্যাক্সেস করার চেষ্টা করছিলাম, যেখানে খণ্ডটি এক্সএমএল হিসাবে ঘোষিত হয়েছিল। ভাইবোনদের দৃষ্টিভঙ্গি অনক্রিয়াটভিউতে এখনও শূন্য ছিল কারণ পিতামাতারা ফুল ফোটানো শেষ করেননি, তবে স্টার্টে তাদের ছিল :)
ড্যানিয়েল উইলসন

3

আপনার অ্যাক্সেসের মতামতগুলি খণ্ডের তৈরির দৃশ্য দেখার পদ্ধতিতে স্থানান্তরিত করার চেষ্টা করুন কারণ কখনও কখনও আপনি অনক্রিট পদ্ধতিতে ভিউগুলি অ্যাক্সেস করার চেষ্টা করার সময় সেগুলি নাল পয়েন্টার ব্যতিক্রমের ফলে রেন্ডার করা হয় না।

 @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
     View something = findViewById(R.id.something);
     something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE

     if (savedInstanceState == null) {
           getSupportFragmentManager().beginTransaction()
            .add(R.id.container, new PlaceholderFragment()).commit();
    }
 }

2

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

একটি উদাহরণ নিম্নলিখিত:

public class ContainerActivity extends FragmentActivity implements ExampleFragment.Callback
{
    @Override
    public void onCreate(Bundle saveInstanceState)
    {
        super.onCreate(saveInstanceState);
        this.setContentView(R.layout.activity_container);
        if (saveInstanceState == null)
        {               
             getSupportFragmentManager().beginTransaction()
                .add(R.id.activity_container_container, new ExampleFragment())
                .addToBackStack(null)
             .commit();
        }
        getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
        {
            public void onBackStackChanged()
            {
                int backCount = getSupportFragmentManager().getBackStackEntryCount();
                if (backCount == 0)
                {
                    finish();
                }
            }
        });
    }

    @Override
    public void exampleFragmentCallback()
    {
        Toast.makeText(this, "Hello!", Toast.LENGTH_LONG).show();
    }
}

activity_container.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/activity_container_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

ExampleFragment:

public class ExampleFragment extends Fragment implements View.OnClickListener
{
    public static interface Callback
    {
        void exampleFragmentCallback();
    }

    private Button btnOne;
    private Button btnTwo;
    private Button btnThree;

    private Callback callback;

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        try
        {
            this.callback = (Callback) activity;
        }
        catch (ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "Activity must implement Callback interface.", e);
            throw e;
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.fragment_example, container, false);

        btnOne = (Button) rootView.findViewById(R.id.example_button_one);
        btnTwo = (Button) rootView.findViewById(R.id.example_button_two);
        btnThree = (Button) rootView.findViewById(R.id.example_button_three);

        btnOne.setOnClickListener(this);
        btnTwo.setOnClickListener(this);
        btnThree.setOnClickListener(this);
        return rootView;
    }

    @Override
    public void onClick(View v)
    {
        if (btnOne == v)
        {
            Toast.makeText(getActivity(), "One.", Toast.LENGTH_LONG).show();
        }
        else if (btnTwo == v)
        {
            Toast.makeText(getActivity(), "Two.", Toast.LENGTH_LONG).show();
        }
        else if (btnThree == v)
        {
            callback.exampleFragmentCallback();
        }
    }
}

fragment_example.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <Button
            android:id="@+id/example_button_one"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="30dp"
            android:text="@string/hello" 
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"/>

        <Button
            android:id="@+id/example_button_two"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/example_button_one"
            android:layout_alignRight="@+id/example_button_one"
            android:layout_below="@+id/example_button_one"
            android:layout_marginTop="30dp"
            android:text="@string/hello" />

        <Button
            android:id="@+id/example_button_three"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/example_button_two"
            android:layout_alignRight="@+id/example_button_two"
            android:layout_below="@+id/example_button_two"
            android:layout_marginTop="30dp"
            android:text="@string/hello" />

</RelativeLayout>

এবং এটি একটি বৈধ উদাহরণ হওয়া উচিত, এটি দেখায় যে কীভাবে আপনি কোনও খণ্ড প্রদর্শন করতে কোনও ক্রিয়াকলাপ ব্যবহার করতে পারেন এবং সেই খণ্ডে ইভেন্টগুলি পরিচালনা করতে পারেন। এবং কীভাবে থাকা ক্রিয়াকলাপের সাথে যোগাযোগ করবেন তাও।


1
এই উদাহরণটি ফ্র্যাগমেন্টএকটিভিটি এবং সাপোর্ট ফ্রেগমেন্ট ম্যানেজারের জন্য অ্যান্ড্রয়েড-সাপোর্ট-ভি 4 লাইব্রেরি ব্যবহার করে।
এপিকপান্ডাফোরস

1
একটি এমনকি সম্পূর্ণ উদাহরণ পাওয়া যায় stackoverflow.com/questions/24840509/...
EpicPandaForce

1
যদিও আপনার Ottoকলব্যাকের পরিবর্তে যোগাযোগের জন্য ব্যবহার করা উচিত , এবং Butterknifeভিউগুলি ইনজেক্ট করার জন্য ব্যবহার করা উচিত ।
এপিকপান্ডাফোরস

2

"কিছু" দর্শনটি খণ্ডে রয়েছে এবং ক্রিয়ায় নেই, সুতরাং ক্রিয়াকলাপে এটি অ্যাক্সেস করার পরিবর্তে আপনাকে অবশ্যই খণ্ড শ্রেণিতে এটি অ্যাক্সেস করতে হবে

প্লেসহোল্ডারফ্রেগমেন্ট.ক্লাসে

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_main, container,
  false);

View something = root .findViewById(R.id.something);
something.setOnClickListener(new View.OnClickListener() { ... });

return root;
}

2

আপনি ইউআই উপাদানগুলিতে অ্যাক্সেস করার চেষ্টা করছেন onCreate()তবে, এটি অ্যাক্সেস করা খুব তাড়াতাড়ি, যেহেতু খণ্ডিত দর্শনগুলি onCreateView()পদ্ধতিতে তৈরি করা যেতে পারে । এবং onActivityCreated()পদ্ধতি তাদের উপর যে কোনও ক্রিয়াকলাপ পরিচালনা করতে নির্ভরযোগ্য, যেহেতু এই অবস্থায় ক্রিয়াকলাপ পুরোপুরি লোড is


1

আপনার ক্রিয়াকলাপ_মাইন.এক্সএমএলে নিম্নলিখিতগুলি যুক্ত করুন

<fragment
    android:id="@+id/myFragment"
    android:name="packagename.MainActivity$PlaceholderFragment"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >
</fragment>

0

যেহেতু আপনি আপনার ভিউ ঘোষণা করেছেন fragment_main.xml, সুতরাং সেই অংশের কোডটি সরান যেখানে আপনি খণ্ডটির onCreateView()পদ্ধতিতে এনপিই পাবেন । এটি সমস্যার সমাধান করা উচিত।


0

প্রশ্নের উপরের পোস্ট কোডটিতে একটি সমস্যা রয়েছে: আপনি আরক্রিট পদ্ধতিতে R.layout.activity_main ব্যবহার করছেন তবে এক্সএমএল ফাইলের নাম "ফ্রেগমেন্ট_মাইন.এক্সএমএল", মানে আপনি ফ্রেগমেন্ট_মাইন.এক্সএমএল ফাইলের ভিউ পাওয়ার চেষ্টা করছেন যা প্রদর্শিত হচ্ছে না তাই এটি নাল পয়েন্টার ব্যতিক্রম দেয়। কোডটি পরিবর্তন করুন:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_main);// your xml layout ,where the views are

    View something = findViewById(R.id.something);
    something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE

    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment()).commit();
    }
}

0

আপনাকে গুরুত্বপূর্ণ জিনিসটি মনে রাখতে হবে: নালপয়েন্টারএক্সেপশন ঘটে যখন আপনি আপনার ভেরিয়েবলটি ঘোষণা করেন এবং এর মান নির্ধারণের আগে এর মানটি পুনরুদ্ধার করার চেষ্টা করেন।


0

ব্যবহারের onViewCreated () মেথড যখনই ব্যবহার বা টুকরা থেকে দেখার সংখ্যা কলিং।

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
      View v = view.findViewById(R.id.whatever)
}

0

NullPointerExceptionকল findViewById() onCreate()এবং onCreateView()পদ্ধতিগুলির পরে আমি শ্রোতার আরম্ভ করার মতোই পেয়েছি ।

কিন্তু যখন আমি এটি ব্যবহার করি onActivityCreated(Bundle savedInstanceState) {...}। সুতরাং, আমি অ্যাক্সেস করতে GroupViewএবং আমার শ্রোতাদের সেট করতে পারি।

আমি আশা করি এটি সহায়ক হবে।


0

প্রায় প্রতিটি বিকাশকারী দ্বারা ব্যবহার করা হয়েছে এমন মতামত সন্ধানের জন্য সর্বাধিক জনপ্রিয় লাইব্রেরি।

মাখন ছুরি

হিসাবে আমি তাদের যথাযথ পদ্ধতি সঙ্গে মতামত সন্ধান ব্যাখ্যা যথেষ্ট উত্তর আছে। তবে আপনি যদি প্রতিদিন ভিত্তিতে অ্যান্ড্রয়েড বিকাশকারী এবং কোড হন তবে আপনি মাখন-ছুরি ব্যবহার করতে পারেন যা ভিউ সন্ধানে অনেক সময় সাশ্রয় করে এবং এর জন্য আপনার লেখার কোড নেই, ২-৩ ধাপে আপনি মিলিসেকেন্ডে ভিউগুলি পেতে পারেন ।

অ্যাপ্লিকেশন স্তরের গ্রেডে নির্ভরতা যুক্ত করুন:

implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'

মাখন ছুরির জন্য প্লাগইন যুক্ত করুন:

File -> Settings -> plugins-> 

তারপরে অ্যান্ড্রয়েড বাটারকনিফ জেলজনি অনুসন্ধান করুন এবং প্লাগইন ইনস্টল করুন এবং আপনার স্টুডিওটি পুনরায় চালু করুন এবং আপনি এটি সম্পন্ন করেছেন।

এখন আপনার ক্রিয়াকলাপের অনক্রিয়েট পদ্ধতিতে যান এবং আপনার লেআউট_নামটিতে ডান ক্লিক করুন এবং জেনারেট বোতামে টিপুন এবং বাটারনিফ ইনজেকশন বিকল্পটি নির্বাচন করুন এবং আপনার মতামত উল্লেখগুলি নীচের উল্লেখের মতো স্বয়ংক্রিয়ভাবে তৈরি হবে:

    @BindView(R.id.rv_featured_artist)
    ViewPager rvFeaturedArtist;
    @BindView(R.id.indicator)
    PageIndicator indicator;
    @BindView(R.id.rv_artist)
    RecyclerView rvArtist;
    @BindView(R.id.nsv)
    NestedScrollingView nsv;
    @BindView(R.id.btn_filter)
    Button btnFilter;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.