web-dev-qa-db-ja.com

ヌルポインター例外-findViewById()

誰でも私がこのプログラムで何が問題になる可能性があるかを見つけるのを手伝うことができます。 onCreate()メソッドでは、findViewById()はすべてのIDに対してnullを返します。これにより、後でnullポインター例外が発生します。 findViewById()がビューを見つけられない理由がわかりません。助言がありますか?

これがメインコードです:

public class MainActivity extends Activity {

    ViewPager pager;
    MyPagerAdapter adapter;
    LinearLayout layout1, layout2, layout3;

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

        layout1 = (LinearLayout) findViewById(R.id.first_View);
        layout2 = (LinearLayout) findViewById(R.id.second_View);
        layout3 = (LinearLayout) findViewById(R.id.third_View);

        adapter = new MyPagerAdapter();
        pager = (ViewPager) findViewById(R.id.main_pager);
        pager.setAdapter(adapter);
    }

    private class MyPagerAdapter extends PagerAdapter
    {

        @Override
        public int getCount() { 
            return 3;
        }

        @Override
        public Object instantiateItem(ViewGroup collection, int position) {

            LinearLayout l = null;

            if (position == 0 )
            {
                l = layout1;
            }
            if (position == 1)
            {
                l = layout2;
            }

            if (position == 2)
            {
                l = layout3;
            }
                collection.addView(l, position);
                return l;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return (view==object);
        }

         @Override
         public void destroyItem(ViewGroup collection, int position, Object view) {
                 collection.removeView((View) view);
         }
    }
}

そして、関連するXMLファイル:

activity_mainレイアウト:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
                Android:orientation="vertical"
                Android:layout_width="fill_parent"
                Android:layout_height="fill_parent"
                Android:background="#a4c639">


    <Android.support.v4.view.ViewPager
                        Android:layout_width="match_parent" 
                        Android:layout_height="match_parent" 
                        Android:id="@+id/main_pager"/>
</LinearLayout>

activity_firstレイアウト:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/first_View">

<TextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="@string/hello_world" />

<Button
    Android:id="@+id/button1"
    style="?android:attr/buttonStyleSmall"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="Button" />

</LinearLayout>

activity_secondレイアウト:

 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"

Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/second_View">

<TextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="@string/hello_world" />

</LinearLayout>

そしてactivity_thirdレイアウト:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/third_View">

<TextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="@string/hello_world" />

</LinearLayout>
46
user2629828

findViewById()は、setContentView()で指定したレイアウトに存在する場合はビューを返します。それ以外の場合は、nullを返します。

たとえば、setContentView(R.layout.activity_first);を呼び出してからfindViewById(R.id.first_View);を呼び出すと、レイアウトであるビューが返されます。

ただし、findViewById(R.id.second_View);を呼び出すと、nullが返されます。これは、activity_first.xmlレイアウト@+id/second_View

78

取得しようとしているビューは、activity_main レイアウト。ページャーに追加しようとしているビューをプログラムで膨らませる必要があります。

@Override
public Object instantiateItem(ViewGroup collection, int position) {
    LinearLayout l = null;

    if (position == 0) {
        l = (LinearLayout) View.inflate(this, R.layout.activity_first, null);
    }
    if (position == 1) {
        l = (LinearLayout) View.inflate(this, R.layout.activity_second, null);
    }
    if (position == 2) {
        l = (LinearLayout) View.inflate(this, R.layout.activity_third, null);
    }

    collection.addView(l, position);
    return l;
}
2
ssantos

強調が追加されました

Activityクラス内の場合。

Activity.findViewById(int id)

onCreate(Bundle)で処理されたXMLid属性によって識別されたビューを検索します。


それ以外の場合、フラグメント、アダプター、ViewからのLayoutInflaterなど。

View.findViewById(int id)

指定されたid子ビューを探します。このビューに特定のIDがある場合、このビューを返します。


どちらの場合でも、

返品
見つかった場合のビューまたはそれ以外の場合はnull


次に、XMLファイルを再確認します。 setContentViewまたはinflater.inflateに正しい値を入力してください。

アクティビティの場合、findViewByIdの後にsetContentViewを呼び出します。

次に、そのレイアウトにAndroid:id="@+id/..."で探しているビューがあることを確認します。 +@+idにあることを確認します。これにより、リソースがR.id値に追加され、Javaから確実に検索できるようになります。

2
cricket_007

今日、このエラーを取得しましたが、クリアするのは非常に簡単だったので、「フェイスパルム」しました。

res/layout-portディレクトリ!!!のレイアウトxmlファイルにUI要素を追加してみてください

1
some_nick

それらのビューにアクセスする前に、これらのビューをページャーアダプターに追加します。

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

    adapter = new MyPagerAdapter();
    pager = (ViewPager) findViewById(R.id.main_pager);
    pager.setAdapter(adapter);

    layout1 = (LinearLayout) findViewById(R.id.first_View);
    layout2 = (LinearLayout) findViewById(R.id.second_View);
    layout3 = (LinearLayout) findViewById(R.id.third_View);

}

ページャアダプタで:

public Object instantiateItem(View collection, int position) {
    if(position == 0){
        View layout = inflater.inflate(R.layout.activity_first, null);

        ((ViewPager) collection).addView(layout);

        return layout;
    } 
    ... and so forth.

}

ここから、findViewByIdを介してそれらにアクセスできます。

1
nebulae

Eclipseでプロジェクトをクリーンアップする必要がある場合があります(Project-Clean ..)。

1
Vlad

私の場合、それは私の側の愚かな間違いでした。 OnCreateメソッドでコードを記述しましたが、それは上記setContentView行でした。この行の下にコードを移動すると、アプリケーションは正常に動作し始めました。

setContentView(R.layout.activity_main);
1
Will Buffington

上記の@Warlockが正しいことは、正しい方法でLinearLayout layout1、layout2、layout3を初期化する必要があります。

LinearLayout layout1 = (LinearLayout) View.inflate(this, R.layout.first_View, null);
LinearLayout layout2 = (LinearLayout) View.inflate(this, R.layout.second_View, null);
LinearLayout layout3 = (LinearLayout) View.inflate(this, R.layout.third, null);

私のアドバイスがあなたを助けることを望みます

0
ArronXY

Androidでは、findViewById(R.id.some_id)は、レイアウトセットでビューを見つけているときに機能します。

つまり、レイアウトを設定した場合は次のように言います。

setContentView(R.layout.my_layout);

ビューはこのレイアウト(my_layout)でのみ見つけることができます。

あなたのコードでlayout1layout2layout3はすべて3つの異なるレイアウトであり、アクティビティに設定されていません。

0
Charan

findViewByIdメソッドは、レイアウト内にあるもの(setContentViewで呼び出したもの)を見つける必要があります

0
Chinevu Amadi