2015-11-15 1 views
0

J'ai commencé à traiter avec Fragments dans Android. J'ai créé Activity avec NavigationView qui a 3 objets et a travaillé avec 3 fragments simples jusqu'à présent. NavigationHeader a 2 boutons - 1 démarre LoginActivity et 2nd RegisterActivity. Je rappelle que tout jusqu'à ce que niw a bien fonctionné. Aujourd'hui, j'ai essayé de créer RecyclerView à l'intérieur d'un des fragments. Maintenant, lorsque j'essaie d'exécuter l'application, findViewById appliqué à ces 2 boutons NavigationHeader renvoie NULL. Je ne sais pas pourquoi.Travailler avec des fragments - findViewById renvoie NULL sur le bouton dans Android

Voici HomeActivity:

public class HomeActivity extends AppCompatActivity { 

    private static final String FRAGMENT_POSITION = "fragment_position"; // Fragment Position 

    private DrawerLayout mDrawerLayout;     // NavigationDrawer Layout 
    private NavigationView nvDrawer;     // NavigationView 
    private CoordinatorLayout homeCoordinatorLayout; // Coordinator Layout For Snackbar 
    private Toolbar toolbar;       // Application Toolbar 
    private TextView navHeaderNamePlusSurname;   // Name And Surname Navigation Header Text 
    private TextView navHeaderEmail;     // E-mail Navigation Header Text 
    AppCompatButton navHeaderButtonLogin;    // Login/Logout Button 
    AppCompatButton navHeaderButtonRegister;   // Register Button 
    private ActionBarDrawerToggle mDrawerToggle;  // ActionBar Drawer Toggle 
    private SQLiteHandler db;       // SQLite Database Helper Class 
    private SessionManager session;      // Session Manager 
    private int lastShownFragment; 

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

     // Setting Toolbar 
     toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
     getSupportActionBar().setDisplayShowHomeEnabled(true); 

     // Setting Up DrawerLayout 
     mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 
     mDrawerToggle = setupDrawerToggle(); 
     mDrawerLayout.setDrawerListener(mDrawerToggle); 

     // Navigation Header Logout Button 
     navHeaderButtonLogin = (AppCompatButton) findViewById(R.id.nav_header_btn_log_in_out); 
     navHeaderButtonRegister = (AppCompatButton) findViewById(R.id.nav_header_btn_register); 
     Log.d("czy_null", "navHeaderButtonLogin: " + navHeaderButtonLogin + ", navHeaderButtonRegister: " + navHeaderButtonRegister); 

     // Name, Surname And E-mail Texts 
     navHeaderNamePlusSurname = (TextView) findViewById(R.id.nav_header_name_plus_surname); 
     navHeaderEmail = (TextView) findViewById(R.id.nav_header_email); 

     // SQLite Database Handler 
     db = new SQLiteHandler(getApplicationContext()); 

     // Session Manager 
     session = new SessionManager(getApplicationContext()); 

     // Navigation Drawer 
     nvDrawer = (NavigationView) findViewById(R.id.navigation_view); 

     // Checking If User Is Logged In 
     if (!session.isLoggedIn()) { 
      hideNavigationViewGroup(nvDrawer); // Hiding NavigationView Group Depending 
               // If Not Logged 
     } else { 
      navHeaderButtonLogin.setText(getText(R.string.home_btn_log_out)); 
      navHeaderButtonRegister.setVisibility(View.INVISIBLE); 

      // Fetching User Details From SQLite 
      HashMap<String, String> user = db.getUserDetails(); 
      String name = user.get(SQLiteHandler.KEY_NAME); 
      String surname = user.get(SQLiteHandler.KEY_SURNAME); 
      String email = user.get(SQLiteHandler.KEY_EMAIL); 

      // Setting Navigation Header Texts 
      String nameSurname = name + " " + surname; 
      navHeaderNamePlusSurname.setText(nameSurname); 
      navHeaderEmail.setText(email); 
     } 

     // Setting Up CoordinatorLayout 
     homeCoordinatorLayout = (CoordinatorLayout) findViewById(R.id.home_coordinator_layout); 

