java - 通过 ImageView onClick 打开在 HomeFragment 的 MainActivity 中创建的 DrawerLayout 并避免 NPE

标签 java android fragment navigation-drawer

我正在尝试通过单击图标打开我在 HomeFragment 的 MainActivity 中创建的 NavigationDrawer。当我单击图标时,我希望抽屉打开...即使我将它放在我的 MainActivity 文件中而不是我的 HomeFragment 中,这可以完成吗?

下面是我的fragment_home.xml 文件和HomeFragment.java


MainActivity.java

    package com.e.events;

    import androidx.annotation.NonNull;
    import androidx.appcompat.app.ActionBarDrawerToggle;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.appcompat.widget.Toolbar;
    import androidx.core.view.GravityCompat;
    import androidx.drawerlayout.widget.DrawerLayout;
    import androidx.fragment.app.Fragment;

    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.view.MenuItem;

    import com.e.events.Fragment.HomeFragment;
    import com.e.events.Fragment.NotificationsFragment;
    import com.e.events.Fragment.ProfileFragment;
    import com.e.events.Fragment.SaveFragment;
    import com.e.events.Fragment.SearchFragment;
    import com.google.android.material.bottomnavigation.BottomNavigationView;
    import com.google.android.material.navigation.NavigationView;
    import com.google.firebase.auth.FirebaseAuth;

    public class MainActivity extends AppCompatActivity implements DrawerLocker, NavigationView.OnNavigationItemSelectedListener {

        private DrawerLayout drawer;

        BottomNavigationView bottomNavigationView;
        Fragment selectedFragment = null;

        @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_drawer_open, R.string.navigation_drawer_close);
            drawer.addDrawerListener(toggle);
            toggle.syncState();

            bottomNavigationView = findViewById(R.id.bottom_navigation);

            bottomNavigationView.setOnNavigationItemSelectedListener(navigationItemSelectedListener);

            Bundle intent = getIntent().getExtras();
            if (intent != null) {
                String publisher = intent.getString("publisherid");

                SharedPreferences.Editor editor = getSharedPreferences("PREFS", MODE_PRIVATE).edit();
                editor.putString("profileid", publisher);
                editor.apply();

                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                        new ProfileFragment()).commit();
            } else {
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                        new HomeFragment()).commit();
            }
        }

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

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
            int id = menuItem.getItemId();
            switch (id) {
                case R.id.nav_edit_profile:
                    Intent editProfile = new Intent(MainActivity.this, EditProfileActivity.class);
                    startActivity(editProfile);
                    break;
                case R.id.nav_settings:
                    Intent settings = new Intent(MainActivity.this, SettingsActivity.class);
                    startActivity(settings);
                    break;
                case R.id.nav_logout:
                    Intent logout = new Intent(MainActivity.this, StartActivity.class);
                    FirebaseAuth.getInstance().signOut();
                    startActivity(new Intent(MainActivity.this, StartActivity.class)
                            .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
                    break;
            }

            drawer.closeDrawer(GravityCompat.START);
            return true;
        }

        @Override
        public boolean onOptionsItemSelected(@NonNull MenuItem item) {
            int id = item.getItemId();
            if (id == R.id.nav_edit_profile) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }

        private BottomNavigationView.OnNavigationItemSelectedListener navigationItemSelectedListener =
                new BottomNavigationView.OnNavigationItemSelectedListener() {
                    @Override
                    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {

                        switch (menuItem.getItemId()) {
                            case R.id.nav_home:
                                selectedFragment = new HomeFragment();
                                break;
                            case R.id.nav_search:
                                selectedFragment = new SearchFragment();
                                break;
                            case R.id.nav_notifications:
                                selectedFragment = new NotificationsFragment();
                                break;
                            case R.id.nav_profile:
                                SharedPreferences.Editor editor = getSharedPreferences("PREFS", MODE_PRIVATE).edit();
                                editor.putString("profileid", FirebaseAuth.getInstance().getCurrentUser().getUid());
                                editor.apply();
                                selectedFragment = new ProfileFragment();
                                break;
                            case R.id.nav_save:
                                selectedFragment = new SaveFragment();
                                break;
                        }

                        if (selectedFragment != null) {
                            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
                                    selectedFragment).commit();
                        }

                        return true;
                    }
                };
        public void setDrawerLocked(boolean enabled){
            if(enabled){
                drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
            }else{
                drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
            }

        }
    }



