可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
So the title says it all. I'm getting a compilation error inside of my onClick
.
Here's the code.
public class fieldsActivity extends Activity { Button addSiteButton; Button cancelButton; Button signInButton; /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // to create a custom title bar for activity window requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.fields); // use custom layout title bar getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.topbar); Pager adapter = new Pager(); ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager); mPager.setAdapter(adapter); mPager.setCurrentItem(1); addSiteButton = (Button) findViewById(R.id.addSiteButton); addSiteButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mPager.setCurrentItem(2, true); //Compilation error happens here. } }); cancelButton = (Button) findViewById(R.id.cancel_button); signInButton = (Button) findViewById(R.id.sign_in_button); }
回答1:
If you don't want to make it final, you can always just make it a global variable.
回答2:
The error says it all, change:
ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);
to
final ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);
回答3:
You can declare the variable final, or make it an instance (or global) variable. If you declare it final, you won't be able to change it later.
Any variable defined in a method and accessed by an anonymous inner class must be final. Otherwise, you could use that variable in the inner class, unaware that if the variable changes in the inner class, and then it is used later in the enclosing scope, the changes made in the inner class did not persist in the enclosing scope. Basically, what happens in the inner class stays in the inner class.
I wrote a more in-depth explanation here. It also explains why instance and global variables do not need to be declared final.
回答4:
As @Veger said, you can make it final
so that the variable can be used in the inner class.
final ViewPager pager = (ViewPager) findViewById(R.id.fieldspager);
I called it pager
rather than mPager
because you are using it as a local variable in the onCreate
method. The m
prefix is cusomarily reserved for class member variables (i.e. variables that are declared at the beginning of the class and are available to all class methods).
If you actually do need a class member variable, it doesn't work to make it final because you can't use findViewById
to set its value until onCreate
. The solution is to not use an anonymous inner class. This way the mPager
variable doesn't need to be declared final and can be used throughout the class.
public class MainActivity extends AppCompatActivity { private ViewPager mPager; private Button mButton; @Override public void onCreate(Bundle savedInstanceState) { // ... mPager = (ViewPager) findViewById(R.id.fieldspager); // ... mButton.setOnClickListener(myButtonClickHandler); } View.OnClickListener myButtonClickHandler = new View.OnClickListener() { @Override public void onClick(View view) { mPager.setCurrentItem(2, true); } }; }