Do something on Fragment goes back - java

I have code that adds a fragment on a click event. This works and the button is removed from display afterwards, but I want the button to appear when the user presses back, and leaves the fragment. Something like onBackStackUsed.
I've tried to find something like it, but i can't find a way to do it. Is it even possible?
final FloatingActionButton floatingActionButton = (FloatingActionButton)findViewById(R.id.live_support);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getFragmentManager()
.beginTransaction()
.replace(R.id.live_support_frame, ChatWindowFragment.newInstance("XXX", "1"), "chat_fragment")
.addToBackStack("chat_fragment")
.commit();
getFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
floatingActionButton.setVisibility(View.INVISIBLE);
}
}
);
}
});

I think what you want is to implement onBackPressed in your activity. Here's a few ways to do it How to implement onBackPressed() in Fragments?

Override onBackPressed inside the activity like this:
#Override
public void onBackPressed() {
Fragment frag = getSupportFragmentManager().findFragmentByTag("fragment");
if(frag instanceOf SearchFragment && frag.getTag().equals("chat_fragment")) {
floatingActionButton.setVisibility(View.INVISIBLE); // or visible
} else {
super.onBackPressed();
}
}

Override onBackPress() method in Activity and manage it like below:
#Override
public void onBackPressed() {
Fragment myFragment = getSupportFragmentManager().findFragmentByTag("fragment");
if (myFragment instanceof SearchFragment && myFragment.isVisible()) {
//do what you want here
}
}
Happy coding :)

getFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
floatingActionButton.show();
} else {
floatingActionButton.hide();
}
}
}
);
onBackStachChanged is called both when adding and stack, or removing.
So i'm just checking if there's already one, or not.

Related

Android Fragment.getView() returns NULL after BackPressed

My question is quite similar to this one: fragment.getView() return null after backpressed
The problem is next: I have a special Fragment with two states: A and B. If Fragment is in the state B, Backpress should switch the state from B to A. (The difference between two states is in visibility of some elements on a layout) If Fragment is in state A, Backpress should close this Fragment. I overwrote the onBackPressed() method in my activity in next way:
#Override
public void onBackPressed() {
int count = getSupportFragmentManager().getBackStackEntryCount();
if (count > 1) {
if (isStateB) {
isStateB = false;
MessagesFragment messFragment = ((MessagesFragment) getSupportFragmentManager().findFragmentByTag("MessagesFragment"));
if (messFragment != null) {
Log.d(TAG, "Message Fragment Refresh");
messFragment.refreshFragWithoutMessChecked();
return;
} else {
Log.d(TAG, "Fail To Message Fragment Resfresh");
}
}
}
}
super.onBackPressed();
}
This code executes refreshFragWithoutMessChecked() but nothing happens. All elements from the layout which I am trying to close aren't null, but code doesn't affect them. Also I have a button in the MessageFragment which executes the similar method, and in case I press it, the code works well. In additional I found out that if I call getView() inside refreshFragWithoutMessChecked(). In case when it called from onBackPressed(), getView() returns NULL. In case when it called from onClick() it returns something isn't NULL.
So that is why I am asking, why Backpress makes my getView() returns NULL, and how can I solve my problem?
Fragment Code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.frag_messages, container, false);
/*
Here is a big amount of elements initizalizations and onClick bindings like this:
check_message = view.findViewById(R.id.check_message);
check_message.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {MainActivity.isStateB = true;}});
*/
return view;
}
public void refreshFragWithoutMessChecked() {
MainActivity.isStateB = false;
MainActivity.posMessChecksEnabled.clear();
refreshMessageFragment();
Log.d(TAG,"Message Fragment Refreshed");
}
// Refresh Message Fragment
public void refreshMessageFragment() {
if(getView() != null){
Log.d(TAG,"A");
} else {
Log.d(TAG,"B");
}
// Hide Message Check Show
// THIS CODE DOESN'T WORK ON BACK PRESS BUT IT'S EXECUTED
if (MainActivity.isStateB == true) {
((MainActivity) getActivity()).getSupportActionBar().hide();
write_message_layout.setVisibility(View.GONE);
reply_forward_bottom.setVisibility(View.VISIBLE);
up_message_selected_panel.setVisibility(View.VISIBLE);
toolbar.setVisibility(View.GONE);
appbar_layout.setVisibility(View.GONE);
} else {
if (fromOpen.equalsIgnoreCase(MainActivity.MESSAGES_FILTER_CONTACTS) == false) {
write_message_layout.setVisibility(View.VISIBLE);
}
reply_forward_bottom.setVisibility(View.GONE);
up_message_selected_panel.setVisibility(View.GONE);
toolbar.setVisibility(View.VISIBLE);
appbar_layout.setVisibility(View.VISIBLE);
}
}

Is there a way to check for popBackStack call in a fragment