fragment_home.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".Fragment.HomeFragment">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:attr/windowBackground">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar_home_fragment"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?android:attr/windowBackground"
                android:elevation="4dp"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:id="@+id/events_logo_main_activity"
                        android:layout_width="180dp"
                        android:layout_height="45dp"
                        android:layout_centerInParent="true"
                        android:layout_marginTop="10dp"
                        android:src="@drawable/events_logo_black_max_size" />

                    <ImageView
                        android:id="@+id/camera_create_an_event_main_activity"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentEnd="true"
                        android:layout_centerInParent="true"
                        android:layout_marginEnd="11dp"
                        android:src="@drawable/ic_camera_create_events_home_fragment_black" />

                    <ImageView
                        android:id="@+id/three_bars_settings_main_activity"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentStart="true"
                        android:layout_centerInParent="true"
                        android:src="@drawable/ic_three_bars_settings_home_fragment_black" />

                </RelativeLayout>

            </androidx.appcompat.widget.Toolbar>

        </com.google.android.material.appbar.AppBarLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/bar">

        </androidx.recyclerview.widget.RecyclerView>

    </LinearLayout>

    <ProgressBar
        android:id="@+id/progress_circular"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

HomeFragment

    package com.e.events.Fragment;

    import android.content.Context;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;

    import androidx.annotation.NonNull;
    import androidx.appcompat.app.ActionBarDrawerToggle;
    import androidx.appcompat.widget.Toolbar;
    import androidx.core.view.GravityCompat;
    import androidx.drawerlayout.widget.DrawerLayout;
    import androidx.fragment.app.Fragment;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;

    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.EditText;
    import android.widget.ImageView;
    import android.widget.ProgressBar;
    import android.widget.TextView;

    import com.e.events.Adapter.PostAdapter;
    import com.e.events.EditProfileActivity;
    import com.e.events.MainActivity;
    import com.e.events.Model.Post;
    import com.e.events.OptionsActivity;
    import com.e.events.PostActivity;
    import com.e.events.R;
    import com.google.android.material.navigation.NavigationView;
    import com.google.firebase.auth.FirebaseAuth;
    import com.google.firebase.database.DataSnapshot;
    import com.google.firebase.database.DatabaseError;
    import com.google.firebase.database.DatabaseReference;
    import com.google.firebase.database.FirebaseDatabase;
    import com.google.firebase.database.ValueEventListener;

    import java.util.ArrayList;
    import java.util.List;

    public class HomeFragment extends Fragment {

        ImageView options;
        DrawerLayout drawer;

        ProgressBar progressBar;

        private RecyclerView recyclerView;
        private PostAdapter postAdapter;
        private List<Post> postLists;

        private ImageView camera_create_event;

        private List<String> followingList;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_home, container, false);

            recyclerView = view.findViewById(R.id.recycler_view);
            recyclerView.setHasFixedSize(true);
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
            linearLayoutManager.setReverseLayout(true);
            linearLayoutManager.setStackFromEnd(true);
            recyclerView.setLayoutManager(linearLayoutManager);
            postLists = new ArrayList<>();
            postAdapter = new PostAdapter(getContext(), postLists);
            recyclerView.setAdapter(postAdapter);

            progressBar = view.findViewById(R.id.progress_circular);

            drawer = view.findViewById(R.id.nav_view);

            Toolbar toolbar = view.findViewById(R.id.toolbar_home_fragment);
            options = view.findViewById(R.id.three_bars_settings_main_activity);

            options.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    drawer.openDrawer(GravityCompat.START);
                }
            });

            camera_create_event = view.findViewById(R.id.camera_create_an_event_main_activity);

            camera_create_event.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(getActivity(), PostActivity.class);
                    startActivity(intent);
                }
            });

            checkFollowing();

            return view;
        }

        private void checkFollowing() {
            followingList = new ArrayList<>();

            DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Follow")
                    .child(FirebaseAuth.getInstance().getCurrentUser().getUid())
                    .child("following");

            reference.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    followingList.clear();
                    for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                        followingList.add(snapshot.getKey());
                    }

                    readPosts();
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });
        }

        private void readPosts() {
            DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");

            reference.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    postLists.clear();
                    for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                        Post post = snapshot.getValue(Post.class);
                        for (String id : followingList) {
                            if (post.getPublisher().equals(id)) {
                                postLists.add(post);
                            }
                        }
                    }

                    postAdapter.notifyDataSetChanged();
                    progressBar.setVisibility(View.GONE);
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });
        }
    }

