我已经开始在Android中处理Fragments了。我用NavigationView创建了Activity,它有3个项目并且使用3个简单的片段直到现在。 NavigationHeader有2个按钮 - 1个启动LoginActivity和2nd RegisterActivity。我提醒一切,直到niw工作正常。今天我尝试在其中一个片段中创建RecyclerView。现在,当我尝试运行app时,应用于这两个NavigationHeader按钮的findViewById返回NULL。我不明白为什么。
这是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();
}
}
这是我的片段,必须包含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);
}
}
}
以下是来自HomeActivity的XML:
<?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>
这是带有这两个按钮的NavigationHeader XML:
<?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>
最后这是片段中的XML:
<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 :(得分:1)
您应该在headerView上使用findViewById,如下所示:
navigationView.getHeaderView(0).findViewById()