     // Setting Listener To NavigationView 
     setupDrawerContent(nvDrawer); 

     // Setting Starting Fragment 
     if (savedInstanceState == null) { 
      setStartingFragment(); 
     } else { 
      restoreOnInstanceState(savedInstanceState.getInt(FRAGMENT_POSITION)); 
     } 

     // Applying Login/Logout Button Listener 
     setLoginButtonListener(); 

     // Applying Register Button Listener 
     setRegisterButtonListener(); 
    } 

    // Listener To Login/Register Button 
    private void setLoginButtonListener() { 
     navHeaderButtonLogin.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       if (!session.isLoggedIn()) { 
        mDrawerLayout.closeDrawers(); 
        Intent intent = new Intent(getApplicationContext(), LoginActivity.class); 
        startActivity(intent); 
       } else { 
        mDrawerLayout.closeDrawers(); 
        logoutUser(); 
        navHeaderNamePlusSurname.setText(getString(R.string.nav_header_name_surname)); 
        navHeaderEmail.setText(getString(R.string.nav_header_email)); 
        hideNavigationViewGroup(nvDrawer); 
        navHeaderButtonLogin.setText(getString(R.string.home_btn_log_in)); 
        navHeaderButtonRegister.setVisibility(View.VISIBLE); 
        showSnackbarInfo(getString(R.string.inf_logout_success), 
          R.color.snackbar_success_msg); 
       } 
      } 

     }); 
    } 

    // Listener To Register Button 
    private void setRegisterButtonListener() { 
     navHeaderButtonRegister.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       mDrawerLayout.closeDrawers(); 
       Intent intent = new Intent(getApplicationContext(), SignUpActivity.class); 
       startActivity(intent); 
      } 

     }); 
    } 

    // Logging Out The User 
    private void logoutUser() { 
     session.setLogin(false); 
     db.deleteUsers(); 
    } 

    // Setting Up DrawerToggle 
    private ActionBarDrawerToggle setupDrawerToggle() { 
     return new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.drawer_open, 
       R.string.drawer_close); 
    } 

    // Setting Up Drawer Content 
    private void setupDrawerContent(NavigationView navigationView) { 
     navigationView.setNavigationItemSelectedListener(
       new NavigationView.OnNavigationItemSelectedListener() { 

        @Override 
        public boolean onNavigationItemSelected(MenuItem menuItem) { 
         selectDrawerItem(menuItem); 

         return true; 
        } 

       }); 
    } 

    // Replace Existing Fragment With a New One 
    public void selectDrawerItem(MenuItem menuItem) { 
     Fragment fragment = null; 
     Class fragmentClass = null; 

     switch(menuItem.getItemId()) { 
      case R.id.nav_top20_recipes: { 
       fragmentClass = Top20RecipesFragment.class; 
       lastShownFragment = 0; 
       break; 
      } 

      case R.id.nav_kitchen_type: { 
       fragmentClass = KitchenTypeFragment.class; 
       lastShownFragment = 1; 
       break; 
      } 
      case R.id.nav_meal_type: { 
       fragmentClass = MealTypeFragment.class; 
       lastShownFragment = 2; 
       break; 
      } 
     } 

     try { 
      fragment = (Fragment) fragmentClass.newInstance(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.frame_layout_content, fragment); 
     fragmentTransaction.commit(); 

     menuItem.setChecked(true);  // Highlight The Selected Item 
     setTitle(menuItem.getTitle()); // Updating Toolbar Title 
     mDrawerLayout.closeDrawers(); // Close The Drawer 
    } 

    // Function Setting First Fragment 
    private void setStartingFragment() { 
     Fragment fragment = null; 
     Class fragmentClass = Top20RecipesFragment.class; 

     try { 
      fragment = (Fragment) fragmentClass.newInstance(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.frame_layout_content, fragment); 
     fragmentTransaction.commit(); 

     lastShownFragment = 0; 
     MenuItem menuItem = nvDrawer.getMenu().getItem(0); 
     menuItem.setChecked(true);  // Highlight The Selected Item 
     setTitle(menuItem.getTitle()); // Updating Toolbar Title 
    } 

    // Saving Fragment Title State 
    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 

     outState.putInt(FRAGMENT_POSITION, lastShownFragment); 
    } 

    // Restoring Fragment Title States 
    @Override 
    protected void onRestoreInstanceState(Bundle savedInstanceState) { 
     super.onRestoreInstanceState(savedInstanceState); 

     restoreOnInstanceState(savedInstanceState.getInt(FRAGMENT_POSITION)); 
    } 

    // Restoring Selected Item On Screen Rotation Or App Minimalize 
    private void restoreOnInstanceState(int lastPosition) { 

     Fragment fragment = null; 
     Class fragmentClass = null; 

     switch (lastShownFragment) { 
      case 0: { 
       fragmentClass = Top20RecipesFragment.class; 
       break; 
      } 

      case 1: { 
       fragmentClass = KitchenTypeFragment.class; 
       break; 
      } 

      case 2: { 
       fragmentClass = MealTypeFragment.class; 
       break; 
      } 
     } 

     try { 
      fragment = (Fragment) fragmentClass.newInstance(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.frame_layout_content, fragment); 
     fragmentTransaction.commit(); 

     lastShownFragment = lastPosition; 
     MenuItem menuItem = nvDrawer.getMenu().getItem(lastPosition); 
     menuItem.setChecked(true);  // Highlight The Selected Item 
     setTitle(menuItem.getTitle()); 
    } 

    @Override 
    protected void onPostCreate(Bundle savedInstanceState) { 
     super.onPostCreate(savedInstanceState); 

     mDrawerToggle.syncState(); 
    } 

    @Override 
    public void onConfigurationChanged(Configuration newConfig) { 
     super.onConfigurationChanged(newConfig); 

     mDrawerToggle.onConfigurationChanged(newConfig); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.menu_main, menu); 

     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     if (mDrawerToggle.onOptionsItemSelected(item)) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    // Function Hiding Items In NavigationView 
    private void hideNavigationViewGroup(NavigationView nvDrawer) { 
     nvDrawer.getMenu().setGroupVisible(R.id.nav_group_logged_user, false); 
    } 

    // Function Showing Snakcbar 
    private void showSnackbarInfo(String info, int textColor) { 
     Snackbar snackbar = Snackbar.make(homeCoordinatorLayout, info, Snackbar.LENGTH_LONG); 

     View sbView = snackbar.getView(); 

     TextView sbText = (TextView) sbView.findViewById(android.support.design.R.id.snackbar_text); 
     sbText.setTextColor(ContextCompat.getColor(getApplicationContext(), textColor)); 

     snackbar.show(); 
    } 
} 

Voici mon fragment qui doit contenir RacyclerView:

public class KitchenTypeFragment extends Fragment { 

    RecyclerView kitchenTypeRecycleView; 
    private ArrayList<KitchenTypeItem> kitchenTypeItems; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     kitchenTypeItems = new ArrayList<>(); 
     fillKitchenTypeArray(kitchenTypeItems); 
    } 

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

     return rootView; 
    } 

    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState) { 
     kitchenTypeRecycleView = (RecyclerView) view.findViewById(R.id.kitchen_type_recycle_view); 

     kitchenTypeRecycleView.setHasFixedSize(true); 
     kitchenTypeRecycleView.setAdapter(new KitchenTypeAdapter(kitchenTypeItems, 
       R.layout.kitchen_type_grid_item)); 
     kitchenTypeRecycleView.setLayoutManager(new GridLayoutManager(getContext(), 2)); 
     kitchenTypeRecycleView.setItemAnimator(new DefaultItemAnimator()); 
    } 

    private void fillKitchenTypeArray(ArrayList<KitchenTypeItem> kitchenTypeItems) { 
     KitchenTypeItem kitchenItem; 

     // Currently 8 Kitchen Types 
     String[] itemNames = getResources().getStringArray(R.array.kitchen_types); 

     // Filling ArrayList 
     for(int i = 0; i < itemNames.length; i++) { 
      kitchenItem = new KitchenTypeItem(itemNames[i], R.drawable.example_kitchen_type); 
      kitchenTypeItems.add(kitchenItem); 
     } 
    } 
} 