I have a back stack of a few fragments and I need to know that I have returned to one from another.
Similar to when you have onActivityResult I was wondering if you could have a check for popBackStack() calls in a fragment?
I call it in another fragment here:
#Override
public void postFinished(){
getFragmentManager().popBackStack();
}
Anything like this in android java?
You Can add Listener for BackStackChange on your Activity page Like,
getSupportFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
public void onBackStackChanged() {
// Your Code Here
}
});
getSupportFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
public void onBackStackChanged() {
FragmentManager fm = getSupportFragmentManager();
if (fm != null) {
int backStackCount = fm.getBackStackEntryCount();
if (backStackCount == 0) {
}
}
}
});
You can use addOnBackStackChangedListener with fm.getBackStackEntryCount(); which will give back stack count of fragments.
you can do in onViewCreated() method:
if (savedInstanceState == null && !mAlreadyLoaded) {
mAlreadyLoaded = true;
// Do this code only first time, not after rotation or reuse fragment from backstack
}
Because when android put fragment on backstack, it only destroy its view, but don't kill instance itself, so mAlreadyLoaded will be still true when fragment will be restored from backstack.

A loop with setOnClickListener at Android Studio

Hey so I'm trying to make a simple code that makes the visibility of a layout visible once an image been clicked twice or more.
Sadly my code doesn't work, but I don't understand why.
Here's my code -
public class MainActivity extends AppCompatActivity {
ImageView logoIMG;
LinearLayout adminLinear;
int cnt = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
logoIMG = (ImageView) findViewById(R.id.logo);
adminLinear = (LinearLayout) findViewById(R.id.adminLinear);
adminLinear.setVisibility(View.INVISIBLE);
adminLinear.setEnabled(false);
while (adminLinear.getVisibility() != View.VISIBLE) {
logoIMG.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (cnt >= 2) {
adminLinear.setVisibility(View.VISIBLE);
adminLinear.setEnabled(true);
} else {
cnt++;
}
}
});
}
}
}
Setting onClickListener in your while loop, will endlessly loop and keep on trying to add new Listener, which will cause issue.
Do following:
#Override
protected void onCreate(Bundle savedInstanceState) {
...
logoIMG.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (cnt >= 2) {
adminLinear.setVisibility(View.VISIBLE);
adminLinear.setEnabled(true);
} else {
cnt++;
}
}
});
}
Your code just gets stuck in an infinite loop. Setting an onClickListener once is enough. Remove the loop around setOnClickListener altogether, or at least replace it with a conditional (if).
"The first click just sets the focus to the Image then the second click actually gets handled as a click. "
try setting android:focusable="false" or true. vice versa
Check this Question

using switch statement to handle onBackPressed() in fragments

i am trying to handle the onBackPressed diferently for every fragment. for this i want to use a switch statement with cases dependedn on the fragment that is currently showing.
in my Main i have. but dont know what to use in the switchstatement.
public class MyActivity extends Activity
{
#Override
public void onBackPressed(){
super.onBackPressed();
switch(........){
case (1):
Fragment1.onBackPressed();
case (2):
Fragment2.onBackPressed();
}
}
in my fragments:
public class Fragment1 extends Fragment
{
//My created method
public static void onBackPressed()
{
// make it do what you want.
}
}
so my question, how can i use a switchstament where de cases are depended on what fragment is showing at this moment.
Don't use such switch in single onBackpressed of activity but you can get the key event of each fragment object and do like this,
fragment.getView().setFocusableInTouchMode(true); //Don't miss this line
fragment.getView().setOnKeyListener( new OnKeyListener()
{
#Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
//Do what you want
return true;
}
return false;
}
} );
In on onBackPressed(). You can check current visible Fragment
public class MyActivity extends Activity
{
#Override
public void onBackPressed(){
if(yourFragment1.isVisible()) {
...
}else if(yourFragment2.isVisible(){
...
}
}
}

Andorid : setOnClickListener does not work when calling Twice

I'm using setOnClickListener for listening on the click event on imageButton in two methods, but it's does not fire in my another method,my first listener firing but my second listener does not fire please see my codes :
Class FirstActivity extends BaseActivity
{
#Override
public void onCreate()
{
super.onCreate();
this.methodA();
this.methodB();
}
public void methodA()
{
ImageButton imageButton = (ImageButton) RContextHelper.getActivity().findViewById(R.id.my_location_button);
imageButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//event firing when image button touched
}
});
}
public void methodB()
{
Test test = new Test(this);
test.methodA();
}
}
class Test
{
Context con;
public Test(Context con)
{
this.con = con;
}
public void methodA()
{
ImageButton imageButton = (ImageButton) getActivity().findViewById(R.id.my_location_button);
imageButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//event does not fire when image button touched
}
});
}
protected ActionBarActivity getActivity()
{
return (ActionBarActivity) con;
}
}
As you can guess from the name setOnClickListener sets the new listener and replaces the old one. That is the case with all the set* listeners in Java. If it was addOnClickListener then you could expect that both listeners should be called.
If you want both of them to be called, you can write a composite on click listener and add both of the listeners to it and set the composite listener to the target.
class CompositeListener implements OnEventListener {
private List<OnEventListener> registeredListeners = new ArrayList<OnEventListener>();
public void registerListener (OnEventListener listener) {
registeredListeners.add(listener);
}
public void onEvent(Event e) {
for(OnEventListener listener:registeredListeners) {
listener.onEvent(e);
}
}
}
And then:
CompositeListener composite = new CompositeListener();
composite.registerListener(listener1);
composite.registerListener(listener2);
imageButton.setOnEventListener(composite);
Source
Very confusing to code with two methodA functions. You never call the second one. At least you are not showing code for that. Moreover - as has been said already - there can only be one listener.

Categories