Solved

Removing tabs from tabhost causes app to crash

Posted on 2012-04-04
4
1,397 Views
Last Modified: 2012-04-10
I need to be able to close tabs in a TabHost for an android app I'm working on. I am currently calling this code.

    tabHost.getTabWidget().removeViewAt(toDelete);

Open in new window


Where toDelete is the index of the tab that called the removal method. It looks like that code removes the tab, from the split second I can see it before it crashes. I'm thinking there's another removal method I need to call somewhere, because it appears to crash when attempting to draw the tab that was removed. I also tried

    tabHost.removeViewAt(toDelete);

Open in new window


But it crashed because it didn't have a view at toDelete, which is expected since (I think) it just contains the tab widget rather than the actual tabs.

Here are my crash logs

    04-04 16:05:53.149: E/AndroidRuntime(7885): FATAL EXCEPTION: main
    04-04 16:05:53.149: E/AndroidRuntime(7885): java.lang.NullPointerException
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2495)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.widget.TabWidget.dispatchDraw(TabWidget.java:323)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.View.draw(View.java:10981)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.widget.FrameLayout.draw(FrameLayout.java:450)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2126)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewRootImpl.draw(ViewRootImpl.java:2026)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1634)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.os.Handler.dispatchMessage(Handler.java:99)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.os.Looper.loop(Looper.java:137)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at android.app.ActivityThread.main(ActivityThread.java:4424)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at java.lang.reflect.Method.invokeNative(Native Method)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at java.lang.reflect.Method.invoke(Method.java:511)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    04-04 16:05:53.149: E/AndroidRuntime(7885): 	at dalvik.system.NativeStart.main(Native Method)

Open in new window


Any ideas on what other methods I should be calling? Or am I going down the entirely wrong path?

Edit: I just tried opening 5 tabs and closing the second one. It didn't crash at first, but it did have some VERY odd behavior. When I click on a tab, it shows the next one to the right as being highlighted, but displays the correct tab, until I click the last tab at which point the app crashes. A few screen shots in case it helps to describe my issue.

When I click the songs tab before closing a tab
Songs tab working
When I click the tab for a specific song before closing a tab
Lyrics tab working
When I click the songs tab after closing the current program tab. The correct contents are displayed but the wrong tab looks selected.
After closing a tab
0
Comment
Question by:HDM
  • 3
4 Comments
 
LVL 24

Expert Comment

by:alexey_gusev
ID: 37809926
have you tried setting current tab to 0 before deleting?
0
 

Author Comment

by:HDM
ID: 37813781
This is the entire code that is responsible for deleting the tab.

if(toDelete != -1)
{
	int currentTab = tabHost.getCurrentTab();
	if(currentTab >= toDelete)
		currentTab--;
	tabHost.setCurrentTab(0);
	tabHost.getTabWidget().removeViewAt(toDelete);
	int count = tabHost.getTabWidget().getTabCount()-1;
	while(currentTab > count)
		currentTab--;
	tabHost.setCurrentTab(currentTab);
	toDelete = -1;
}

Open in new window


I was able to find a solution, but I don't like it. As each tab is added, I save it to a Map, with the index of the tab as the key, and the TabHost.TabSpec as the value. Then this code runs when a tab is deleted

if(toDelete != -1)
{
	int currentTab = tabHost.getCurrentTab();
	tabs.remove(toDelete);
	tabHost.setCurrentTab(0);
	tabHost.clearAllTabs();
	Iterator<Entry<Integer, TabSpec>> it = tabs.entrySet().iterator();
	int counter = 0;
	while(it.hasNext())
	{
		@SuppressWarnings("rawtypes")
		Map.Entry pairs = (Map.Entry)it.next();
		TabHost.TabSpec spec = (TabSpec)pairs.getValue();
		tabHost.addTab(spec);
		if(counter != 0)
		{
			View view = getTabWidget().getChildTabViewAt(counter);
			view.setId((Integer)pairs.getKey());
			registerForContextMenu(view);
		}
		counter++;
	}
	int count = tabHost.getTabWidget().getTabCount()-1;
	while(currentTab > count)
		currentTab--;
	tabHost.setCurrentTab(currentTab);
	toDelete = -1;
}

Open in new window


I don't like having to delete all the tabs to close one tab though, and I'm still hoping there might be a better solution.
0
 
LVL 24

Expert Comment

by:alexey_gusev
ID: 37826673
I don't like it either :) - but this seems to be the only one available
0
 
LVL 24

Accepted Solution

by:
alexey_gusev earned 500 total points
ID: 37826879
actually, looking at the source code (conveniently available now for API levels 14 & 15 right from SDK manager)  I guess you might use TabHost.getContentView() and then go from there.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article we will discuss all things related to StageFright bug, the most vulnerable bug of android devices.
Displaying an arrayList in a listView using the default adapter is rarely the best solution. To get full control of your display data, and to be able to refresh it after editing, requires the use of a custom adapter.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

948 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now