Voici XML de HomeActivity:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/home_coordinator_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context=".RegisterActivity"> 

    <android.support.v4.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:context=".SignUpActivity"> 

     <!-- This LinearLayout represents the contents of the screen --> 
     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical"> 

      <!-- The ActionBar displayed at the top --> 
      <include 
       android:id="@+id/toolbar" 
       layout="@layout/tool_bar" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" /> 

      <!-- The main content view where fragments are loaded --> 
      <FrameLayout 
       android:id="@+id/frame_layout_content" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" /> 
     </LinearLayout> 

     <!-- The navigation drawer that comes from the left --> 
     <!-- Note that `android:layout_gravity` needs to be set to 'start' --> 
     <android.support.design.widget.NavigationView 
      android:id="@+id/navigation_view" 
      android:layout_width="wrap_content" 
      android:layout_height="match_parent" 
      android:layout_gravity="start" 
      app:menu="@menu/drawer_view" 
      app:headerLayout="@layout/nav_header" /> 

    </android.support.v4.widget.DrawerLayout> 

</android.support.design.widget.CoordinatorLayout> 

Voici XML NavigationHeader avec ces 2 boutons:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    android:id="@+id/relative_nav_header" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="192dp" 
    android:background="@color/primary" 
    android:paddingLeft="16dp" 
    android:paddingRight="16dp" 
    android:paddingBottom="16dp" 
    android:paddingTop="40dp" 
    android:theme="@style/ThemeOverlay.AppCompat.Dark" 
    android:orientation="vertical"> 


     <!-- Name + Surname, E-mail --> 
     <LinearLayout 
      android:id="@+id/nav_lin_layout" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center|left" 
      android:orientation="vertical"> 

      <!-- Name + Surname Text --> 
      <TextView 
       android:id="@+id/nav_header_name_plus_surname" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:fontFamily="sans-serif-medium" 
       android:textSize="17sp" 
       android:text="@string/nav_header_name_surname" /> 

      <!-- E-mail Adress --> 
      <TextView 
       android:id="@+id/nav_header_email" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:textColor="@color/accent" 
       android:fontFamily="sans-serif" 
       android:textSize="13sp" 
       android:text="@string/nav_header_email" /> 

     </LinearLayout> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" 
     android:layout_marginTop="7dp" 
     android:gravity="center|left" 
     android:layout_below="@+id/nav_lin_layout"> 

     <!-- Login/Logut Button --> 
     <android.support.v7.widget.AppCompatButton 
      android:id="@+id/nav_header_btn_log_in_out" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:padding="12dp" 
      android:backgroundTint="@color/nav_header_login_color" 
      android:textColor="@color/text_icons" 
      android:stateListAnimator="@null" 
      android:text="@string/btn_log_in" /> 

     <android.support.v7.widget.AppCompatButton 
      android:id="@+id/nav_header_btn_register" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:padding="12dp" 
      android:backgroundTint="@color/nav_header_register_color" 
      android:stateListAnimator="@null" 
      android:textColor="@color/text_icons" 
      android:text="@string/btn_sign_up" /> 

    </LinearLayout> 

</RelativeLayout> 

Et voici enfin XML de Fragment:

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/kitchen_type_fragment" 
    android:padding="16dp" 
    tools:context="com.example.nazwamarki.myapplication.fragments.KitchenTypeFragment"> 

     <android.support.v7.widget.RecyclerView 
      android:id="@+id/kitchen_type_recycle_view" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" /> 

</FrameLayout> 
+0

Si je commente ces lignes: setLoginButtonListener() et setRegisterButtonListener() tout fonctionne bien. – anton86993

Répondre

1

Vous devez utiliser findViewById sur la headerView comme ceci:

navigationView.getHeaderView (0) .findViewById()

+0

Le problème était dans la nouvelle bibliothèque google. Dernière mise à jour foiré sth up. En utilisant la version précédente, la bibliothèque a résolu ce problème. – anton86993