am not too experienced in android and i am just using the TabActivity, so please bear with me. i keep seeing post about not using activites in Tabhost but views. and am not sure which is which and if thats the reason of my latest headache? i have a code with 4 tabs like this:
// Category TabActivity class
tab.setContent(new Intent(this, Mylist.class));
tab1.setContent(new Intent(this, Mylist.class));
tab2.setContent(new Intent(this, Mylist.class));
and each tab is showing the result of a method in the Mylist Activity.
is that using an activity in a tab or displaying a view? whats the difference?.
i have a context menu on an item selected in the Mylist Activity which updates the list. how can i reflect the changes in the list back to the tab in other to display that particular method in the Mylist class, that was set as the tabs content. obviously this will change if i updated or deleted an item from the list when the tab is shown. i think its possible with onResume(), but don't know what to call there or is there any better way?
in the Mylist class, i have tried this little piece of code to restart the TabActivity:
myAdapter.deleteItem(id);
fillData(); //
Intent refereshCategory = new Intent(this, Category.class);
startActivity(refereshCategory);
its restarting the activity after the item have been deleted, but how can i only show the tab whose view was in focus when it restarts and i don't want fillData() method to be shown as it does not have to do with the tabs. i hope i made myself clear enough. Thanks
Any help will be greatly appreciated. Thanks for your time.
With tab.setContent(new Intent(this, Mylist.class)); You are telling the application to display a new MyList Activity in that tab.
I'm not sure of the activity lifecycle for tabbed activities but I think it is safe to assume they follow the same standards as regular activities. onResume is called every time the activity shown (which would include being switched from another tab's activity to this activity). So any kind of updating you want to do to the list every time it is shown should go here and not in onCreate(Bundle savedInstanceState)
To create any kind of Android application you should become familiar with the Component Lifecycle
Related
I'm not so good at Android but I'm working on my project. So please forgive my ignorance.
I'm making a set of similar items with need prefenrences setting, so I made them preference fragments for each, and put those preference fragments in a viewpager, for easier use. I want to go to fragment No.1 if I clicked item No.1, then maybe fragment No.3 if I clicked on item No.3. Simply put, I want the items can link to its own preference fragment in the viewpager. The items are in MainActivity, the viewpager is in its own activity and this viewpager activity would not start as the app starts unless an item was clicked.
I learnt that viewPager.setCurrentItem(position); should be used when I want to get to a specific page of a viewpager. But my items are in MainActivity, not inside the viewpager activity. I set the viewpager as static, and put viewPager.setCurrentItem(position); inside onClick method in MainActivity, but when I click a item, the app crashes. It shows error: java.lang.NullPointerException. The app had worked fine before I dicided to link those items to their own settings, and now I really have no idea...
Could you please tell me whether it is possible to get to a specific page of a viewpager from other activity? If it is possible, how to do? Thank you so much!
Renew:
I tried to mess with the code, I changed the adapter of the viewpager into protected static MyAdapter adapter;. There was no crash then, but I always went to the first page of the viewpager, whichever item I clicked...
I think you need to pass the data to the activity.
When you call the ViewPager in the MainActivity, set a parameter.
Intent intent = new Intent(getBaseContext(), ViewPagerActivity.class);
intent.putExtra("EXTRA_PAGE", (String) position);
startActivity(intent);
Then in the start of the View Pager Activity, get the object and change the currentItem.
Bundle extras = getIntent().getExtras();
if (extras != null) {
String value = extras.getString("EXTRA_PAGE");
int position= Integer.parseInt(value );
viewPager.setCurrentItem(position);
}
Android can only have 1 visible activity at the same time, so i think it's impossible in your way.
Another approach will be the use of Fragment, but it depends on your app design and structure.
You can check more about Fragments here (Android documentation).
Hope it helps ;)
Best Regards
I have implemented a TabHost. In one tab I have Activity1, which calls Activity2 after a button click, which calls Activity3 after a button click, which calls Activity1 after a button click, etc.. No backstack functionality is required, just 1 --> 2 --> 3 --> 1, etc. All three activities have a separate layout file.
Everything works fine, except that after the first transition from 1 --> 2 the activities grab the entire screen and the tabs are invisble forever.
Question: how can I keep these three activities within the confinement of de tab area and the tabs visible? The problem has been recognized here many times before; the solution used to be ActivityGroups, but these are deprecated and Fragments are advised instead. I have seen many examples here, but nothing that could help me.
Can I keep my three activites (Activity1 extends Activity, etc)?
Should I add fragment tags to the layout files?
Do I need to work with transactions?
Should I work with one fragment class or three?
Can you please give me a few hints how I should go about? I woud already be helped if you tell which classes I need to use and of what type they are.
Thanks in advance.
It took me more than half a day, but finally found a solution that works. Unfortunately I am still stuck with deprecated issues (Activity Group and getLocalActivityManager().startActivity(..)).
Again I have a single tab under a TabHost and several activities, all operating within that tab. Navigation from one activity to the next occurs with a buttonclick. Solution:
all Activities operating within the tab need to extend ActivityGroup
All Activity classes need to have a button handler that links to the next activity like this:
public void onBtnClicked(View view) {
Intent intent = new Intent(view.getContext(), NextActivity.class);
replaceContentView("NextActivity", intent);
}
public void replaceContentView(String id, Intent newIntent) {
View view = getLocalActivityManager().startActivity(id, newIntent.
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
this.setContentView(view);
}
By this the tabs remain visible all the time, as desired.
Hope this helps someone.
I have an app that can create tabs dynamically. And when I create a tab I initiate an activity as an intent. Like so:
private void addTab(Context packageContext, Class<?> newClass, TabHost mTabHost, String tabId, String tabLabel){
// newClass is my Activity class that I want to start in the tab
Intent intent = new Intent().setClass(packageContext, newClass);
TabHost.TabSpec spec;
spec = mTabHost.newTabSpec(tabId).setIndicator(tabLabel)
.setContent(intent);
mTabHost.addTab(spec);
mTabHost.setCurrentTabByTag(tabId);
}
Pretty standard. And it works great. Now, suppose that I have a button (or menuitem, whatever) in the activity that I instantiated inside of my tab. When the user presses this button, I want the activity, and the tab it is inside of, to be removed and destroyed.
I can't seem to find a simple way to do this. I have found the TabHost.clearAllTabs() function, but this destroys all tabs and activities, I just want to remove one.
Someone suggested I save a list of all Tabs that I have opened, and then call clearAllTabs(), after which I recreate all of my other tabs except for the one I don't want.
Something like this:
public static ArrayList<TabHost.TabSpec> list = new ArrayList<TabHost.TabSpec>();
I add this line to my addTab() function so that every tab I create is remember in my ArrayList:
list.add(spec);
And then when I want to remove my tab I run this function:
public static void removeTab(){
list.remove(list.size()-1); // remove it from memory
mTabHost.clearAllTabs(); // clear all tabs from the tabhost
for(TabHost.TabSpec spec : list) // add all that you remember back
mTabHost.addTab(spec);
}
This removes my tab from my ArrayList, removes all tabs, then recreates all the tabs remaining using my ArrayList. In theory it should work, but I get the following error when I try call this function:
FATAL EXCEPTION: main
java.lang.NullPointerException
at android.widget.TabWidget.setCurrentTab(TabWidget.java:342)
at android.widget.TabWidget.focusCurrentTab(TabWidget.java:366)
at android.widget.TabHost.setCurrentTab(TabHost.java:323)
at android.widget.TabHost.addTab(TabHost.java:216)
at com.example.myapp.TabManager.removeTab(QuikBrowser.java:86)
at com.example.myapp.TabManager.TabWindow.onOptionsItemSelected(TabWindow.java:91)
at android.app.Activity.onMenuItemSelected(Activity.java:2205)
For some reason, when adding a tab, it attempts to set the current tab, and it hits a null pointer exception.
If you guys could suggest another way of achieving what I want to do, or a way to fix my current method, I would appreciate it.
Try changing current tab to 0.
Something like:
getTabHost().setCurrentTab(0);
getTabHost().clearAllTabs();
I was reading that calling clearAllTabs(); will throw a nullpointerexception if you don't set the tabhost to the first tab (.setCurrentTab(0)) before calling (.clearAllTabs())
Also this answer may help? (How to remove tab from TabHost)
I would suggest a different approach. You can use an ActivityGroup to build your own TabControl. As you are using normal Buttons (or similar controls just as you like) you can easyly arrange/create/remove them as needed.
I can't dump the whole code here but that is basically what I did when I had the same problem:
Create an Activity inherited from ActivityGroup
Place a ViewGroup in your layout where you want to show the sub-activities
Setup your buttons as needed (LinearLayout works fine with a variable count of buttons)
Start activites thru getLocalActivityManager().startActivity() as needed
You can now add/remove buttons as you like. The Activites follow the Android lifecycle so you don't have to delete them yourself.
You might have to implement onBackPressed on your ActivityGroup to properly handle the history but that depends on the project.
To put it simply. From a context menu on a TabActivity how can I initiate executing the intent for the current tab? I am trying to force a refresh.
The tabs all initiate activities displaying a subset of people names. While in one list you call up an edit activity which allows you to associate the name to one of the other lists in the TabHost. Using the back button to get back to the tabhost (onResume fires) and the list has not updated. I would like to have a context menu item to refresh the current tab.
I know about using one activity for all the views in a tabhost but for many reasons I have not chosen that method.
You can also try adding a flag to the intent when you set up the tabs in the first place.
Intent i = new Intent().setClass(this, YourClass.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
TabHost.TabSpec spec = tabHost.newTabSpec("name")
.setIndicator("Class",res.getDrawable(R.drawable.ic_tab_something))
.setContent(intent);
Tabhost tabHost.addTab(spec);
I think due to the activity lifecycle, you will have some problems 'restarting' the activity (Activity lifecycle - startActivity()) - if you were to move any logic you have inside the onCreate method into another method, then call the method from onCreate and onResume, so it rebuilds the tab content for you.
Alternatively you could add a menu item to call this method, so onCreate calls the logic method on first run, and your user can call it from the menu to refresh the contents.
I have an Android application which has four tabs (I use a main TabActivity with TabHost and TabSpecs).
In one of my sub activity (activity opened in a tab), i need to open a tab not by clicking on the tab title and i don't know how to do this.
For example, i have a button in my activity and when i click on it, it opens a different tab.
For the moment, it is what i do:
Intent intent = new Intent(myActivity.this, myTabActivity.class);
intent.putExtra("ComeFrom", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Then in the TabActivity, if i get true reading the "ComeFrom" extra i open the wished tab but the problem is that it kills all the other activies. So, if someone knows a better (cleaner) way to do that trick, please tell me...
Found an easier (I think) answer:
on the TabActivity declare a public, static and self variable and populate it on the onCreate method. F.e.:
public class TheActivity extends TabActivity {
public static TheActivity self;
...
#Override
public void onCreate(Bundle savedInstanceState) {
self=this;
on any Activity running in a tab, when you want to change the one shown on your app. you can do this:
TabHost tabHost = TheActivity.self.getTabHost();
tabHost.setCurrentTab(0);
Worked ok for me, hope serves someone else!
You have to use TabHost's "setCurrentTab(...)" for that. In one of my projects, I created a static method in the main Activity (the one with the TabHost), named "swtichToTab(int tab)". In my subactivites (those inside the tabs) could then just call "MainActivity.switchToTab()" to trigger switching.
It may not be the cleanest method, I'm sure you can achieve this using broadcast intents too.
You can create a BroadcastReceiver and send a broadcast with the index of the tab as extra
You can use views instead of activities for the content of the tabs. This way, the code is simpler and doesn't use as much memory. Plus, you then can use the setCurrentTab(tabIndex) method to easily switch between views.
I have a simple tutorial here. It has a tab activity with a list and map view. When you you click on an item in the list, the activity dynamically goes to the map view (using the setCurrentTab(tabIndex) method). You can easily modify this to have a button switch views.