Доступ к переменной осуществляется внутри внутреннего класса. Необходимо объявить окончательным

Итак, название говорит все. Я получаю ошибку компиляции внутри моего onClick .

Вот код.

 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); } 

Solutions Collecting From Web of "Доступ к переменной осуществляется внутри внутреннего класса. Необходимо объявить окончательным"

Если вы не хотите делать это окончательным, вы всегда можете просто сделать глобальную переменную.

Ошибка говорит обо всем, измените:

 ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager); 

в

 final ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager); 

Вы можете объявить переменную final или сделать ее переменной экземпляра (или глобальной). Если вы объявите его окончательным, вы не сможете его изменить позже.

Любая переменная, определенная в методе и доступная анонимным внутренним классом, должна быть окончательной. В противном случае вы можете использовать эту переменную во внутреннем классе, не подозревая, что если переменная изменяется во внутреннем классе и затем она используется позже в охватывающей области, изменения, внесенные во внутренний класс, не сохраняются в охватывающей области. В основном, то, что происходит во внутреннем классе, остается во внутреннем классе.

Я написал здесь более подробное объяснение . Он также объясняет, почему экземпляры и глобальные переменные не обязательно должны быть объявлены окончательными.

Как сказал @Veger, вы можете сделать его final чтобы переменная могла использоваться во внутреннем классе.

 final ViewPager pager = (ViewPager) findViewById(R.id.fieldspager); 

Я назвал его pager а не mPager потому что вы используете его как локальную переменную в методе onCreate . Префикс m зарезервирован для переменных класса (т.е. переменных, объявленных в начале класса и доступных для всех методов класса).

Если вам действительно нужна переменная-член класса, она не работает, чтобы сделать ее окончательной, потому что вы не можете использовать findViewById для установки ее значения до onCreate . Решение состоит в том, чтобы не использовать анонимный внутренний класс. Таким образом, переменная mPager не обязательно должна быть объявлена ​​окончательной и может использоваться во всем классе.

 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); } }; }