Android中结合抽屉导航与标签页活动时Java报错解决
com.dimas.adttest.MainHome is not an enclosing class报错问题 嘿,这个报错我之前整合抽屉和标签页功能时也碰到过,来给你捋清楚问题根源和解决办法:
问题到底出在哪?
你在MainActivity里写的new MainHome.SectionsPagerAdapter(...)之所以报错,核心原因是SectionsPagerAdapter是MainHome中的非静态内部类。非静态内部类的实例必须依附于外部类(也就是MainHome)的实例才能创建,而你现在并没有初始化MainHome对象,编译器自然会提示它不是一个可直接引用的封闭类。
两种可行的解决方案
方案1:把SectionsPagerAdapter移到MainActivity中(推荐,更符合你的整合需求)
既然你要把标签页功能整合到抽屉导航所在的MainActivity,直接把MainHome里的SectionsPagerAdapter完整代码迁移过来就好,这样代码结构更清晰,也避免了跨类引用的麻烦。
修改后的MainActivity代码示例:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private ViewPager mViewPager; private SectionsPagerAdapter mSectionsPagerAdapter; // 声明适配器 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); // 这里直接使用自己内部的SectionsPagerAdapter,无需再引用MainHome mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); mViewPager = (ViewPager) findViewById(R.id.container); mViewPager.setAdapter(mSectionsPagerAdapter); TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); tabLayout.setupWithViewPager(mViewPager); // 抽屉导航相关代码保持不变 DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); } // 从MainHome复制过来的SectionsPagerAdapter,作为MainActivity的内部类 public class SectionsPagerAdapter extends FragmentPagerAdapter { public SectionsPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { // 根据position返回对应标签页的Fragment,示例如下: switch (position) { case 0: return new Tab1Fragment(); case 1: return new Tab2Fragment(); default: return null; } } @Override public int getCount() { // 返回标签页的总数,比如2个 return 2; } @Override public CharSequence getPageTitle(int position) { // 返回每个标签页的标题 switch (position) { case 0: return "TAB 1"; case 1: return "TAB 2"; } return null; } } // 实现抽屉菜单的点击事件处理 @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { int id = item.getItemId(); if (id == R.id.nav_home) { // 处理首页菜单点击 } else if (id == R.id.nav_gallery) { // 处理相册菜单点击 } DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } }
方案2:将MainHome中的SectionsPagerAdapter改为静态内部类
如果你不想移动类的位置,也可以修改MainHome里的适配器,给它加上static修饰符,让它变成静态内部类,这样就不再依赖外部类实例:
public class MainHome extends AppCompatActivity { // ... 其他代码保持不变 ... // 加上static修饰符,转为静态内部类 public static class SectionsPagerAdapter extends FragmentPagerAdapter { public SectionsPagerAdapter(FragmentManager fm) { super(fm); } // ... 重写的getItem、getCount、getPageTitle方法保持不变 ... } }
修改后你在MainActivity里的new MainHome.SectionsPagerAdapter(getSupportFragmentManager())就能正常运行了。不过这种方式不如方案1直观,毕竟你已经在整合功能到MainActivity,跨类引用没必要保留。
额外注意点
确保你的activity_main.xml布局文件中包含了ViewPager(id为container)和TabLayout(id为tabs),否则会出现NullPointerException哦!
内容的提问来源于stack exchange,提问作者user9056633

