Navigation drawer header textview nullpointerexception - java

I have an 2 activity and a service, in first I have navigation drawer, and 2 textviews in its header, and I must change their text sometimes, in service there is some data that i need
On first run everything is perfect, but when I go to the first activity from second, I have nullpointerexception in textviews. What causes it, and how to fix?
//First
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Navigation drawer init
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbarMain);
setSupportActionBar(toolbar);
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_main);
navigationView.setNavigationItemSelectedListener(this);
intent = new Intent("playbackservice");
sConn = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder binder) {
Log.d(LOG_TAG, "MainActivity onServiceConnected");
service = ((PlaybackService.PlaybackServiceBinder) binder).getService();
bound = true;
prepareLayout();
}
public void onServiceDisconnected(ComponentName name) {
Log.d(LOG_TAG, "MainActivity onServiceDisconnected");
bound = false;
}
};
}
private void prepareLayout() {
Log.d(LOG_TAG, "prepareLayout: Running");
((TextView) findViewById(R.id.songNameNavhead)).setText(currentSong.getName());
((TextView) findViewById(R.id.artistNavhead)).setText(currentSong.getArtist());
}
And
//Layout nav_header_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="#dimen/nav_header_height"
android:gravity="bottom"
android:orientation="vertical"
android:background="#color/colorPrimaryDark"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/default_song_name"
android:id="#+id/songNameNavhead"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/default_artist"
android:id="#+id/artistNavhead"/>
</LinearLayout>
And
//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view_main"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
Error
05-12 19:34:05.001 11086-11086/iskandarovlev.myitschool.ru.lyricplayer E/AndroidRuntime: FATAL EXCEPTION: main
Process: iskandarovlev.myitschool.ru.lyricplayer, PID: 11086
java.lang.NullPointerException
//MainActivity.java:302 is
//((TextView) header.findViewById(R.id.songNameNavhead)).setText(currentSong.getName());
//this line
at iskandarovlev.myitschool.ru.lyricplayer.MainActivity.prepareLayout(MainActivity.java:302)
at iskandarovlev.myitschool.ru.lyricplayer.MainActivity.access$700(MainActivity.java:48)
at iskandarovlev.myitschool.ru.lyricplayer.MainActivity$3.onServiceConnected(MainActivity.java:355)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1140)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1157)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5542)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:657)
at dalvik.system.NativeStart.main(Native Method)

To successfuly find any widget in Navigation Drawer's header, you need to obtain header view first. This can be achieved by using getHeaderView() method:
View header = ((NavigationView)findViewById(R.id.navigation_view)).getHeaderView(0);
Then, having header pointing to the right ViewGroup with our widgets in it, you can use findViewById() as usual:
TextView tv = header.findViewById(R.id.songNameNavhead);
tv.setText(currentSong.getName());
Or in more compact manner:
((TextView)header.findViewById(R.id.songNameNavhead))
.setText(currentSong.getName());

private void prepareLayout() {
Log.d(LOG_TAG, "prepareLayout: Running");
((TextView) findViewById(R.id.songNameNavhead)).setText(currentSong.getName());
((TextView) findViewById(R.id.artistNavhead)).setText(currentSong.getArtist());
}
These need to use the navigationDrawer's view and then it's header, not your activity's view, so it should be
View header = navigationView.getHeaderView(0)
((TextView) navigationViewHeader.findViewById(R.id.songNameNavhead)).setText(currentSong.getName());
((TextView) navigationViewHeader.findViewById(R.id.artistNavhead)).setText(currentSong.getArtist());

Related

Toolbar menu being cleared after being set (When activity is started)

