When i try to update the value of a Textview after a dialogfragment i get the right value but if the previous value is longer its old view is still visible (and ugly) in the background.
I tried calling onResume() for the current fragment but no improvements.
I just call a dialog and when the listener onFinishEditDialog() is called i just set the text
If i open another app and i come back it is perfect (the old is gone)
how is this possible?
in the xml layout:
<TextView
android:id="#+id/txttotalcho"
style="#style/importantTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="40dp"
android:text="33 cho"
android:textSize="64dp" />
in the MainActivity:
#Override
public void onGoToPage(int pageNumber,boolean verso, Pasto p,ArrayList<CiboSelezionato> cibiSelezionati,String extra) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment firstDetail =
(Fragment)fm.findFragmentByTag(SECOND_DETAIL_FRAGMENT_TAG);
ft.remove(firstDetail);
ft.commit();
FragmentTransaction ft2 = fm.beginTransaction();
switch (pageNumber){
case Constants.P_SCELTA_PASTO:{
WizardPasti10 secondDetail = WizardPasti10.getInstance(this);
ft2.replace(R.id.anchor_layout,secondDetail,SECOND_DETAIL_FRAGMENT_TAG);
break;
}
case Constants.P_TOTAL_CHO:{
WizardPastiTotalCho secondDetail = WizardPastiTotalCho.getInstance(this);
ft2.replace(R.id.anchor_layout,secondDetail,SECOND_DETAIL_FRAGMENT_TAG);
break;
}
ft2.commit();
View v1,v2;
v1=(View)findViewById(R.id.anchor_left);
v2=(View)findViewById(R.id.anchor_layout);
v1.setVisibility(View.GONE);
v2.setVisibility(View.VISIBLE);
v2.setBackgroundColor(getResources().getColor(R.color.white));
}
in the fragment WizardPastiTotalCho:
private TextView txtTotalCho;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View firstView = inflater.inflate(R.layout.wizardpastitotalcho, container, false);
txtTotalCho = (TextView)firstView.findViewById(R.id.txttotalcho);
txtTotalCho.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View button) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = new TastierinoDialogFragment(WizardPastiTotalCho.this,Constants.CARBOIDRATI,0);
newFragment.show(ft, "totalchoDialog");
}
});
}
#Override
public void onFinishEditDialog(int dialogType, String inputText) {
//called when i close the dialogFragment
txtTotalCho.setText(inputText+" cho");
txtTotalCho.setBackgroundColor(Color.YELLOW);//just to see the difference
try {
totalCho=Float.parseFloat(inputText);
tmpPasto.setCarboidrati(totalCho);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
Related
I have Index.class as the Activity, when the user choose Profile, it will call fragment Profile
if (id == R.id.nav_profile){
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.setCustomAnimations(R.anim.enter,R.anim.exit,R.anim.enter,R.anim.exit);
transaction.replace(R.id.flContent, new Profile(), "ProfileFragment");
transaction.addToBackStack(null);
viewPager.getAdapter().notifyDataSetChanged();
transaction.commit();
}
Now in Profile Fragment, when the user clicks a button it will call DevRegistration Activity
case 1:
btnBeDeveloper.setText("Developer Console");
btnBeDeveloper.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent index = new Intent(getActivity(), DevRegistration.class);
startActivity(index);
}
});
break;
Then in DevRegistration class, after I click the register button, it will display a dialog fragment class.
What I want to do is when I click the button inside the dialog fragment, how can I refresh the profile fragment?
Dialog Fragment Class:
public class df_SuccessDevRegistration extends DialogFragment {
Button btnDevGoProfile;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
View rootView = inflater.inflate(R.layout.fragment_success_developer_registration, container, false);
btnDevGoProfile = (Button) rootView.findViewById(R.id.btnDevGoProfile);
btnDevGoProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
getFragmentManager().popBackStack();
getActivity().finish();
Profile fragment = (Profile)
getSupportFragmentManager().findFragmentByTag("ProfileFragment");
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction()
transaction.detach(fragment);
transaction.attach(fragment);
transaction.commit();
}
});
return rootView;
}
}
By the way, I dont know why getSupportFragmentManager isnt working. It shows an error cannot resolve method... when I used getFragmentManager() it crashes.
You could also try this to refresh the current fragment
FragmentTransaction ftran = getActivity().getFragmentManager().beginTransaction();
ftran .detach(this).attach(this).commit();
In your dev registration activity , get your fragment :
Profile profileFragment = getSupportFragmentManager().findFragmentByTag("ProfileFragment");
To refresh it you can try :
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.detach(profileFragment);
transaction.attach(profileFragment);
transaction.commit();
EDIT:
Can you try this ?
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
View rootView = inflater.inflate(R.layout.fragment_success_developer_registration, container, false);
btnDevGoProfile = (Button) rootView.findViewById(R.id.btnDevGoProfile);
return rootView;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
btnDevGoProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().popBackStack();
Profile fragment = (Profile)
getActivity().getSupportFragmentManager().findFragmentByTag("ProfileFragment");
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction()
transaction.detach(fragment);
transaction.attach(fragment);
transaction.commit();
getActivity().finish();
dismiss();
}
});
}
Hope this helps.
Please any one help me, I am new in android studio, my app getting crash while resume application,
I have three different fragment layout which have
<fragment
android:id="#+id/map_online"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/action_bar" /> with different ID.
while resume application I need to load one Fragment with map,
I am getting following error:
Caused by: java.lang.IllegalArgumentException: Binary XML file line
39: Duplicate id 0x7f0f018a, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.SupportMapFragment
Please any one sugggest how to solve this.
This is my fragment class:
public class ClientRequestFragment extends Fragment implements OnMapReadyCallback {
View clientRequestView;
private static final String TAG = ClientRequestFragment.class.getSimpleName();
GoogleMap googleMap;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
SupportMapFragment mapFragment = (SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map_online);
mapFragment.getMapAsync(this);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LayoutInflater li = (LayoutInflater) getActivity().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
clientRequestView = li.inflate(R.layout.offline_fragment, container, false);
return clientRequestView;
}
public void addFragment(Fragment fragment, boolean addToBackStack,
String tag, boolean isAnimate) {
FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (isAnimate) {
ft.setCustomAnimations(R.anim.slide_in_right,
R.anim.slide_out_left, R.anim.slide_in_left,
R.anim.slide_out_right);
}
if (addToBackStack) {
ft.addToBackStack(tag);
}
ft.replace(R.id.content_frame, fragment, tag);
ft.commitAllowingStateLoss();
}
#Override
public void onClick(View view) {
}
#Override
public void onMapReady(GoogleMap googleMap) {
this.googleMap = googleMap;
//googleMap.setMyLocationEnabled(true);
/* try {
// Customise the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
getActivity(), R.raw.retro_style_json));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style. Error: ", e);
}*/
}
#Override
public void onDestroyView() {
super.onDestroyView();
FragmentManager fm = getActivity().getSupportFragmentManager();
Fragment fragment = (fm.findFragmentById(R.id.map_online));
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();
}
#Override
public void onPause() {
super.onPause();
}
}
Thank you.
Your app getting crash because static fragment inside fragment can not be remove or replace , you can only hide or show this static fragment.
make your xml file like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/coreLayout"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical">
<FrameLayout
android:id="#+id/fragment_home_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
in your fragment.java file write this code:
PlaceAutocompleteFragment autocompleteFragmentSourceAddress = new PlaceAutocompleteFragment();
replaceFragment(autocompleteFragmentSourceAddress, R.id.fragment_home_container);
You need to remove fragment before push new one in your fragment view have been re-created so add ==null condition in onCreatedView method,
View mainView;// this should be global variable.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(mainview==null){
mainView = inflater.inflate(R.layout.fragment_layout, container, false);
initializeView();//initialize all views in this method instead of onActivityCreated
}
return mainView;
}
Add this when you push above fragment to avoid duplication
try {
android.app.Fragment fragment = getFragmentManager().findFragmentById(R.id.map_online);
if (fragment != null) {
android.app.FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}
} catch (Exception e) {
e.printStackTrace();
}
I have a series of fragments. And I use "previous" and "next" buttons for navigation within this fragments. There are many edit texts and radio buttons in this fragments.
I want to save and and restore the user input in these edit texts and radio buttons when a previous fragment is loaded by clicking on "previous" button.
Screeshots:
Fragment 1
Fragment 2
Fragment 1:
public class Register_Page6 extends Fragment {
public Register_Page6() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_register_page6, container, false);
Button Previous = (Button) view.findViewById(R.id.Previous6);
Button Next = (Button) view.findViewById(R.id.Next6);
Next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
android.support.v4.app.FragmentTransaction FT;
FT = getActivity().getSupportFragmentManager().beginTransaction();
FT.replace(R.id.main_container,new Register_Page7());
FT.commit();
}
});
Previous.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
android.support.v4.app.FragmentTransaction FT;
FT = getActivity().getSupportFragmentManager().beginTransaction();
FT.replace(R.id.main_container,new Register_Page5());
FT.commit();
}
});
return view;
}
}
Fragment 2:
public class Register_Page7 extends Fragment {
public Register_Page7(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_register_page7, container, false);
Button Previous = (Button) view.findViewById(R.id.Previous7);
Button Regiter = (Button) view.findViewById(R.id.Submit);
Regiter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
android.support.v4.app.FragmentTransaction FT;
FT = getActivity().getSupportFragmentManager().beginTransaction();
FT.replace(R.id.main_container,new Register_Page6());
FT.commit();
}
});
Previous.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
android.support.v4.app.FragmentTransaction FT;
FT = getActivity().getSupportFragmentManager().beginTransaction();
FT.replace(R.id.main_container,new Register_Page6());
FT.commit();
}
});
return view;
}
}
Add Your fragment to back stack using addToBackStack("YOUTAG") like this in all your fragments :
android.support.v4.app.FragmentTransaction FT;
FT = getActivity().getSupportFragmentManager().beginTransaction();
FT.replace(R.id.main_container, new Register_Page6()).addToBackStack("FragmentName");
FT.commit();
When you have a series of fragments if you add them to the backstack it would be memory wastage.
For this kind of action android provides something called ViewPager, which will always store 2 fragments at a time and create the rest of fragments dynamically when needed.
So if you still decided you don't want to use ViewPager, you can store the Fragment's data in activity's bundle and you can retrieve data when creating the fragment again
I have a Fragment addtaskfragment in which I am asking the user to provide details like name, place,etc. I have a Button in the same fragment which when clicked goes to another fragment mycontacts gets a string value from that fragment and is passed to addtaskfragment. When mycontacts fragment goes back to the addtaskfragment the values previously entered in the edittexts disappears. I want those values to stay there when the value from mycontacts is returned. How can I do that? My codes are as below. Please guide me step by step.
addtaskfragment.class
public class addtaskfragment extends Fragment {
int mYear, mMonth, mDay;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.friendspage2, container, false);
addcontacts.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Fragment fr;
fr = new mycontacts();
FragmentManager fm = getFragmentManager();
android.app.FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_frame, fr);
ft.commit();
}
});
}
}
mycontacts extends Fragment
purple.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v){
Fragment fr;
fr = new addtaskfragment();
FragmentManager fm = getFragmentManager();
android.app.FragmentTransaction ft = fm.beginTransaction();
Bundle args = new Bundle();
args.putString("CID", cid);
Log.i("cid from long click", "" + cid);
fr.setArguments(args);
ft.replace(R.id.content_frame, fr);
ft.commit();
}
});
Your EditText search text is clear it's because you're replace ft.replace(R.id.content_frame, fr); fragment that means it's first called ft.remove(); and then called ft.add(); so your onCreateView() method again called and create a New reference of your EditText so that's why your EditText search text is clear.
Solution is store search text in SharedPreferences on onPause() and load the search text value from SharedPreferences on onResume() on Fragment.
Implement like below:
private void savePreferences() {
SharedPreferences settings = getActivity().getSharedPreferences("settings",
Context.MODE_APPEND);
SharedPreferences.Editor editor = settings.edit();
KeywordValue = inputSearch.getText().toString();
System.out.println("onPause save keyword: " + KeywordValue);
editor.putString("searchText","");
editor.commit();
}
and
private void loadPreferences() {
SharedPreferences settings = getActivity().getSharedPreferences("settings",
Context.MODE_APPEND);
KeywordValue = settings.getString("searchText",
"");
inputSearch.setText(KeywordValue.toString());
keyword_search=KeywordValue;
System.out.println("onResume load keyword: " + KeywordValue);
}
and used in your Fragment like
#Override
public void onPause() {
super.onPause();
savePreferences();
}
and
#Override
public void onResume() {
super.onResume();
loadPreferences();
}
Try to add android:saveEnabled="false" attribute in EditText. It fixed the same problem for me.
<EditText
android:id="#+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
...
android:saveEnabled="false" />
Here you can see another example:
I just started with fragment design for HoneyComb. I created two fragments. When i click a button in the left side fragment, a new fragment is created in right side. Meanwhile when i click a button in the right fragment(ie. DetialsFragment in my code below should be replaced by another fragment.
main.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="horizontal" >
<fragment class="com.fragment.example.Titles"
android:id="#+id/titles" android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />
<FrameLayout android:id="#+id/details" android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />
</LinearLayout>
FragmentExample.java
public class FragmentExample extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Titles.java
public class Titles extends Fragment {
public FragmentTransaction ft;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.main1, null);
Button button1 = (Button)v.findViewById(R.id.button1);
button1.setText("santhosh");
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
DetailsFragment details = (DetailsFragment)
getFragmentManager().findFragmentById(R.id.details);
if (details == null || details.getShownIndex() != 1) {
// Make new fragment to show this selection.
details = DetailsFragment.newInstance(1);
// Execute a transaction, replacing any existing
// fragment with this one inside the frame.
ft
= getFragmentManager().beginTransaction();
ft.add(R.id.details, details, "detail");
ft.setTransition(
FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
}
});
return v;
}
}
DetailsFragment.java
public class DetailsFragment extends Fragment {
/**
* Create a new instance of DetailsFragment, initialized to
* show the text at 'index'.
*/
Titles title = new Titles();
String[] titles = {"Title1", "Title2", "Title3", "Title4"};
public static DetailsFragment newInstance(int index) {
DetailsFragment f = new DetailsFragment();
// Supply index input as an argument.
Bundle args = new Bundle();
args.putInt("index", index);
f.setArguments(args);
return f;
}
public int getShownIndex() {
return getArguments().getInt("index", 0);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
// Currently in a layout without a container, so no
// reason to create our view.
return null;
}
Button button = new Button(getActivity());
button.setText("Next");
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
return button;
}
}
Then provided your button is showing and the click event is being fired you can call the following in your click event:
final FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.details, new NewFragmentToReplace(), "NewFragmentTag");
ft.commit();
and if you want to go back to the DetailsFragment on clicking back ensure you add the above transaction to the back stack, i.e.
ft.addToBackStack(null);
Or am I missing something? Alternatively some people suggest that your activity gets the click event for the button and it has responsibility for replacing the fragments in your details pane.
Latest Stuff
Okay. So this is a very old question and has great answers from that time. But a lot has changed since then.
Now, in 2020, if you are working with Kotlin and want to change the fragment then you can do the following.
Add Kotlin extension for Fragments to your project.
In your app level build.gradle file add the following,
dependencies {
def fragment_version = "1.2.5"
// Kotlin
implementation "androidx.fragment:fragment-ktx:$fragment_version"
// Testing Fragments in Isolation
debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
}
Then simple code to replace the fragment,
In your activity
supportFragmentManager.commit {
replace(R.id.frame_layout, YourFragment.newInstance(), "Your_TAG")
addToBackStack(null)
}
References
Check latest version of Fragment extension
More on Fragments
You can try below code. it’s very easy method for push new fragment from old fragment.
private int mContainerId;
private FragmentTransaction fragmentTransaction;
private FragmentManager fragmentManager;
private final static String TAG = "DashBoardActivity";
public void replaceFragment(Fragment fragment, String TAG) {
try {
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(mContainerId, fragment, tag);
fragmentTransaction.addToBackStack(tag);
fragmentTransaction.commitAllowingStateLoss();
} catch (Exception e) {
// TODO: handle exception
}
}
Use android.support.v4.app for FragmentManager & FragmentTransaction in your code, it has worked for me.
DetailsFragment detailsFragment = new DetailsFragment();
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.details,detailsFragment);
fragmentTransaction.commit();
If you have a handle to an existing fragment you can just replace it with the fragment's ID.
Example in Kotlin:
fun aTestFuction() {
val existingFragment = MyExistingFragment() //Get it from somewhere, this is a dirty example
val newFragment = MyNewFragment()
replaceFragment(existingFragment, newFragment, "myTag")
}
fun replaceFragment(existing: Fragment, new: Fragment, tag: String? = null) {
supportFragmentManager.beginTransaction().replace(existing.id, new, tag).commit()
}
Updated Answer (Working for Overlap problem as well)
#aniket-thakur(https://stackoverflow.com/users/2396539/aniket-thakur) gave correct answer. Thank you for that!
But, getFragmentManager() is deprecated, so following code did work for me.
final FragmentTransaction ft = getParentFragmentManager().beginTransaction();
ft.replace(R.id.nav_host_fragment, new GalleryFragment(), "NewFragmentTag");
ft.addToBackStack(null);
ft.commit();
it's very simple how to replace with Fragment.
DataFromDb changeActivity = new DataFromDb();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.changeFrg, changeActivity);
transaction.commit();