Fragment: reloading on back press - android

I am using Fragments and Activity extended by AppCompatActivity in an application.
Working:
I have two fragments "Dashboard" and "Order". I am replacing fragment after clicking "Order Button" from Dashboard Fragment, and coming back to "Dashboard Fragment" after pressing back button.
Problem
I have called an API on onCreateView() of Dashboard Fragment. When I press back from Order Fragment then I come to "Dashboard Fragment" the it recall the API. I don't want to recall the API if I come to the fragment by back press.
Thanks in advance.
Code to replace dashboard fragment with order fragment
// Click event of Order
#OnClick(R.id.ll_order)
void openOrder() {
if (isOrderNotClicked) {
OrderFragment fragment = new OrderFragment();
this.getFragmentManager().beginTransaction().replace(R.id.flContent, fragment, "Order").addToBackStack(null).commit();
isOrderNotClicked = !isOrderNotClicked;
}
}

I did had same problem so i solved by `View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (view == null) {
//inflate layout and codes
}
return view;
}` but i dont know it is the best solution

Related

Fragment button not opening new activity

I've incorporated a horizontal slide navigation component (which required making the class extend Fragment). The slide part works fine. Here i have respective onClick() buttons which open a new activity. If I add a button into one of those activities I'm not finding a way to have the displayed activity subsequently refresh. I would think inflating an activity from a button within a fragment would be possible but anything I try stops the emulator.
There's not much to my code so far, so I'm not going to clutter my question with the associated layout part. Any help is certainly appreciated.
Fragment #1’s Java code
public class TasksFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tasks, container, false);
Button ID = (Button) rootView.findViewById(R.id.button_create_appraisal_rpt);
ID.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AppraisalReportActivity appraisalRptAct = new AppraisalReportActivity();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.child_fragment, appraisalRptAct);
fragmentTransaction.setTransition(fragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return rootView;
}
}
Fragment #1 (portion), which has the button that should initiate aa refresh of this Fragment #1 with Fragment #2
Fragment #2 that's to supersede/refresh the previous fragment when Fragment #1's button is clicked
I don't really understand what you mean. Do you want to click Button in Fragment to jump to another Activity?
If it is,I think maybe you can try use getActivity() to make Activity are working.
for example:
getActivity().startActivity(new Intent(getActivity(),Activity.class))
I hope my answer will help you

DialogFragment findFragmentByTag return null

I use DialogFragment contain a webview. After show the DialogFragment , when pressed back button, the app will return to the activity view. If pressed show DialogFragment button, the webview load the init url again. But my requirement is that if second time open the DialogFragment , i want the webview show page last time loaded. How can i achieve this?
My current thought is keep the DialogFragment instance, when push the show button then check if activity already has the DialogFragment. But in my code, the findFragmentByTag always return null ,what's the problem? Or I should do some work in the DialogFragment?
main activity code:
mcWebViewDialog m_webviewDialog = null;
public void showWebviewDialog()
{
FragmentManager fragmentManager=getFragmentManager();
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
Fragment prev=fragmentManager.findFragmentByTag("mcWebDialog");
if(prev!=null)
{
Log.v("seayoung","m_webviewDialog not null");
fragmentTransaction.show(prev);
}
else
{
Log.v("seayoung","m_webviewDialog null");
m_webviewDialog=mcWebViewDialog.newInstance();
m_webviewDialog.set_loadurl("file:///android_asset/input.html");
m_webviewDialog.show(fragmentManager,"mcWebDialog");
}
}
WebViewDialog code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
//other code
m_webView.loadUrl(m_loadurl);
return m_webView;
}
When you press back your dialog fragment is destroyed and is removed from backstack, hence you are getting null while performing findFragmentByTag, well it wont be a good idea to hold the view when user presses back, but as an alternative you can try caching the created fragment locally, like this.
HashMap<String,WeakReference<DialogFragment>> dialogMap = new HashMap<>();
// call this before callin `show`
dialogMap.put(TAG,new WeakReference<>(YOUR_FRAGMENT));
and next time, you can perform this
DialogFragment prev=fragmentManager.findFragmentByTag("mcWebDialog");
if(prev == null){
prev = dialogMap.get("mcWebDialog").get();
}
if(prev!=null){
Log.v("seayoung","m_webviewDialog not null");
fragmentTransaction.show(prev);
}

How to make changes in widget in parent activity based on the logic written in fragment

As an exercise i am writing a simple Ebook reader app. This has only 1 Main Activity with 3 widgets on it, 2 buttons (Previous, Next) and one Fragment container(I have used Frame Layout). All pages are different fragments that I have created that will go inside the container, and these fragments have only 1 scrollable text view that will only display text. when "next" button is pressed it should go to page2(fragment2) and when previous is pressed it should go back(previous fragment).
My problem is I don't want the "previous" button to show up on the initial screen (page1) and similarly the "next" button should not be observed on the last page.
The approach i tried was, in my fragment1(page1) class, i wrote an if condition like,
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup
container, #Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragmentpage1,container,false);
textView1=(TextView)view.findViewById(R.id.tview);
**View listView = getActivity().findViewById(R.id.previous);**
textView1.setText(R.string.page1);
if (textView1.isEnabled()){
listView.setVisibility(View.INVISIBLE);
}
return view;
}
I am checking if textview1(the first fragment) is present or not , if yes then hide the previous button on the Main Activity. This works but it completely hides the previous button even when i go to page2. I tried all possible "is" options but none of them are giving me the results I want.
One workaround that i found was to add "setvisibility" of previous button to all fragments, so on fragment1 it is invisible and then on fragment2 i changed that to visible. But that becomes lengthy if there are 100s of fragments(pages).
Please provide me with a simple solution, I am new to Android.
Below is my Main Activity code:(Do let me know if any changes needs to be done to make code more clean)
public class MainActivity extends FragmentActivity {
Fragment fragment;
FragmentManager fm=getSupportFragmentManager();
FragmentTransaction ft;
private static Button next;
private static Button previous;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
next=(Button)findViewById(R.id.next);
previous=(Button)findViewById(R.id.previous);
create();
}
public void create(){
fragment= new FragmentPage1();
ft= fm.beginTransaction();
ft.add(container,fragment);
ft.commit();
}
public void next(View view){
fragment= new FragmentPage2();
ft= fm.beginTransaction();
ft.replace(container,fragment);
ft.commit();
}
}
Maybe you can try to use the getItem() method in FragmentPagerAdapter class.
Try to disable or enable your buttons using the switch case. Hope this can help =)