Toolbar menu is inflated in fragment but then cleared later.
When activity is first created (or rotated) the toolbar menu is inflated properly in the fragment, but then gets cleared before it can be displayed.
I set the toolbar menu in my fragment's onActivityCreated, and it stays set through onResume in the activity. The next call I've found is in onCreateOptionsMenu in the activity, but at this point toolbar.getMenu().size() = 0
Somewhere between onResume and onCreateOptionsMenu the toolbar menu is getting reset.
Edit:
I'm not sure what is necessary to reproduce it, but here is all(?) of the relevant code.
Activity:
private Toolbar toolbar;
private DrawerLayout drawer;
private ActionBarDrawerToggle toggle;
private FloatingActionButton fab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawer_main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fab = findViewById(R.id.main_fab);
drawer = findViewById(R.id.drawer_layout);
toggle = new ActionBarDrawerToggle(this, drawer,toolbar,R.string.nav_drawer_open,R.string.nav_drawer_close);
drawer.addDrawerListener(toggle);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
if (savedInstanceState == null) {
showFragment(ScheduleFragment.newInstance());
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(toggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
CharSequence retainTitle = toolbar.getTitle();
super.onPostCreate(savedInstanceState);
toggle.syncState();
toolbar.setTitle(retainTitle);
}
Fragment:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
toolbar = ((MainActivity)getActivity()).getToolbar();
setMenuAction(MENU_ACTION_DELETE);
}
protected void setMenuAction(int menuAction) {
Log.d(logger, "setting the menu");
switch(menuAction) {
case MENU_ACTION_DELETE:
toolbar.getMenu().clear();
toolbar.inflateMenu(R.menu.menu_delete);
break;
case MENU_ACTION_NONE:
Log.d(logger, "clearing menu");
toolbar.getMenu().clear();
break;
}
}
Layouts:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout">
<include
layout="#layout/activity_main"/>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/nav_header"
app:menu="#menu/menu_nav" />
</android.support.v4.widget.DrawerLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|snap|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/main_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:src="#drawable/ic_baseline_add_24px"
android:layout_margin="16dp" />
<include layout="#layout/content_main"/>
</android.support.design.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/activity_main">
<FrameLayout
android:id="#+id/fragmentHolder"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
The problem in my current code as posted was the line setSupportActionBar(toolbar);
This was not needed, and was in fact causing the troubling lifecycle problems stated above.

Using data binding inside of a Drawer Layout, where the drawer holds a fragment

I have a Navigation Drawer Activity, however, I'm using a Fragment inside of the drawer. I can't get both data binding and the fragment working together. With the example code the data binding doesn't work. If I change binding = ContentNewSessionBinding.inflate(getLayoutInflater()) to binding = DataBindingUtil.setContentView(this, R.layout.content_new_session_); I get an error that a view cannot be found the fragment.
activity_new_session.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
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.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_new_session_"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<FrameLayout
android:id="#+id/new_session_draw_frame"
android:name="uk.co.alexanderjs.catchtrack2.SpeciesManager_Fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
</layout>
content_new_session.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="WeatherModel"
type="uk.co.alexanderjs.models.WeatherModel"/>
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/CL_content_new_session"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".NewSession_Activity"
tools:showIn="#layout/app_bar_new_session_">
<android.support.constraint.ConstraintLayout
android:id="#+id/CL_info_tray"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.v7.widget.AppCompatImageView
android:id="#+id/IV_location_type_info_tray"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginEnd="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/IV_watch_info_tray"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_cell_tower" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
NewSession_Activity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_session)
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final DrawerLayout drawer = 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();
toggle.setDrawerIndicatorEnabled(false);
Class fragmentClass = SpeciesManager_Fragment.class;
Fragment fragment = null;
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e ) {
e.printStackTrace();
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.new_session_draw_frame, fragment);
fragmentTransaction.commit();
}
ContentNewSessionBinding binding = ContentNewSessionBinding.inflate(getLayoutInflater());
binding.setWeatherModel(MainActivity.weatherModel);
}
You should try to move that FrameLayout in your activity_new_session.xml outside the NavigationView, between the toolbar layout and the NavigationView is the place for the fragment container and then you can add to your NavigationView:
app:headerLayout="YourHeaderLayout"
in case you want to have a header in your DrawerLayout
app:menu="YourMenuXml"
where you have the items that will show on your DrawerLayout

Not able to view the navigation bar in Android app despite including the necessary syntaxes

