Launch Launcher Activity when app goes to background - android

I have 4 activities, when i press home button, it goes in background and when i open it from background, it starts from the activity from where i resume, but i want to open Launcher activity always because in my first activity password is set and i want the user to type password every time when the app is open
android:clearTaskOnLaunch="true"
android:finishOnTaskLaunch="true"
android:launchMode="singleInstance"
`
I have tried this code in Manifest,but it is also not working.
I have also tried this but unfortunately result is same
#Override
protected void onStop() {
sliderShow.stopAutoCycle();
super.onStop();
GalleryBrowserActivity.this.finish();
Log.d("value","value on Stop"+("position"));
}

UPDATE
Hi, I tried to solve this issue so that it can be useful for future too. May be my attempt will not suit in each and every application requirement but it can be helpful in many situations. This is a demo I tried using fragments and I assume this is the only possible way to achieve this requirement. Correct me if I am wrong anywhere. Here is the code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Fragment mCurrentFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addFragment(MainFragment.newInstance());
}
public void replaceFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
String backStackTag = fragment.getClass().getName();
boolean fragmentPoped = fragmentManager.popBackStackImmediate(backStackTag, 0);
if (!fragmentPoped) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, fragment, backStackTag);
if (backStackTag != null) {
fragmentTransaction.addToBackStack(backStackTag);
}
fragmentTransaction.commitAllowingStateLoss();
}
}
public void addFragment(Fragment fragment) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
if (mCurrentFragment != null) {
Fragment f = getSupportFragmentManager().findFragmentByTag(mCurrentFragment.getClass().getName());
if (f != null) {
fragmentTransaction.remove(f);
}
}
fragmentTransaction.add(R.id.frame, fragment, fragment.getClass().getName());
fragmentTransaction.commit();
mCurrentFragment = fragment;
}
public void replaceInMainFragment(Fragment fragment) {
if (mCurrentFragment != null && mCurrentFragment instanceof MainFragment) {
((MainFragment) mCurrentFragment).replaceFragment(fragment);
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</RelativeLayout>
MainFragment.java
public class MainFragment extends Fragment {
private View mView;
private Fragment mCurrentFragment;
public static MainFragment newInstance() {
MainFragment loginFragment = new MainFragment();
return loginFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_main, container, false);
Log.e("MainFragment", "onCreateView");
return mView;
}
#Override
public void onStart() {
super.onStart();
Log.e("MainFragment", "onStart");
addFragment(LoginFragment.newInstance());
}
public void replaceFragment(Fragment fragment) {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
String backStackTag = fragment.getClass().getName();
boolean fragmentPoped = fragmentManager.popBackStackImmediate(backStackTag, 0);
if (!fragmentPoped) {
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_main, fragment, backStackTag);
if (backStackTag != null) {
fragmentTransaction.addToBackStack(backStackTag);
}
fragmentTransaction.commitAllowingStateLoss();
}
}
public void addFragment(Fragment fragment) {
removeAllFragmentFromBackstack();
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
if (mCurrentFragment != null) {
Fragment f = getActivity().getSupportFragmentManager().findFragmentByTag(mCurrentFragment.getClass().getName());
if (f != null) {
fragmentTransaction.remove(f);
}
}
fragmentTransaction.add(R.id.frame_main, fragment, fragment.getClass().getName());
fragmentTransaction.commit();
mCurrentFragment = fragment;
}
private void removeAllFragmentFromBackstack() {
FragmentManager fm = getActivity().getSupportFragmentManager();
for (int i = 0; i < fm.getBackStackEntryCount(); ++i) {
fm.popBackStack();
}
}
}
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frame_main"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</RelativeLayout>
LoginFragment.java
public class LoginFragment extends Fragment {
private View mView;
public static LoginFragment newInstance() {
LoginFragment loginFragment = new LoginFragment();
return loginFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_login, container, false);
Log.e("LoginFragment", "onCreateView");
mView.findViewById(R.id.btnLogin).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity) getActivity()).replaceInMainFragment(Fragment1.newInstance());
}
});
return mView;
}
}
fragment_login.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btnLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Login" />
</RelativeLayout>
Fragment1.java
public class Fragment1 extends Fragment {
private View mView;
public static Fragment1 newInstance() {
Fragment1 fragment1 = new Fragment1();
return fragment1;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_1, container, false);
mView.findViewById(R.id.btnFrag1).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity) getActivity()).replaceInMainFragment(Fragment2.newInstance());
}
});
return mView;
}
}
fragment_1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btnFrag1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="This is Fragment 1" />
</RelativeLayout>
Fragment2.java
public class Fragment2 extends Fragment {
private View mView;
public static Fragment2 newInstance() {
Fragment2 fragment1 = new Fragment2();
return fragment1;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_2, container, false);
mView.findViewById(R.id.btnFrag2).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return mView;
}
}
fragment_2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btnFrag2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="This is fragment 2" />
</RelativeLayout>
Hope it helps someone.
OLD
Then I think you need some hack. It will not directly accessible. Try calling 2nd activity when user press back button or any other option to go to the 2nd activity from 3rd activity. Hope it suits your app's requirement.
ThirdActivity.java
public class ThirdActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
}
#Override
public void onBackPressed() {
super.onBackPressed();
startActivity(new Intent(getBaseContext(), SecondActivity.class));
}
}
SecondActivity.java
public class SecondActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
findViewById(R.id.btnJumpToThirdScreen).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getBaseContext(), ThirdActivity.class));
}
});
}
}
OLD
Here is the demo I made just now. For this you need to define android:noHistory="true" in your manifest. Here is the sample code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btnJump).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getBaseContext(), SecondActivity.class));
}
});
}
}
SecondActivity.java
public class SecondActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ccc.stackoverflow">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:noHistory="true"></activity>
</application>
</manifest>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btnJump"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="My Launcher Activity Main" />
</RelativeLayout>
Try this demo. Also check removing noHistory flag from your Manifest. You can see the difference. Hope it helps you.

You should change your app design! Users do not want the app restarted every time they step out. They may lose some work.
You should rather use a sign-in dialog, or fragment, that is displayed above the current activity, every time user returns after app goes to background.

If you call the method:
finish();
In your life cycle methods it will work but It will have a disadvantage too:
The advantage is that when the user clicks "back" the activity will be destroyed and the user will have to put the password again.
The disadvantage is that when the user go to another app may be due to a click in the notification. After finishing using that other app, when the user clicks "back" he wont find your activity! He will have to go to a launcher and click your app icon again. This is not good for users for because they will have to click your app from launcher each time they leave the app.
BEST WAY
Declare a boolean in your Activity call it for example:
private boolean hasUserReturned=false;
Then in your onPause() method:
#Override
protected void onPause() {
super.onPause();
hasUserReturned=true;
}
Then in your onResume() nethod:
#Override
protected void onResume() {
super.onResume();
if(hasUserReturned){
recreate();
}
}
This will recreate your activity each time the user revisit your app. It handles "back button" clicks without removing your activity from backstack!

you should just follow life cycle of android,
when user press back button >> onStop() and onDestroy() called
when use press Home button >> onStop() called
when user again back to open application without more waiting and clean from stack(clear background data) >> called onRestart() called
and if user close the application and also remove application from background then it call >> onCreate()
Now just you find your point while following the life cycle of Android :-)
Solution One: apply code in onStop()
Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
OR
Solution Two: In AndroidManifest.xml file put android:launchMode="singleTask" in to all Activity
like above
<activity
android:name=".Activity.BookingConfirmClass"
android:label="#string/string_confrim_booking"
android:launchMode="singleTask"
android:parentActivityName=".Activity.HotelDetailsClass"
android:screenOrientation="portrait" />

I could suggest you one approach,
Make all your activities extend from one BaseActivity
Add a variable in BaseActivity
public static boolean HAS_RESUMED_FROM_ACTIVITY=false;
and then override startActivity in your BaseActivity like
#Override
startActivity(Intent intent){
HAS_RESUMED_FROM_ACTIVITY=true;
super.startActivity(intent);
}
Now in onResume of your activities you
#Override
protected void onResume(){
if(!BaseActivity.HAS_RESUMED_FROM_ACTIVITY){
//show your lock screen
}
super.onResume();
}

Related

Handling Back button in Parent Activity

I have my main activity which contains 2 fragments:
MainActivity
public class MainActivity extends AppCompatActivity implements FragmentOne.OnFragmentOneInteractionListener, FragmentTwo.OnFragmentTwoInteractionListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create a new Fragment to be placed in the activity layout
FragmentOne fragmentOne = new FragmentOne ();
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragmentOne ).commit();
}
}
This activity initially display fragment one.
Fragment one has a button which listens and when clicked it will replace itself with fragment two. When the button is clicked the interface in fragment one gets
//Main acitivty has this method which is a a method the interface in fragment one requires
#Override
public void goToFragmentTwo() {
//Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
// setSupportActionBar(toolbar);
// Create fragment and give it an argument specifying the article it should show
FragmentTwo fragmentTwo = new FragmentTwo ();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, fragmentTwo );
transaction.addToBackStack(FragmentTwo.BACKSTACK_TAG);
// Commit the transaction
transaction.commit();
}
If the android back button or the back button in the toolbar gets called the fragments need to have a confirm dialog which asks are you sure you want to leave. If Ok then I have a second activity called the HomeActivity (this activity is the parent activity of MainActivity) which it needs to go to, or if cancel it needs to just close the dialog and stay in the current fragment.
So in the MainActivity I have overrode the onBackPressed method which displays a :
#Override
public void onBackPressed() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Do you want to leave? ");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainActivity.super.onBackPressed();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
builder.show();
}
I am experiencing two problems with this code:
1) Pressing the back button in the toolbar doesn't display a dialog
2) The dialog's OK and Cancel features are not working correctly.
Essentially what I am trying to accomplish is I have a HomeActivity which has a button to navigate to the MainActivity. When the MainActivity gets called I will start a workflow where each fragment is a section of that workflow. If the back button is pressed this workflow needs to be discarded and the user should be returned back to the HomeActivty.
i am assuming you are using ActionBar.
Try adding this in your activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return false;
}
#Override
public void onBackPressed() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Do you want to leave? ");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MainActivity.super.onBackPressed();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
builder.show();
}
1) You should make your toolbar back button call onBackPressed() from your activity, so they both share the same functionality.
See onSupportNavegationUp() in the main activity.
2) Have your Main Activity control what happens with the fragment, but let the fragments handle any back press if they must.
I hope this is of use to you.
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.johnurrutia.so_43172788">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?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"
tools:context="com.johnurrutia.so_43172788.MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolBar"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
</android.support.v7.widget.Toolbar>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#id/toolBar"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteY="8dp">
</FrameLayout>
</android.support.constraint.ConstraintLayout>
fragment_one.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/btnGoFrag2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go To Fragment TWO" />
</LinearLayout>
fragment_two.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/goToFragmentOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Go To Fragment One" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity
implements FragmentOne.OnFragmentOneInteractionListener, FragmentTwo.OnFragmentTwoInteractionListener {
public static final int FRAGMENT_ONE = 0;
public static final int FRAGMENT_TWO = 1;
private Toolbar toolbar;
private FragmentOne fragmentOne;
private FragmentTwo fragmentTwo;
private ArrayList<Fragment> fragments = new ArrayList<>();
private int currentFragment = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create a new Fragment to be placed in the activity layout
fragmentOne = new FragmentOne();
fragmentTwo = new FragmentTwo();
fragments.add(FRAGMENT_ONE, fragmentOne);
fragments.add(FRAGMENT_TWO, fragmentTwo);
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragmentOne,"FRAGMENT_ONE")
.add(R.id.fragment_container, fragmentTwo, "FRAGMENT_TWO")
.hide(fragmentTwo)
.show(fragmentOne)
.commit();
}
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
#Override
public void onBackPressed() {
boolean fragmentProcessedTheEvent = ( (BackButtonListener) fragments.get(currentFragment)).onBackPressed();
if(!fragmentProcessedTheEvent) {
//The event is for Main Activity to exit
showActivityExitDialog();
}
}
public void showActivityExitDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Do you want to leave? ");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
builder.show();
}
private void switchToFragment(int pos) {
if (currentFragment != pos) {
getSupportFragmentManager().beginTransaction()
.hide(fragments.get(currentFragment))
.show(fragments.get(pos))
.commit();
currentFragment = pos;
}
}
public void goToFragmentTwo(){
switchToFragment(FRAGMENT_TWO);
}
public void goToFragmentOne(){
switchToFragment(FRAGMENT_ONE);
}
}
FragmentOne.java
public class FragmentOne extends Fragment implements BackButtonListener{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_one, container, false);
Button goToFragmentTwoBtn = (Button) v.findViewById(R.id.btnGoFrag2);
goToFragmentTwoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
( (OnFragmentOneInteractionListener) getActivity() ).goToFragmentTwo();
}
});
return v;
}
public interface OnFragmentOneInteractionListener{
public void goToFragmentTwo();
}
#Override
public boolean onBackPressed() {
/*
* if(fragment_has_any_use_for_back_press){
* process_it_here();
* return EVENT_PROCESSED;
* }
*
* */
return EVENT_IGNORED;
}
}
FragmentTwo.java
public class FragmentTwo extends Fragment implements BackButtonListener{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_two, container, false);
Button goToFragmentTwoBtn = (Button) v.findViewById(R.id.goToFragmentOne);
goToFragmentTwoBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
( (FragmentTwo.OnFragmentTwoInteractionListener) getActivity() ).goToFragmentOne();
}
});
return v;
}
#Override
public boolean onBackPressed() {
/*
* if(fragment_has_any_use_for_back_press){
* process_it_here();
* return EVENT_PROCESSED;
* }
*
* */
return EVENT_IGNORED;
}
public interface OnFragmentTwoInteractionListener{
public void goToFragmentOne();
}
}
BackButtonListener.java
public interface BackButtonListener {
public static final boolean EVENT_PROCESSED = true;
public static final boolean EVENT_IGNORED = false;
public boolean onBackPressed();
}

How to create a EditText common for all activities with its contents?

I am new to android. I want a EditText such that it should be visible to all activities & if I change its contents in any activity, they should reflect in every activity.Please give me solution...!!!
This can be done using a fragment , fragments are reusable , and can be attached to multiple activities , there is a single xml and java file for a fragment, when you make changes of EditText in these files , changes will be made in all of your activities , So make a fragment and attach it to all of your Activities.
If you want to use all activities, you can create a static variable
public class Utils {
public static String myString;
}
And before you start another activity, you can set the variable
Utils.myString = editText.getText().toString();
Then onResume of each activity, you can get the variable and set it to EditText
#Override
protected void onResume() {
super.onResume();
editText.post(new Runnable() {
#Override
public void run() {
if (editText!= null) {
editText.setText(Utils.myString);
}
}
});
}
But i recommend that you should use fragment is this case. It's easier.
Reuse the same fragment across the different activities.
The assumption here is that you want the edit text to be shown in activity 1 and 2.
Activity1 will be called before Activity2.
the layout of both activity1 and activity2 have a framelayout of id holder
Activity1
public class Activity1 extends Activity{
public static Fragment editTextFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_group);
...
editTextFragment = new EditTextFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.holder, editTextFragment);
ft.commit()
}
}
Activity2
public class Activity2 extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_group);
...
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.holder, Activity1.editTextFragment);
ft.commit()
}
}
EditTextFragment.java
public class EditTextFragment extends Fragment {
public testFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_edittext, container, false);
}
}
layout/fragment_edittext.xml
<FrameLayout 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"
tools:context="com.example.editTextFragment">
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>

Fragment wont start - called from Activity

I'm trying to start a fragment from my main activity, but somehow the fragment is not showing up. Can someone help me with this?
Here is my code:
public class Main extends Activity implements OnClickListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b = (Button) findViewById(R.id.action_menu);
b.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v.getId()==R.id.action_menu){
Log.d("--", "menu clicked");
MenuFragment newFragment = new MenuFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(android.R.id.content, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}
main activity layout:
<RelativeLayout 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:id="#+id/main_rl" >
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="#+id/action_menu" android:text="Menu"/>
</RelativeLayout>
and my fragment Class:
public class MenuFragment extends Fragment{
final String TAG=this.getClass().getSimpleName();
private GridView grid;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mView;
Log.d(TAG, "Hello from Fragment");
mView=inflater.inflate(R.layout.menu_fullscreen, null);
initWidgets(mView);
return mView;
}
private void initWidgets(View mView) {
grid=(GridView) mView.findViewById(R.id.menu_fullscreen_grid);
}
}
you cannot replace what you put in setContentView(R.layout.main); if main.xml is hardCoded...(xml file). with
transaction.replace...
You may use fragmentActivity without setContentView(R.layout.main)

Get edittext value from fragment

I am using fragments,I have an edittext in fragment and I want to get value in main activity.
This is my fragment layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#878787" >
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="dfgdfgdf"
android:textSize="20dp"
android:layout_centerInParent="true"
android:id="#+id/user_name"/>
<EditText
android:id="#+id/message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:text="Gönder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="getFromUser"
android:layout_marginTop="40dp"
/>
</RelativeLayout>
I am loading fragment with this function:
public void startChat(JsonObject user) {
FrameLayout layout = (FrameLayout)findViewById(R.id.container);
layout.setVisibility(View.VISIBLE);
Bundle bundle = new Bundle();
bundle.putString("name", user.get("name").getAsString());
sendTo=user.get("username").getAsString();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ConversationFragment conv = new ConversationFragment();
conv.setArguments(bundle);
fragmentTransaction.add(R.id.container, conv);
fragmentTransaction.commit();
viewPager.setVisibility(View.GONE);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayHomeAsUpEnabled(true);
}
And this is my fragment class
public class ConversationFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String name = getArguments().getString("name");
View rootView = inflater.inflate(R.layout.fragment_conversation, container, false);
TextView username=(TextView)rootView.findViewById(R.id.user_name);
username.setText(name);
return rootView;
}
}
As you can see when press the button main activity runs "getFromUser" function.I want to get edittext value in this function.How can I do this ?
It's always the same procedure for these things. You can't access a fragment's views just like that. You need a callback method.
Add this code to ConversationFragment:
private OnGetFromUserClickListener mListener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnGetFromUserClickListener ) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnGetFromUserClickListener");
}
}
public void getFromUser(View v) {
if (mListener != null) {
EditText edit = (EditText)findViewById(R.id.message);
mListener.getFromUser(edit.getText().toString());
}
}
public interface OnGetFromUserClickListener {
void getFromUser(String message);
}
Make your MainActivity implement this interface. Replace getFromUser() inside MainActivity with:
public void getFromUser(String message) {
sendMessage(message);
}
Done.
Edit:
Actually, using the XML-onClick attribute is currently bugged (see onClick inside fragment called on Activity): It links to the activity instead of the fragment. You have to set the click listener programmatically to make sure the code won't break at some point in the future. So give the button an ID inside the XML (e.g. get_from_user) and add this code to onCreateView inside ConversationFragment:
v.findViewById(R.id.get_from_user).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (v.getId() == R.id.get_from_user) {
getFromUser(v);
}
}
});
Using this code vastly decouples the activity and the fragment from each other.
I resolved this problem.
public void getFromUser(View view) {
ConversationFragment fragment1 = (ConversationFragment)getSupportFragmentManager().findFragmentById(R.id.container);
View frag=fragment1.getView();
EditText editText1 =(EditText) frag.findViewById(R.id.message);
String message=editText1.getText().toString();
sendMessage(message);
}
Now I can get edittext value from fragment.

Accessing Views inside fragment

I'm having troubles accessing the Views that within my Fragment. In the example below, I can't access the 2nd button that is within the Fragment (e.g., findViewById appears to return NULL and the app crashes when I try b2.setText("test") ), but when I directly add it in the activity_main.xml, it does work.
Here is the code:
MainActivity.java
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button fragmentButton = (Button)findViewById(R.id.iMainButton);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.iMainInnerLLContainer, new TestFragment());
ft.commit();
final Button b2 = (Button)findViewById(R.id.iTestFragmentInnerButton);
if(b2 == null) { Log.d("MainActivity.java:", "b2 is null"); }
else { Log.d("MainActivity.java:", "b2 is NOT null"); }
fragmentButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
// do stuff here
}
});
}
}
activity_main.xml
<LinearLayout 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:id="#+id/iMainRootLinearLayoutContainer"
android:orientation="vertical"
>
<Button
android:id="#+id/iMainButton"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Add fragment..."
/>
<LinearLayout
android:id="#+id/iMainInnerLLContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
>
<!-- Fragment goes here, can reference button if it is added here manually -->
</LinearLayout>
</LinearLayout>
TestFragment.java
public class TestFragment extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.ltestfragment, container, false);
}
}
ltestfragment.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="match_parent"
android:orientation="vertical"
android:id="#+id/iTestFragmentOuterLinearLayout"
>
<Button
android:id="#+id/iTestFragmentInnerButton"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="This is my test fragment button."
/>
</LinearLayout>
I think I'm missing something very basic here and I would appreciate some insight on what that might be.
Thank you in advance!
I think you need to set up a textchangelistener in your fragment.
public class FragmentA extends Fragment {
TextChangeListener listener;
public interface TextChangeListener {
public void onTextChange(CharSequence newText);
}
public void setTextChangeListener(TextChangeListener listener) {
this.listener = listener;
}
Then, in your activity, set up the listener :
public class ActivityAB extends FragmentActivity {
FragmentA fragmentA;
FragmentB fragmentB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ab);
FragmentManager manager = getSupportFragmentManager();
fragmentA = (FragmentA) manager.findFragmentById(R.id.fragmentA);
fragmentB = (FragmentB) manager.findFragmentById(R.id.fragmentB);
fragmentA.setTextChangeListener(new TextChangeListener() {
#Override
public void onTextChange(CharSequence newText) {
fragmentB.updateTextValue(newText);
}
});
}
}
Implement an interface to listen to the events of a fragment from its activity.
Code in Fragment:-
public class TestFragment extends Fragment
{
public interface OnClickListener
{
public void onButtonClicked(<data type><data>);
}
b2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
listener.onButtonClicked(<<pass some values here>>);
}
});
}
Code in Main:-
MainActivity extends FragmentActivity implements TestFragment.OnClickListener,
{
#Override
public void onButtonClicked(<<receive the pased data here>>) {
//do some stuff here with the received data after the button is clicked
}
}

Categories

Resources