2

我似乎无法解决这个令人困惑的问题,我有很多东西想在我的班级顶部添加以帮助减少混乱。

由于多种方法使用这些复选框变量。

我想把所有东西都放在开口支架的正下方。

这是有效的,但不是我想要的:

public class MyClass extends Activity implements View.OnClickListener {

    //leaving out most code like onCreate. Just pretend it's there.

    public void checkboth(View view) {

        CheckBox cb1 = (CheckBox) findViewById(R.id.cb1);
        CheckBox cb2 = (CheckBox) findViewById(R.id.cb2);

            cb1.setchecked(true);
            cb2.setchecked(true);

    }

    @Override
    public void onClick(View v) {
    }
}

但是对于我的生活,我无法弄清楚为什么我不能这样做:

public class MyClass extends Activity implements View.OnClickListener {

CheckBox cb1 = (CheckBox) findViewById(R.id.cb1);
CheckBox cb2 = (CheckBox) findViewById(R.id.cb2);

    //leaving out most code like onCreate. Just pretend it's there.

    public void checkboth(View view) {            

        cb1.setchecked(true);
        cb2.setchecked(true);

    }

    @Override
    public void onClick(View v) {
    }
}
4

4 回答 4

7

您不能View在这样的方法之外初始化 s

CheckBox cb1 = (CheckBox) findViewById(R.id.cb1);
CheckBox cb2 = (CheckBox) findViewById(R.id.cb2);

因为这意味着这些行之前运行onCreate()会导致这些变量在您尝试对这些变量调用方法时null抛出一个。NPE这是因为您调用setContentView(R.layout.your_layout)inside ofonCreate()并且您的Views“生活”在 that 内部layout。这意味着在layoutinflated调用setContentView(). 在尝试初始化setContentView()Views. 没有办法绕过那部分。

有些人可能会做的是创建一个单独的函数,在setContentView()调用之后初始化这些变量。像这样的东西

public class MyActivity
    // declare your Views so they are global to the class
    TextView tv;
   // more views
    @Override
    public void onCreat(stuff)
    {
       // super call
       setContentView(R.layout.my_layout);
       init();

然后在你的init()函数中初始化Views你声明的所有

private void init()
{
     tv = (TextView) findViewById(R.id.myTextView);
     // more initializations
}

but you can just initialize them in onCreate(), onResume() or wherever as long as it's after setContentView() Declaring and initializing them in this way will make sure they are all available to other functions, listeners, inner classes, etc... of the Activity. And if you have a lot of Views it may lessen the "clutter" a bit.

于 2013-09-18T19:48:34.557 回答
2

findViewById is a method that can be run from the activity (or any view group) after the view has been inflated. To inflate a view a the activity level, you usually call setContentView.

Since setContentView has not been called yet, no views are attached to the activity.

Here is how to do it

public class MyClass extends Activity implements View.OnClickListener {


        CheckBox cb1;
        CheckBox cb2;

        public void onCreate(Bundle sis) {
            super.onCreate(sis);
            setContentView(R.layout.whatever);

            cb1 = (CheckBox) findViewById(R.id.cb1);
            cb2 = (CheckBox) findViewById(R.id.cb2);
        }

        public void checkboth(View view) {

            cb1.setchecked(true);   
            cb2.setchecked(true);

        }

        @Override
        public void onClick(View v) {
        }
    }
于 2013-09-18T19:49:14.057 回答
1

您不能从这里调用方法 (findViewById) 并期望一个非空值。只有在调用 setContentView(R.layout.my_layout) 后,才会在 android 中创建视图。你必须做的是这样的:

public class MyClass extends Activity implements View.OnClickListener {

CheckBox cb1 = null;
CheckBox cb2 = null;

//leaving out most code like onCreate. Just pretend it's there.
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate();
    setContentView(R.layout.my_layout);
    cb1 = (CheckBox) findViewById(R.id.cb1);
    cb2 = (CheckBox) findViewById(R.id.cb2);   
}

public void checkboth(View view) {            

    cb1.setchecked(true);
    cb2.setchecked(true);

}

@Override
public void onClick(View v) {
}
}
于 2013-09-18T19:48:04.260 回答
0

When you move the declarations to the top of the class, you change local variables to fields. These fields are initialized when an instance is created - which means they are initialized "right before" the constructor executes.

Now, you can not call instance methods (like findViewById) before the implicit call to super() finishes.

Move them to the constructor, and things should work out.

于 2013-09-18T19:48:40.527 回答