日志猫

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.e.events, PID: 18229
    java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.drawerlayout.widget.DrawerLayout.openDrawer(int)' on a null object reference
        at com.e.events.Fragment.HomeFragment$1.onClick(HomeFragment.java:85)
        at android.view.View.performClick(View.java:6663)
        at android.view.View.performClickInternal(View.java:6635)
        at android.view.View.access$3100(View.java:794)
        at android.view.View$PerformClick.run(View.java:26199)
        at android.os.Handler.handleCallback(Handler.java:907)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:216)
        at android.app.ActivityThread.main(ActivityThread.java:7625)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

最佳答案

您的 fragment_home.xml 中没有任何 DrawerLayout,请尝试将 RelativeLayout 更改为 DrawerLayout :

 <?xml version="1.0" encoding="utf-8"?>
    <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:openDrawer="start"
        tools:context=".Fragment.HomeFragment">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <com.google.android.material.appbar.AppBarLayout
                android:id="@+id/bar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?android:attr/windowBackground">

                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/toolbar_home_fragment"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="?android:attr/windowBackground"
                    android:elevation="4dp"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

                    <RelativeLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content">

                        <ImageView
                            android:id="@+id/events_logo_main_activity"
                            android:layout_width="180dp"
                            android:layout_height="45dp"
                            android:layout_centerInParent="true"
                            android:layout_marginTop="10dp"
                            android:src="@drawable/events_logo_black_max_size" />

                        <ImageView
                            android:id="@+id/camera_create_an_event_main_activity"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_alignParentEnd="true"
                            android:layout_centerInParent="true"
                            android:layout_marginEnd="11dp"
                            android:src="@drawable/ic_camera_create_events_home_fragment_black" />

                        <ImageView
                            android:id="@+id/three_bars_settings_main_activity"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_alignParentStart="true"
                            android:layout_centerInParent="true"
                            android:src="@drawable/ic_three_bars_settings_home_fragment_black" />

                    </RelativeLayout>

                </androidx.appcompat.widget.Toolbar>

            </com.google.android.material.appbar.AppBarLayout>

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/bar">

            </androidx.recyclerview.widget.RecyclerView>

        </LinearLayout>

        <ProgressBar
            android:id="@+id/progress_circular"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true" />

    </androidx.drawerlayout.widget.DrawerLayout>

关于java - 通过 ImageView onClick 打开在 HomeFragment 的 MainActivity 中创建的 DrawerLayout 并避免 NPE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59007662/

相关文章:

java - Android获取GPS数据时能否将GPS数据写入CSV文件?

Android 将按钮添加到 Fragment

android - 从其他 fragment 更改 fragment ,如导航链接

java - 如何维护 session 范围的pojo类中的数据 spring mvc 3.0.3

java - 如何使用displaytag过滤数据?

java - 如何处理 AWT 框架中的关闭按钮

java - 需要对 Java 线程 : start() and run() 进行一些说明

java - 在 Android 外部存储上创建的文件夹通过 MTP 不可见,但显示在 adb shell 中

android - fragment popbackstack 行为在 25.1.0 和 25.1.1 中被破坏

java - fragment - 错误膨胀