I am Implementing tabhost with 5 tabs.On 5th tab i have an activitygroup with 2 child activity.From child activity if i press back button the app returns to the parent activity.
But what i need is on pressing tab button too it has to return to the parent activity.
this is my activity group:
public class Activitygroup extends ActivityGroup {
private Stack<String> stack;
public static Activitygroup grp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
grp = new Activitygroup();
if (stack == null) {
stack = new Stack<String>();
}
push("HomeStackActivity", new Intent(this,Extras.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
#Override
public void finishFromChild(Activity child) {
pop();
}
#Override
public void onBackPressed() {
pop();
}
public void push(String id, Intent intent) {
Window window = getLocalActivityManager().startActivity(id,
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
if (window != null) {
stack.push(id);
setContentView(window.getDecorView());
}
}
public void pop() {
if (stack.size() == 1) {
finish();
}
LocalActivityManager manager = getLocalActivityManager();
manager.destroyActivity(stack.pop(), true);
if (stack.size() > 0) {
Intent lastIntent = manager.getActivity(stack.peek()).getIntent()
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Window newWindow = manager.startActivity(stack.peek(), lastIntent);
setContentView(newWindow.getDecorView());
}
}
this is where i am handling second tab press in tabhost activity:
int numberOfTabs = tabHost.getTabWidget().getChildCount();
for (int t = 0; t < numberOfTabs; t++) {
tabHost.getTabWidget().getChildAt(t).setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
String currentSelectedTag = MainActivity.this.getTabHost().getCurrentTabTag();
String currentTag = (String) v.getTag();
if (currentSelectedTag.equalsIgnoreCase(currentTag)) {
MainActivity.this.getTabHost().setCurrentTabByTag(currentTag);
String newSelectedTabTag = MainActivity.this.getTabHost().getCurrentTabTag();
if (newSelectedTabTag.toLowerCase().indexOf("extras") != -1) {
"BACKPRESS FUNCTIONALITY"-MUST BRING THE PARENT ACTIVITY ON TOP HERE
}
return true;
}
}
return false;
}
});
}
Iphone has this functionality by default.On pressing tab on current activity it bring the parent activity on top.Please suggest me some workaround for this.thanks in advance!!!
This code is used to sense the tab press from the child activity
int numberOfTabs = tabHost.getTabWidget().getChildCount();
for (int t = 0; t < numberOfTabs; t++) {
tabHost.getTabWidget().getChildAt(t).setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
String currentSelectedTag = MainActivity.this.getTabHost().getCurrentTabTag();
String currentTag = (String) v.getTag();
if (currentSelectedTag.equalsIgnoreCase(currentTag)) {
MainActivity.this.getTabHost().setCurrentTabByTag(currentTag);
String newSelectedTabTag = MainActivity.this.getTabHost().getCurrentTabTag();
if (newSelectedTabTag.toLowerCase().indexOf("extras") != -1) {
****Here call a static method to check whether the child activity is active****
childactivity.getappcontext();
}
return true;
}
}
return false;
}
});
}
In child activity paste this code.If the child activity is active then it'll be closed when pressing the tab hence the parent activity will be visible.
#Override
public void onStart() {
super.onStart();
active=true;
}
#Override
public void onStop() {
super.onStop();
active=false;
}
public static void getAppContext() {
if(active){
System.out.println("gallery");
galleryActivity1.finish();
}
}
Feel free to ask if not clear.Would love to help.
Related
I have and application in which I am using the Single activity and different fragments let say on activity start I call fragment A , and then after taking inputs I switch to fragment B and then Fragment C .
For Some reasons I have changed the Overflow Icon successfully from styles. But now The only problem is that for some reasons I want to show the overflow icons on Fragment B but not on Fragment A and C . for this I am doing this
public static void setOverflowButtonColor(final Activity activity, final int i) {
final String overflowDescription = activity.getString(R.string.abc_action_menu_overflow_description);
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
TintImageView overflow = null;
final ArrayList<View> outViews = new ArrayList<View>();
decorView.findViewsWithText(outViews, overflowDescription,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty()) {
return;
}
overflow = (TintImageView) outViews.get(0);
//overflow.setColorFilter(Color.CYAN);
overflow.setImageResource(R.drawable.my_overflow_image);
if (i == 1 && overflow!=null) {
overflow.setEnabled(false);
overflow.setVisibility(View.GONE);
} else if (overflow != null) {
overflow.setEnabled(true);
overflow.setVisibility(View.VISIBLE);
}
overflow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity, "Overflow", Toast.LENGTH_SHORT).show();
}
});
removeOnGlobalLayoutListener(decorView, this);
}
});
}
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
}
else {
v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
}
So from Fragment A I am sending 1 in parameter so to hide the Icon but from Activity B I am sending 0 in parameter to re visible it , but it is not getting call.
Let me tell you this function working when it is called from Fragment A , I mean it is calling one time but not 2nd time or so on .
please tell me how to do this , if you know any other best method
Define an interface like below.
public interface FragmentHost{
public void onFragmentChange(int currentFragment);
}
Activity A should implement this interface.
class A extends Activity implents FragmentHost {
public static final int FRAGMENT_B = 0;
public static final int FRAGMENT_C = 1;
#Override
public void onFragmentChange(int currentFragment) {
if (currentFragment == FRAGMENT_A) {
// enable or disable button
} else if(currentFragment == FRAGMENT_B) {
// enable or disable button
}
}
}
And in each fragment . OnResume function call the onFragmentChange() method and pass the fragment id.
class B extends Fragment {
#Override
public void onResume() {
((FragmentHost) getParentActivity()).onFragmentChange(A.FRAGMENT_B);
}
}
I am working with Tabs in my application. Worked on the TabHost Class to make it customize.
When I have PARENT --> CHILD activity, in this case on back press, onResume of Parent Activity is not called in my application.
I am using the below code:
public class TabGroupActivity extends ActivityGroup {
private ArrayList<String> mIdList;
private HashMap<String, Window> mWindowStorage = new HashMap<String, Window>();//UPDATED
private boolean _isFromResume;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mIdList == null) mIdList = new ArrayList<String>();
}
/**
* This is called when a child activity of this one calls its finish method.
* This implementation calls {#link LocalActivityManager#destroyActivity} on the child activity
* and starts the previous activity.
* If the last child activity just called finish(),this activity (the parent),
* calls finish to finish the entire group.
*/
#Override
public void finishFromChild(Activity child) {
LocalActivityManager manager = getLocalActivityManager();
int index = mIdList.size()-1;
if (index < 1) {
finish();
return;
}
String actName = mIdList.get(index);
manager.destroyActivity(actName, true);
mWindowStorage.remove(actName);
mIdList.remove(index); index--;
String lastId = mIdList.get(index);
Window newWindow = null;
if(mWindowStorage.containsKey(lastId)){
newWindow = mWindowStorage.get(lastId);
}else{
Intent lastIntent = manager.getActivity(lastId).getIntent();
newWindow = manager.startActivity(lastId, lastIntent);
}
setContentView(newWindow.getDecorView());
}
/**
* Starts an Activity as a child Activity to this.
* #param Id Unique identifier of the activity to be started.
* #param intent The Intent describing the activity to be started.
* #throws android.content.ActivityNotFoundException.
*/
public void startChildActivity(String Id, Intent intent) {
Window window = null;
if(mWindowStorage.containsKey(Id)){
window = mWindowStorage.get(Id);
if(_isFromResume){
setFromResume(false);
mIdList.clear();
mIdList.add(Id);
mWindowStorage.clear();
mWindowStorage.put(Id, window);
}
}else{
window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
if (window != null) {
mIdList.add(Id);
mWindowStorage.put(Id, window);
}
}
setContentView(window.getDecorView());
}
/**
* The primary purpose is to prevent systems before android.os.Build.VERSION_CODES.ECLAIR
* from calling their default KeyEvent.KEYCODE_BACK during onKeyDown.
*/
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//preventing default implementation previous to android.os.Build.VERSION_CODES.ECLAIR
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* Overrides the default implementation for KeyEvent.KEYCODE_BACK
* so that all systems call onBackPressed().
*/
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
return true;
}
return super.onKeyUp(keyCode, event);
}
/**
* If a Child Activity handles KeyEvent.KEYCODE_BACK.
* Simply override and add this method.
*/
#Override
public void onBackPressed () {
int length = mIdList.size();
if ( length > 0) {
Activity current = getLocalActivityManager().getActivity(mIdList.get(length-1));
current.finish();
}
}
public void setFromResume(boolean isFromResume) {
_isFromResume = isFromResume;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Activity activity = getLocalActivityManager().getCurrentActivity();
RegisterDeRegisterResponse register = RegisterDeRegisterResponse
.getInstance();
register.notifyRegisteredUser(requestCode, resultCode, data);
register.deRegisterForServerResponse((IResultResponse) activity);
}
public void switchTab(int i) {
WeddingTabActivity parentActivity = (WeddingTabActivity) getParent();
parentActivity.switchTab(i);
}
}
Also worked with default startChildActivity(String Id, Intent intent) and finishFromChild(Activity child) methods but in that case every Activity is relaunched on BackPress.
#Override
public void finishFromChild(Activity child) {
LocalActivityManager manager = getLocalActivityManager();
int index = mIdList.size()-1;
if (index < 1) {
finish();
return;
}
manager.destroyActivity(mIdList.get(index), true);
mIdList.remove(index); index--;
String lastId = mIdList.get(index);
Intent lastIntent = manager.getActivity(lastId).getIntent();
Window newWindow = manager.startActivity(lastId, lastIntent);
setContentView(newWindow.getDecorView());
}
public void startChildActivity(String Id, Intent intent) {
Window window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
if (window != null) {
mIdList.add(Id);
setContentView(window.getDecorView());
}
}
In tab host I have done a whole project and then same problem I have the onresume does not get called.. and the activity group is now deprecated and you will be not able to call onresume check this may be it will help.. best of luck
Currently i am working in Android application, Using Tabbar to create five tabs like 1,2,3,4 and 5. 1st tab using ListActivity to create ListView, when i select the ListItem from ListView, the ListItem value goes to 3rd tab and also i am getting the value in 3rd tab fine, but the problem is the value pass from 1st tab to 3rd tab, at the time 1st tab only selected, but i want 3rd tab select.
How to fix this?, please help me.
Thanks in Advance
Source code for your reference:
1st Tab :
#Override
protected void onListItemClick(ListView l, final View v, int position, long id)
{
super.onListItemClick(l, v, position, id);
String SelectedItem = l.getItemAtPosition(position).toString();
System.out.println("Selected Item: "+ SelectedItem);
System.out.println("position Item: "+ position);
String SelectedPhoneNumber = phoneNumber.get(position);
System.out.println("SelectedPhoneNumber " + SelectedPhoneNumber);
// Using TabGroupActivity, so
Intent i = new Intent(getParent(), 3rdTab.class);
i.putExtra("DestinationNumber", SelectedPhoneNumber);
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("Sample", i);
}
TabGroupActivity.java
public class TabGroupActivity extends ActivityGroup
{
private ArrayList<String> mIdList;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (mIdList == null) mIdList = new ArrayList<String>();
}
#Override
public void finishFromChild(Activity child)
{
LocalActivityManager manager = getLocalActivityManager();
int index = mIdList.size()-1;
if (index < 1)
{
finish();
return;
}
manager.destroyActivity(mIdList.get(index), true);
mIdList.remove(index); index--;
String lastId = mIdList.get(index);
Intent lastIntent = manager.getActivity(lastId).getIntent();
Window newWindow = manager.startActivity(lastId, lastIntent);
setContentView(newWindow.getDecorView());
}
public void startChildActivity(String Id, Intent intent) {
Window window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
if (window != null) {
mIdList.add(Id);
setContentView(window.getDecorView());
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//preventing default implementation previous to android.os.Build.VERSION_CODES.ECLAIR
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* Overrides the default implementation for KeyEvent.KEYCODE_BACK
* so that all systems call onBackPressed().
*/
#Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
onBackPressed();
return true;
}
return super.onKeyUp(keyCode, event);
}
#Override
public void onBackPressed ()
{
int length = mIdList.size();
if ( length > 1)
{
Activity current = getLocalActivityManager().getActivity(mIdList.get(length-1));
current.finish();
}
}
}
Have you looked through the sample application at the bottom of this post?
More specifically:
Does your main activity follow the format of TabSample.java and add the tabs to a TabHost?
Do your tabbed Activities extend TabGroupActivity? You can see in the sample that the author creates a new class that extends TabGroupActivity for each tab (eg TabGroup1Activity, TabGroup2Activity), then each of those Activities launches another activity (such as OptionsActivity or EditActivity).
If all else fails, you should also be able to manually change the selected tab using tabHost.setCurrentTab(int tabIndex).
I use Tabgroupactivity in my app if i used editbox in my app .When i click editbox keyboard opens. At this tym if if press back button my app goes two backs.
Following is my code for tabgroupactivity.
public class TabGroupActivity extends ActivityGroup {
private ArrayList<String> mIdList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mIdList == null) mIdList = new ArrayList<String>();
}
/**
* This is called when a child activity of this one calls its finish method.
* This implementation calls {#link LocalActivityManager#destroyActivity} on the child activity
* and starts the previous activity.
* If the last child activity just called finish(),this activity (the parent),
* calls finish to finish the entire group.
*/
// public void finishFromChild(Activity child) {
//
// LocalActivityManager manager = getLocalActivityManager();
// int index = mIdList.size()-1;
//
// if (index < 1) {
// finish();
// return;
// }
//
// manager.destroyActivity(mIdList.get(index), true);
// mIdList.remove(index); index--;
// String lastId = mIdList.get(index);
// Intent lastIntent = manager.getActivity(lastId).getIntent();
// Window newWindow = manager.startActivity(lastId, lastIntent);
// setContentView(newWindow.getDecorView());
// }
#Override
public void finishFromChild(Activity child)
{
LocalActivityManager manager = getLocalActivityManager();
int index = mIdList.size()-1;
if (index < 1)
{
finish();
return;
}
destroy(mIdList.get(index), manager);
mIdList.remove(index);
index--;
String lastId = mIdList.get(index);
Intent lastIntent = manager.getActivity(lastId).getIntent();
Window newWindow = manager.startActivity(lastId, lastIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
//Window newWindow = manager.startActivity(lastId, lastIntent);
setContentView(newWindow.getDecorView());
}
public boolean destroy(String id , LocalActivityManager manager) {
if(manager != null){
manager.destroyActivity(id, false);
try {
final Field mActivitiesField = LocalActivityManager.class.getDeclaredField("mActivities");
if(mActivitiesField != null){
mActivitiesField.setAccessible(true);
#SuppressWarnings("unchecked")
final Map<String, Object> mActivities = (Map<String, Object>)mActivitiesField.get(manager);
if(mActivities != null){
mActivities.remove(id);
}
final Field mActivityArrayField = LocalActivityManager.class.getDeclaredField("mActivityArray");
if(mActivityArrayField != null){
mActivityArrayField.setAccessible(true);
#SuppressWarnings("unchecked")
final ArrayList<Object> mActivityArray = (ArrayList<Object>)mActivityArrayField.get(manager);
if(mActivityArray != null){
for(Object record : mActivityArray){
final Field idField = record.getClass().getDeclaredField("id");
if(idField != null){
idField.setAccessible(true);
final String _id = (String)idField.get(record);
if(id.equals(_id)){
mActivityArray.remove(record);
break;
}
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
return false;
}
/**
* Starts an Activity as a child Activity to this.
* #param Id Unique identifier of the activity to be started.
* #param intent The Intent describing the activity to be started.
* #throws android.content.ActivityNotFoundException.
*/
public void startChildActivity(String Id, Intent intent) {
Window window;
window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP ));
if (window != null) {
mIdList.add(Id);
setContentView(window.getDecorView());
}
}
/**
* The primary purpose is to prevent systems before android.os.Build.VERSION_CODES.ECLAIR
* from calling their default KeyEvent.KEYCODE_BACK during onKeyDown.
*/
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//preventing default implementation previous to android.os.Build.VERSION_CODES.ECLAIR
return true;
}
return super.onKeyDown(keyCode, event);
}
/**
* Overrides the default implementation for KeyEvent.KEYCODE_BACK
* so that all systems call onBackPressed().
*/
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
return true;
}
return super.onKeyUp(keyCode, event);
}
/**
* If a Child Activity handles KeyEvent.KEYCODE_BACK.
* Simply override and add this method.
*/
#Override
public void onBackPressed () {
int length = mIdList.size();
if ( length > 1) {
Activity current = getLocalActivityManager().getActivity(mIdList.get(length-1));
current.finish();
}else{
finish();
}
}
}
Try adding key listener to your EditText like this,
eidtText.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
if(arg2=KeyEvent.KEYCODE_BACK)
{
//handle back event here
onBackPressed();
return true;
}
else
{
return false;
}
}
});
I make an application in which i had made 5 Tabs on the First Tab there is a ListView When i Click on any ListItem i had call another activity with intent .Now there us a problem As & when i click on Listitem The Tabs will Dissapears How can i show Tabs on my SubActivity .
Any help willl be Appretiated.
That is the normal behavior in Android, not very nice.
I usually create the first Activity in a Tab extending from this class
public class TabActivityGroup extends ActivityGroup {
protected LocalActivityManager manager;
protected ArrayList<String> mIdList;
public TabActivityGroup() {
this(false);
}
public TabActivityGroup(boolean single) {
super(single);
}
public void onCreate(Bundle ins) {
super.onCreate(ins);
manager = getLocalActivityManager();
mIdList = new ArrayList<String>();
}
public void startChildActivity(String Id, Intent intent) {
Log.d(this.getClass().getName(), "startChildActivity " + Id + " / " + mIdList.size());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Window window = manager.startActivity(Id, intent);
if (window != null) {
mIdList.add(Id);
setContentView(window.getDecorView());
}
}
#Override
public void finishFromChild(Activity child) {
Log.d(this.getClass().getName(), "finishFromChild("+child.getClass().getName()+") mIdList.size " + mIdList.size());
int index = mIdList.size() - 1;
if (index < 1) {
finish();
}else{
Log.e(getClass().getName(), "destroy " + mIdList.get(index));
manager.destroyActivity(mIdList.get(index), true);
mIdList.remove(index);
index--;
String lastId = mIdList.get(index);
Activity previous = manager.getActivity(lastId);
setContentView(previous.getWindow().getDecorView());
}
}
/**
* Overrides the default implementation for KeyEvent.KEYCODE_BACK so that
* all systems call onBackPressed().
*/
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
goBack();
return true;
}
return super.onKeyUp(keyCode, event);
}
public void goBack() {
Log.d(this.getClass().getName(), "goBACK() : " + mIdList.size());
int length = mIdList.size();
if (length > 1) {
Activity current = manager.getActivity(mIdList.get(length - 1));
current.finish();
}else{
((MyApplication)getApplication()).systemExit(this);
//This just calls to System.exit
}
}
}
You can then create a Tab like this
public class TabOne extends TabActivityGroup {
#Override
public void onCreate(Bundle b) {
super.onCreate(b);
startChildActivity(OneActivity.class.getName(), new Intent(this, OneActivity.class));
}
Things to keep in mind:
The tab has nothing inside, just starts the real tab activity with
the startChildActivity method. This is to get a nice behavior when
going back and reach the first activity and the app needs to close.
Be very careful with the Context on the subactivities as you have
to use the TabActivityGroup context. You can do this manually by
calling getParent(), or better defining a method that loops calling
getParent() until you find the root parent.