I tried to include the navigation bar in an existing app. but the contens of the activity is also not shown on inclusion
this is my code --
<?xml version="1.0" encoding="utf-8"?>
<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:layout_gravity="start"
android:fitsSystemWindows="true"
tools:context=".common.components.main.HomeActivity"
tools:openDrawer="start">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<include layout="#layout/nav_toolbar" />
<include layout="#layout/activity_home_contents" />
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:itemTextAppearance="#style/TextAppearance.AppCompat.Body1"
app:itemTextColor="#FFFFFF"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
This is the contents of my nav_toolbar layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/toolbar1"
android:background="#color/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
>
</android.support.v7.widget.Toolbar>
Similarly I have activity_home_contents in scroll view as
<ScrollView 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:fillViewport="true"
android:background="#color/white"
android:scrollbars="none"
>
<RelativeLayout android:orientation="vertical"
android:id="#+id/home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="30dp"
tools:context=".common.components.main.HomeActivity">
......
And code snipplet from HomeActivity.java is
.....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
floodEvacApplication = (FloodEvacApplication)
getApplicationContext();
lastAddress = floodEvacApplication.getLatestAddress();
if (lastAddress == null) {
initGoogleAPI();
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar1);
setSupportActionBar(toolbar);
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();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
NavigationView navigationView = (NavigationView)
findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
......
I tried various ways avaliable online and searched online but couldn't able to display the activity_home_contents also but if I remove the navigation drawer and display the activiy_home then I am able to display it.
Try to add the following line under android.support.design.widget.NavigationView in Drawer's XML:
android:layout_gravity="start"

Failed to resolve attribute at index 60

