i have tabs in a TabActivity that is being populated by a listview from a method in another Activity. when i click on the listview in the tab, i am trying to delete an item in the listview from onContextItemSelected and let the tab in the tabhost callback the same method in the Activity that populated the listview. please does anyone know how i can identify the tab where the action was performed from the Activity that has the listview method?
There seems to be know method like setTag() on the tabs in other to identify them. i tried this which works if i am in the TabActivity class but if i am in the other Activity, i want it to call fillAllData(). but am getting a warning from eclipse that the line is a dead code and its calling fillShopData() instead. Any ideas on how to go around this?.. i hope i have made myself clear. Thanks.
/* code in activity class after delete is pressed in onContextItemSelected*/
if( Categories.SHOP_TAB_TAG == 1) { // tab in categories TabActivity identified as int
fillShopData(); // fill this data back in tab
}else {
fillAllData(); // Dead Code from Activity
}
You can have a static variable in the Constants class which will keep the track of the Tab selected which you'll modify in the OnTabChangedListener like:
#Override
public void onTabChanged(String tabId) {
if (tabId.equalsIgnoreCase("Assigned")) {
Constants .LIST_ACTIVITY = 0;
} else if (tabId.equalsIgnoreCase("Accepted")){
Constants .LIST_ACTIVITY = 1;
}else if (tabId.equalsIgnoreCase("Rejected")){
Constants .LIST_ACTIVITY = 2;
}else if (tabId.equalsIgnoreCase("Completed")){
Constants .LIST_ACTIVITY = 3;
}
}
where tabId is the one you give while creating the tabs.
Since this is a static variable you can access it in any of the classes as a flag.
Related
I have a ViewPager using a FragmentPagerAdapter for displaying three tabs, each represented by its ow fragment. One of these fragments contains a list, that should be updated on switching / swiping to that tab. But I don't find any way to make it happen. I tried using the onResume method, but the fragments seem not to be paused and resumed on tab change. I also tried using ViewPager.OnPageChangeListener in my MainActivity:
#Override
public void onPageSelected(int position)
{
FragmentRefreshInterface currentFragment = (FragmentRefreshInterface) mSectionsPagerAdapter.getItem(position);
currentFragment.onRefreshed();
}
And in the fragment I use the following:
#Override
public void onRefreshed()
{
List<Record> records = mRecordingService.getRecords();
mRecordAdapter.clear();
mRecordAdapter.add(record);
}
But using this code I can't access my RecordingService class that is used to provide the database functions (because mRecordingService seems to be null). I initialize it in the fragment like this:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mRecordingService = new RecordingService(getContext());
}
Using the onPageChangeListener is the correct way to do it. I believe the reason why your code is not working, is because you are calling getItem on your pager adapter: getItem() actually returns a new instance of the fragment. In order to get the current instance, you use instantiateItem() (which returns a reference to the fragment actually being used).
Change your code to look something like this:
#Override
public void onPageSelected(int position)
{
FragmentRefreshInterface currentFragment = (FragmentRefreshInterface) mSectionsPagerAdapter.instantiateItem(viewPager,position);
currentFragment.onRefreshed();
}
And it should work.
I suggest that the code you have in onRefreshed() go in onResume() instead. Fragment doesn't have an onRefreshed() method. You must be implementing another interface that declares this method.
Since you are storing data in a database, you should be use a CursorAdapter or subclass such as SimpleCursorAdapter. If you do this correctly, the ListView will automatically update when you add a record to the database. Then the service can add records without needing to access the service from the fragment.
In your MainActivity:
private FirstFragment firstFragment;
private WantedFragment wantedFragment;
private ThirdFragment thirdfragment;
In getItem
switch(postition){
//return first, wanted, third fragments depending on position
}
onPageSelected:
if(position == 1) // position of the wanted fragment
wantedfragment.onRefreshed()
I have a view pager with 2 scrolling pages in my app. at first I populate it with two fragments.
In first fragment I have a button. clicking the button new adapter is created and view pager is populated with two different fragments. at the moment when I press back I exit from the app instead I want to restore previous state of the view pager. please help
For the first time:
ViewPagerAdapter pagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(),nBank);
mViewpager.invalidate();
mViewpager.setAdapter(pagerAdapter);
Second time:
public void onListItemPressed(Currency objectCurrency) {
// TODO Auto-generated method stub
DetailPagerAdapter detaluriadapteri = new DetailPagerAdapter(getSupportFragmentManager());
mViewpager.setAdapter(detaluriadapteri);
}
One solution could be to implement onBackPressed:
#Override public void onBackPressed() {
if (mViewpager != null && mViewpager.getAdapter() instanceof DetailPagerAdapter) {
ViewPagerAdapter pagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(),nBank);
mViewpager.invalidate();
mViewpager.setAdapter(pagerAdapter);
} else {
super.onBackPressed();
}
}
Though, I think it would be better to start a new activity using DetailPagerAdapter when onListItemPressed is called. This way the default behavior of android would be to navigate back to your main activity on backpress, currently your main activity could be getting too much responsibility. Thus, having a self contained activity handling the details part would also be easier to maintain as it might need different tabs, actionbar menu items, etc..
Could also be a Fragment containing a the details viewpager but I have had trouble implementing this myself. Should be possible though and my trouble might be caused by some of the libraries I use.
I have 3 tabs in my sample application with activity group. First tab contains search activity i.e.Home/Root activity and am displaying the results of search in another activity but under same tab i.e Tab1. When I press back button in result activity, it is going to search activity. Everything works fine till here. Now I want to go search activity by pressing tab1 instead of pressing back button. How can achieve this? I tried something like this
public class TabSample extends TabActivity {
public TabHost tabHost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.tabHost = getTabHost();
tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("OPT")
.setContent(new Intent(this, TabGroup1Activity.class)));
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("EDIT")
.setContent(new Intent(this, TabGroup2Activity.class)));
tabHost.setCurrentTab(1);
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String arg0) {
if (tabHost.getCurrentTabTag().equals("tab1")) {
//What should I do to display search activity here
} else {
tabHost.setCurrentTab(1);
}
}
});
tabHost.setFocusable(true);
tabHost.requestFocus();
}
}
Can anyone please help let me know how to invoke search activity when tab is pressed? What will go into if part? Because if I use tabHost.setCurrentTab(index), it will display result activity but not search activity.
NOTE: I followed the tutorial given in this link.
I think what you want to do is this: when the 'tab1' tag is selected, go back to TabGroup1Activity if (and only if) the current activity is not that activity (basically you want to simulate a 'back' press).
If so, what you want is this:
if (getCurrentActivity().getClass() != TabGroup1Activity.class)
getCurrentActivity().finish()
I'm not 100% sure I understand you fully, but let's see :)
In your onTabChanged listener you can switch on which tab have been tabed, and then open the activity as normal inside an activitygroup:
public void onTabChanged(String tabId) {
if (tabId.contentEquals("tab1")) {
Intent intent = new Intent(tabHost.getContext(), TabGroup1Activity.class);
View view = StartGroup.group.getLocalActivityManager().startActivity("tab1", intent).getDecorView();
StartGroup.group.setContentView(view);
}
}
I just reviewed my code and think there's a bit more to explain here. The problem is that you don't stack activities as normal. Instead the workaround is to make a content stack and change these instead. So what I have done is to create a class StartGroup which extends
ButtonHandlerActivityGroup:
public class StartGroup extends ButtonHandlerActivityGroup {
// Keep this in a static variable to make it accessible for all the nested activities, lets them manipulate the view
public static StartGroup group;
// Need to keep track of the history if you want the back-button to work properly,
// don't use this if your activities requires a lot of memory.
private ArrayList<View> history;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.history = new ArrayList<View>();
group = this;
// Start the root activity within the group and get its view
View view = getLocalActivityManager().startActivity("UserList", new Intent(this, UserList.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
replaceView(view);
}
public void back() {
if (history.size() > 0) {
// pop the last view
history.remove(history.size()-1);
setContentView(history.get(history.size()-1));
} else {
finish();
}
}
}
Then from the TabMaster class or what you call it you can use the StartGroup class to change the content view of an activity group.
This is something I wrote to work on devices from 2.2, so there might be an easier and more androidish way to accomplished it, but this works on almost all devices :)
Here is another thread where the use a similar approach:
Launching activities within a tab in Android
Let me know if I can help more.
There is an ArrayList in your ActivityGroup so override onPause() method in ActivityGroup and remove all the ids from ArrayList except the first one which must be your SearchActivity.
So when you go to other tab then comes back to SearchActivity( or on Tab1 ) Home will be displayed.
i have TabActivity in android project which contains some tabs. In each tab i can open various activities, and after open it in a tab i want go back to previous activity in same tab, but default android behavior close my root tab activity. How i can realise behavior that i need?
There are a few ways of doing this. The first involves creating a custom GroupActivity that will keep track of the stack from the LocalActivityManager and then extending that class for each of your tabs. For that, check out this tutorial:
http://ericharlow.blogspot.com/2010/09/experience-multiple-android-activities.html
A simpler approach is to keep an array of your tab's subviews within your initial ActivityGroup class and then override the back button. Here's some sample code:
public void replaceContentView(String id, Intent newIntent) {
View view = getLocalActivityManager()
.startActivity(id, newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
.getDecorView();
viewList.add(view); // Add id to keep track of stack.
this.setContentView(view);
}
public void previousView() {
if(viewList.size() > 0) {
viewList.remove(viewList.size()-1);
if (viewList.size() > 0)
setContentView(viewList.get(viewList.size()-1));
else
initView();
}else {
finish();
}
}
The initView() class holds all of the inflating of the original activity's view. This way, you can call this method to regenerate the original activity if there are no more views in the array.
I am trying to make an application which have 4 tabs at the bottom of the screen.
All of them contain Activity (Intent).
And I want to navigate any of the Activity to another activity. But want to keep the TabWidget visible.
Let me know as quickly as possible if you know about it.
Shaiful
The problem of error occuring due to the replacement of activities can be solved in the following manner.
First Let us understand the flow:
We have in a Tab host , activity (say a list) from which we need to go to the next Activity (say details for the clicked item) under the same tab. For this we can use the concept of replacing the activity.Also setting the flags for the tab selected and other for knowing that details are being shown now
When we press back we should get the previous activity under the same tab.For this instead of again replacing the activity we can refresh the tab while using the particular flag for tab which was selected. Also if flag for show details is true we'll go the the list in the same tab or else we will go the activity before the tabwidget (normal use of onBackPressed)
The code can be as follows..
For going from list to details...
(This can be in the onClickListener)
private OnClickListener textListener = new OnClickListener() {
#Override
public void onClick(View v) {
Constants.SHOW_DETAILS = true;
Intent intent = new Intent(context, DetailsActivity.class);
replaceContentView("activity3", intent);
}
};
public void replaceContentView(String id, Intent newIntent) {
View view = ((ActivityGroup) context)
.getLocalActivityManager()
.startActivity(id,
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
.getDecorView();
((Activity) context).setContentView(view);
}
When back pressed is done we override on BackPressed in each of the Activity under the tab to go to the list again from the details screen
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
if (MathHelper.SHOW_DETAILS) {
Log.e("back", "pressed accepted");
Constants.LIST_ACTIVITY = 1;
Constants.SHOW_DETAILS = false;
Intent intent = new Intent(this, Tab_widget.class);
startActivity(intent);
finish();
}
}
The most important part here is
Constants.LIST_ACTIVITY = 1; it indicates which tab we are in. so the corresponding activities will have its value as 0,1,2...etc
Again to load the correct list (Activty) when the tab activity is refreshed we have to include this in the TabWidget onCreate after the creation of the tabs
tabHost.setCurrentTab(Constants.LIST_ACTIVITY);
This is implemented in Tabs with multiple activities in a single tab.
However when multiple times activities are called StackOverFlow error arises. Tried very hard but unable to solve it.. Please someone tell a method to solve this problem
Also need to Replace an activity in a tab, However from child activity. How is that to be done?
At any one moment there may only be one activity. Docs about this here