RecyclerView is empty when restoring fragment from backStack

I have a RecyclerView in a Fragment and initially is hidden. When user clicks a button, I set visibility to true for the RecyclerView and I display some data I have on an ArrayList.
The problem starts when I move another fragment on top (I add the previous fragment with the RecyclerView in the backStack) : if I click back from the new fragment the previous fragment (the one with the RecyclerView ) is visible and in onCreateView() I log the values of the dataSet I'm using for the recyclerView and everything is there, but the recyclerView is empty ( only footer item is presented ).
If we call RvFragment the Fragment with the RecyclerView and NextFragment the fragment that comes to the backstack and then leaves the schema is :
(back pressed)
RvFragment ----------> NextFragment ------------> RvFragment
and here's the code from onCreateView() :
#Nullable
#Override
public View onCreateView(final LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_photo_comments, container, false);
ButterKnife.bind(this, view);
Timber.i("onCreateView data.size == %d", commentArrayList.size());
setToolbarTitle();
Picasso.with(getActivity())
.load(photo)
.placeholder(R.drawable.ic_timeline_image_placeholder)
.centerCrop()
.fit()
.into(ivPhoto);
if (hasCommentsVisible) {
Timber.i("comments are visible!! and dataSize == %d", commentArrayList.size());
llFlagsCommentsContainer.setVisibility(View.GONE);
rvCommentsList.setVisibility(View.VISIBLE);
}
tvComments.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
hasCommentsVisible = true;
llFlagsCommentsContainer.setVisibility(View.GONE);
rvCommentsList.setVisibility(View.VISIBLE);
}
});
initRecyclerView();
return view;
}
You can see with the log statements in the code above I can confirm the data exist. Thanks!
I'm not sure I understand how you set up your fragment stack but just to be sure : onCreateView won't be called again when you press the back button if the fragment is still on the stack.
https://developer.android.com/training/basics/fragments/fragment-ui.html#Replace
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
Only onStart() will.
If you want onCreateView to be called again then you need to use the
FragmentTransaction.replace(NextFragment)
without the addToBackStack() but it means the whole fragment will be recreated from scratch. Probably not what you want, especially if you are getting your data from a webservice.
Alternatively, to fully recreate your fragment every time you come back to it, you can simply remove it entirely :
FragmentTransaction.remove(RvFragment)
and then push your next fragment

Android - Blank fragment when returning from backstack

I have a view that shows a List of Properties, at the bottom of the screen there's a button that opens a fragment containing a MapView.
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.find_property_btn_map:
PropertyMapFragment fragment = PropertyMapFragment.newInstance(false, null);
getActivity().getSupportFragmentManager().beginTransaction()
.addToBackStack(null)
.replace(((ViewGroup) getView().getParent()).getId(), fragment, PropertyMapFragment.class.getSimpleName())
.commit();
break;
}
}
The onCreateView method for my Properties fragments is as follows
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_properties_list, container, false);
getmBtnMap().setOnClickListener(this);
getmBtnSaveSearch().setOnClickListener(this);
getmBtnSort().setOnClickListener(this);
getmListView().setAdapter(getPropertyAdapter());
getmListView().setOnItemClickListener(this);
getmListView().setOnScrollListener(this);
getmListView().setScrollingCacheEnabled(false);
searchProperties();
return mRootView;
}
searchProperties(); takes care of calling a Web Service and filling the ArrayAdapter.
The thing is that, when I open the MapFragment and then press the back button, my Property fragment is blank and the buttons do not respond to onClick events.
I tried debugging and saw that onCreateView() is being called when coming back to Property fragment, but the buttons are no longer working and the listview is nowhere to be seen.
What am I doing wrong?
If you are trying to launch that web view from a fragment, then try to use add fragment instead of replace.
For example :
getActivity().getSupportFragmentManager().beginTransaction()
.addToBackStack(null)
.replace(YOUR_CONTAINER_ID, fragment, PropertyMapFragment.class.getSimpleName())
.commit();
The code above is replace that fragment container with the new one and not adding that fragment on top of that. So when you do a replace fragment with that ID, it just replaces that view with new one.
Now,
Same code but with add:
getActivity().getSupportFragmentManager().beginTransaction()
.addToBackStack(null)
.add(YOUR_CONTAINER_ID, fragment, PropertyMapFragment.class.getSimpleName())
.commit();
Now, that web view fragment that you have will be added to the view/fragment and now when you press back from that web view, you previous fragment will be visible.
Just make sure that that the ID you are replacing is the same as the one in which you have all the other properties.
Maybe i misinterpreted the question so please correct me in that context.
Hope this helps.
addToBackStack() <--dont include this for your first fragment.-->
if(getSupportFragmentManager().getBackStackEntryCount() !=1){
fragmentTransaction.addToBackStack(null);
}

Categories

Resources