I have imported the scanner control module in my app. I have also added the module dependency correctly. I can even access the classes of imported module. But the problem is, whenever I try to open that module (I have added that as in main app navigation drawer item) it looks like there is a problem with setContentView(R.layout.activity_active_scanner). I think that the main problem is in tablayout(or else in other xml parts).
The logcat is shown below:
Caused by: java.lang.RuntimeException: Failed to resolve attribute at index 60
at android.content.res.TypedArray.getColor(TypedArray.java:401)
at android.support.design.widget.TabLayout.<init>(TabLayout.java:348)
at android.support.design.widget.TabLayout.<init>(TabLayout.java:290)
at java.lang.reflect.Constructor.newInstance(Native Method) 
at java.lang.reflect.Constructor.newInstance(Constructor.java:288) 
at android.view.LayoutInflater.createView(LayoutInflater.java:607) 
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809) 
at android.view.LayoutInflater.parseInclude(LayoutInflater.java:916) 
at android.view.LayoutInflater.rInflate(LayoutInflater.java:802) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:504) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:414) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:365) 
at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:284) 
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:143) 
at ****com.zebra.scannercontrol.app.activities.ActiveScannerActivity.onCreate(ActiveScannerActivity.java:79)**** 
at android.app.Activity.performCreate(Activity.java:6092)
and the code for activity_active_scanner is:
<?xml version="1.0" encoding="utf-8"?>
<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:openDrawer="start">
<include
layout="#layout/app_bar_activescanner"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_home"
app:menu="#menu/activity_home_drawer" />
</android.support.v4.widget.DrawerLayout>
and below is the app_bar_active_scanner which I have included in activity_active_scanner:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.zebra.scannercontrol.app.activities.ActiveScannerActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<android.support.design.widget.TabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="#integer/abc_max_action_buttons"
app:tabBackground="#color/blue"
app:tabGravity="fill"
app:tabIndicatorColor="#color/yellow"
app:tabMaxWidth="0dp"
app:tabMode="fixed"
app:tabTextAppearance="#style/AppTabTextAppearance"/>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_activescanner" />
</android.support.design.widget.CoordinatorLayout>
and given below is the ActiveScannerActivity in which, I have declared/initialized and set the tablayout with view pager. You can ignore other codes (I think main problem is with tablayout).
public class ActiveScannerActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener,
ActionBar.TabListener,ScannerAppEngine.IScannerAppEngineDevEventsDelegate,ScannerAppEngine.IScannerAppEngineDevConnectionsDelegate{
private ViewPager viewPager;
ActiveScannerAdapter mAdapter;
TabLayout tabLayout;
private NavigationView navigationView;
static int picklistMode;
public boolean isPagerMotorAvailable() {
return pagerMotorAvailable;
}
static boolean pagerMotorAvailable;
private int scannerID;
TextView barcodeCount;
int iBarcodeCount;
int BARCODE_TAB = 1;
int ADVANCED_TAB = 2;
static MyAsyncTask cmdExecTask=null;
Button btnFindScanner = null;
static final int ENABLE_FIND_NEW_SCANNER =1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_active_scanner);
Configuration configuration = getResources().getConfiguration();
if(configuration.orientation == Configuration.ORIENTATION_LANDSCAPE){
if(configuration.smallestScreenWidthDp<Application.minScreenWidth){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}else{
if(configuration.screenWidthDp<Application.minScreenWidth){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
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.setDrawerListener(toggle);
toggle.syncState();
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
addDevConnectionsDelegate(this);
scannerID = getIntent().getIntExtra(Constants.SCANNER_ID, -1);
BaseActivity.lastConnectedScannerID = scannerID;
String scannerName = getIntent().getStringExtra(Constants.SCANNER_NAME);
String address = getIntent().getStringExtra(Constants.SCANNER_ADDRESS);
picklistMode = getIntent().getIntExtra(Constants.PICKLIST_MODE, 0);
pagerMotorAvailable = getIntent().getBooleanExtra(Constants.PAGER_MOTOR_STATUS,false);
Application.CurScannerId = scannerID;
Application.CurScannerName = scannerName;
Application.CurScannerAddress = address;
// Initilization
viewPager = (ViewPager) findViewById(R.id.activeScannerPager);
mAdapter= new ActiveScannerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
tabLayout = (TabLayout) findViewById(R.id.tablayout);
tabLayout.setupWithViewPager(viewPager);

DrawerLayout or TabLayout is null after resuming activity from background?

whenever I create my activity initially, everything goes fine as I am able to inflate my layouts correctly. However, the issue is whenever I switch to using another app, then go back to my own app, I get an error saying that the TabLayout is null, causing my app to crash. If I switch to another app for a few minutes, my DrawerLayout is null, also causing my app to crash.
If I understand the Android Life Cycle correctly, I realize that the activity is recreated when it goes from background to foreground, and the onCreate method is called again as referenced from this: Android activity life cycle - what are all these methods for?. However, I don't understand why when the app starts, everything works fine, but when I go into the background, either the TabLayout or the DrawerLayout is set to null. Here is my attempt:
news_feed.java:
private static DrawerLayout drawer;
private static TabLayout tabLayout;
public class news_feed extends BatchAppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_feed);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Listen for navigation events
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close){
public void onDrawerOpened(View view) {
super.onDrawerOpened(view);
}
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
};
System.out.println("news_feed: toolbar: " + toolbar);
System.out.println("news_feed: Drawer: " + drawer);
System.out.println("news_feed: toggle: " + toggle);
drawer.setDrawerListener(toggle);
toggle.syncState();
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
System.out.println("news_feed: Tab Layout: " + tabLayout);
tabLayout.addTab(tabLayout.newTab().setText("First"));
tabLayout.addTab(tabLayout.newTab().setText("Second"));
tabLayout.addTab(tabLayout.newTab().setText("Third"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
}
}
news_feed.xml:
<?xml version="1.0" encoding="utf-8"?>
<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:openDrawer="start">
<include layout="#layout/app_bar_news_feed" android:layout_width="match_parent"
android:layout_height="match_parent" android:id="#+id/app_bar_main" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="#layout/nav_header_friends_list"
android:id="#+id/navigation_header"/>
<ListView
android:id="#+id/friends_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
</LinearLayout>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
app_bar_news_feed.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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:layout_width="match_parent"
android:layout_height="match_parent" android:fitsSystemWindows="true"
tools:context=".news_feed">
<RelativeLayout
android:id="#+id/main_layout"
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:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
android:layout_width="match_parent" android:theme="#style/AppTheme.AppBarOverlay" android:id="#+id/app_bar">
<android.support.v7.widget.Toolbar android:id="#+id/toolbar"
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<!-- <include layout="#layout/content_news_feed" /> -->
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/app_bar"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_below="#id/tab_layout"/>
</RelativeLayout>
<android.support.design.widget.FloatingActionButton android:id="#+id/fab"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom|end" android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
I made sure that the findViewById's are all referencing the correct id's, but I can't seem to figure what is going wrong. It's strange: if I quickly switch from app -> another app -> app, then the TabLayout is null. If I switch from app -> another app -> wait a few minutes -> app, then DrawerLayout is null. I have no idea why this is occuring! Any help would be appreciated.
Edit: The app crashes on the onCreate method of my activity. Moreover, I have provided a stacktrace: as followed here:
03-16 09:31:21.116 25852-25852/com.test.tabs.tabs I/System.out: news_feed: toolbar: android.support.v7.widget.Toolbar{380bcc25 V.E..... ......ID 0,0-0,0 #7f0d009c app:id/toolbar}
03-16 09:31:21.116 25852-25852/com.test.tabs.tabs I/System.out: news_feed: Drawer: android.support.v4.widget.DrawerLayout{3ed761fa VFE..... ......I. 0,0-0,0 #7f0d0095 app:id/drawer_layout}
03-16 09:31:21.116 25852-25852/com.test.tabs.tabs I/System.out: news_feed: toggle: com.test.tabs.tabs.com.tabs.activity.news_feed$1#22eb13ab
03-16 09:31:21.116 25852-25852/com.test.tabs.tabs I/System.out: news_feed: Tab Layout: null
03-16 09:31:21.116 25852-25852/com.test.tabs.tabs E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test.tabs.tabs, PID: 25852
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.tabs.tabs/com.test.tabs.tabs.com.tabs.activity.news_feed}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.design.widget.TabLayout$Tab android.support.design.widget.TabLayout.newTab()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2661)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.access$900(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5835)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.design.widget.TabLayout$Tab android.support.design.widget.TabLayout.newTab()' on a null object reference
at com.test.tabs.tabs.com.tabs.activity.news_feed.onCreate(news_feed.java:174)
at android.app.Activity.performCreate(Activity.java:6221)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2614)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
at android.app.ActivityThread.access$900(ActivityThread.java:172) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:5835) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 
Edit: Included BatchAppCompatActivity class:
public class BatchAppCompatActivity extends AppCompatActivity {
#Override
protected void onStart()
{
super.onStart();
Batch.onStart(this);
}
#Override
protected void onStop()
{
Batch.onStop(this);
super.onStop();
}
#Override
protected void onDestroy()
{
Batch.onDestroy(this);
super.onDestroy();
}
#Override
protected void onNewIntent(Intent intent)
{
Batch.onNewIntent(this, intent);
super.onNewIntent(intent);
}
}
Your declaration of the drawer and tabLayout variables seems a bit strange. Unless it's a typo I'm surprised it even works. Something like
public class news_feed extends BatchAppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
private TabLayout tabLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_feed);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Listen for navigation events
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close){
public void onDrawerOpened(View view) {
super.onDrawerOpened(view);
}
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
};
System.out.println("news_feed: toolbar: " + toolbar);
System.out.println("news_feed: Drawer: " + drawer);
System.out.println("news_feed: toggle: " + toggle);
drawer.setDrawerListener(toggle);
toggle.syncState();
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
System.out.println("news_feed: Tab Layout: " + tabLayout);
tabLayout.addTab(tabLayout.newTab().setText("First"));
tabLayout.addTab(tabLayout.newTab().setText("Second"));
tabLayout.addTab(tabLayout.newTab().setText("Third"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
}
}
should work assuming toolbar is defined somewhere else in your class.

Categories

Resources