Android:使用导航抽屉从一个片段导航到另一个片段时出错 (java.lang.NullPointerException)

时间:2021-06-22 09:14:24

标签: java android android-studio

我是 Android 新手,我正在制作这个项目,其中包含 3 可通过导航抽屉访问的片段。我加了一个自动 图像滑块在第一个/开口处带有圆形图像指示器 fragment(HomeFragment.java) 但是当我尝试打开另一个片段时 应用程序不断崩溃并显示以下错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
        at android.view.ViewConfiguration.get(ViewConfiguration.java:481)
        at android.view.View.<init>(View.java:5046)
        at android.widget.ImageView.<init>(ImageView.java:179)
        at com.example.cogenx.fragments.HomeFragment.prepareDots(HomeFragment.java:105)
        at com.example.cogenx.fragments.HomeFragment.access$100(HomeFragment.java:34)
        at com.example.cogenx.fragments.HomeFragment$1.onPageSelected(HomeFragment.java:67)
        at androidx.viewpager.widget.ViewPager.dispatchOnPageSelected(ViewPager.java:1947)
        at androidx.viewpager.widget.ViewPager.scrollToItem(ViewPager.java:686)
        at androidx.viewpager.widget.ViewPager.setCurrentItemInternal(ViewPager.java:670)
        at androidx.viewpager.widget.ViewPager.setCurrentItemInternal(ViewPager.java:631)
        at androidx.viewpager.widget.ViewPager.setCurrentItem(ViewPager.java:623)
        at com.example.cogenx.fragments.HomeFragment$2.run(HomeFragment.java:86)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)`

HomeFragment.java

    Public class HomeFragment extends Fragment {
        private ViewPager viewPager;
        private CustomSwipeAdapter adapter;
        private Timer timer;
        private int current_position=0;
        private LinearLayout dotsLayout;
        private int custom_position=0;

    @Nullable
    @org.jetbrains.annotations.Nullable
    @Override

    public View onCreateView(@NonNull @org.jetbrains.annotations.NotNull LayoutInflater inflater, @Nullable @org.jetbrains.annotations.Nullable ViewGroup container, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_home, container, false);

        dotsLayout=v.findViewById(R.id.dotsContainer);
        viewPager=v.findViewById(R.id.view_pager);
        adapter=new CustomSwipeAdapter(getContext());
        viewPager.setAdapter(adapter);
        prepareDots(custom_position++);
        createSlide();

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                if (custom_position>4)
                    custom_position=0;
                prepareDots(custom_position++);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        return v;
    }

    private void createSlide(){
        final Handler handler=new Handler();
        final Runnable runnable=new Runnable() {
            @Override
            public void run() {
                if (current_position==Integer.MAX_VALUE)
                    current_position=0;
                viewPager.setCurrentItem(current_position++,true);
            }
        };
        timer=new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                handler.post(runnable);
            }
        },250,3000);
    }

    private void prepareDots(int currentSlidePosition){
        if (dotsLayout.getChildCount()>0)
            dotsLayout.removeAllViews();

        ImageView[] dots=new ImageView[5];

        for (int i=0;i<5;i++){
            dots[i]=new ImageView(getContext());
            if (i==currentSlidePosition)
                dots[i].setImageDrawable(ContextCompat.getDrawable(requireContext(),R.drawable.active_dot));
            else
                dots[i].setImageDrawable(ContextCompat.getDrawable(requireContext(),R.drawable.inactive_dot));

            LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams.setMargins(10,0,10,0);
            dotsLayout.addView(dots[i],layoutParams);
        }
    }

}

MainActivity.java

    public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
    private DrawerLayout drawer;

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

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar,
                R.string.navigation_draw_open, R.string.navigation_draw_close);

        drawer.addDrawerListener(toggle);
        toggle.syncState();

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                    new HomeFragment()).commit();
            navigationView.setCheckedItem(R.id.nav_home);
        }

    }

    @Override
    public boolean onNavigationItemSelected(@NonNull @NotNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.nav_home:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                        new HomeFragment()).commit();
                break;
            case R.id.nav_hospital:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                        new HospitalFragment()).commit();
                break;
            case R.id.nav_ngo:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                        new NGOFragment()).commit();
                break;
        }
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    @Override
    public void onBackPressed() {
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

}

我在 MainActivity.java 的“onNavigationItemSelected()”中放置了 break 语句,以便在我选择另一个片段时停止该过程,但它不起作用,请帮忙。

1 个答案:

答案 0 :(得分:-1)

不要使用requireContext()它会抛出异常

dots[i].setImageDrawable(ContextCompat.getDrawable(requireContext(),R.drawable.active_dot));

onCreateView()内获取上下文

context = view.getContext();

为定时器添加 getActivity()

Timer timer=new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            if(getActivity()!=null)
            handler.post(runnable);
        }
    },250,3000);

和 Surround prepareDots() 与 try catch 来处理崩溃。详情见日志

private void prepareDots(int currentSlidePosition){
try{
    if (dotsLayout.getChildCount()>0)
        dotsLayout.removeAllViews();

    ImageView[] dots=new ImageView[5];

    for (int i=0;i<5;i++){
        dots[i]=new ImageView(getContext());
        if (i==currentSlidePosition)
            dots[i].setImageDrawable(ContextCompat.getDrawable(context ,R.drawable.active_dot));
        else
            dots[i].setImageDrawable(ContextCompat.getDrawable(context ,R.drawable.inactive_dot));

        LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.setMargins(10,0,10,0);
        dotsLayout.addView(dots[i],layoutParams);
    }
}catch (Exception e) {
        Log.e("prepareDots", "Error: " + e.getMessage());
 }
 }