using switch statement to handle onBackPressed() in fragments - java

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(){
...
}
}
}

Related

Android Studio Databinding: Can I access the contents of a binding within an onKey event?

I am trying to implement some button events without any reference to the XML-File and with databinding instead of FindByID. Is this possible? I am having the problem that, within the OnKeyListener, the bound InputBox from which I try to get the typed text seems inaccessible (this.binding shows in red color where I put it bold). Is this a wrong approach or am I making a mistake? I'd like to avoid all that FindByID-Lines.
this.binding =
DataBindingUtil.setContentView(this, R.layout.content_main);
this.binding.EditNumber.setText("553");
this.binding.EditNumber.setOnKeyListener(new OnKeyListener()
{
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_DOWN)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
Cat supertest = Manager.CreateMainCat(this.**binding**.EditNumber.toString());
this.**binding**.DisplayCurrentBudget.setText(supertest.getsName());
return true;
default:
break;
}
}
return false;
}
});
Thank you very much
Strangely, it works when I simply put the binding in another method:
(...)
this.binding.Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
xxx();
}
});
}
public void xxx()
{
Cat supertest = Manager.CreateMainCat(this.binding.EditNumber.getText().toString());
this.binding.DisplayCurrentBudget.setText(supertest.getsName());
}
But this doesn't:
this.binding.Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cat supertest = Manager.CreateMainCat(this.binding.EditNumber.getText().toString());
this.binding.DisplayCurrentBudget.setText(supertest.getsName());
}
The propblem is solved easily, but I'd be very interested to know what's going if someone has the answer :)

Do something on Fragment goes back

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.

Communicate from Activity to Fragment using Interface

I have searched SO for this problem but was not able to find anything which would solve my problem. My problem is, I have a activity which contains FrameLayout which is constantly updated with different fragments. The top view and bottom view are going to remain same hence they are in the layout of the
activity.
As you can see bottom view has a button on click of that i want to make changes in the fragments which will be present in the FrameLayout.
I have created a interface
public interface ShowFormula {
void showFormula(boolean show);
}
which i will use to implement in the fragment.
Now the main problem in my MainActivity class i am trying to initialize the interface but not able to as i am getting class cast exception
showFormula = (ShowFormula) this;//yes i know this is wrong
How should i initialize this in order to communicate with the fragment.
Main goal is to toggle the view in fragments on click of the button in activity.
Thanks in advance.
You don't need to use an interface to make calls from an Activity to a Fragment. Just keep a reference to the current Fragment, and call into a public method in the Fragment from the Activity.
If you have multiple Fragments and you don't want to keep a reference for each one, you can create a Fragment base class, declare the common method in the base class, and then implement that method override in all of your Fragments that inherit from the base Fragment. Then, keep one reference of the base Fragment type, and always have it set to the Fragment that is shown currently.
Activity ---> Fragment
Communication from Activity to Fragment is pretty straightforward. You
really don't need a listener.
Let's say you have a method inside Fragment share()
public class MyFragment extends Fragment{
public static MyFragment getInstance()
{
return new MyFragment();
}
........
public void share()
{
// do something
}
}
How to call share() method from an Activity?
Get the reference of the Fragment and call the method. Simple!
MyFragment myFragment = MyFragment.getInstance();
myFragment.share();
You can see the full working code for Fragment to Fragment Communication
Just to add to Daniel Nugent's brilliant answer, here are snippets from my working code for delegating calls from Activity to Fragment.
I have a MVP architecture and I have defined the error handling method showError on the BaseView class and the code below demonstrates how to handle the UI on a TargetFragment class. I, specifically needed to hide my progress spinner on the fragment upon any error scenario. Here's the code snippets for the base classes:
public interface BaseView {
void showError(ErrorResponse errorResponse);
}
public abstract class BaseActivity implements BaseView {
#Override
public void showError(ErrorResponse errorResponse) {
// Check error condition or whatever
// ...
MaterialDialog dialog = new MaterialDialog.Builder(this)
.title(R.string.dialog_error_title)
.content(R.string.error_no_internet)
.positiveText(R.string.dialog_action_ok)
.build();
dialog.show();
}
}
public abstract class BaseFragment implements BaseView {
#Override
public void showError(ErrorResponse errorResponse) {
((BaseView) getActivity()).showError(errorResponse);
}
}
And, this is how I handle UI inside my TargetFragment class:
public final class TargetFragment extends BaseFragment implements TargetView {
#Override
public void showError(ErrorResponse errorResponse) {
super.showError(errorResponse);
hideSpinner();
// Do other UI stuff
// ...
}
private void hideSpinner() {
spinner.setVisibility(View.INVISIBLE);
}
}
a clean solution:
public interface ShowFormula {
public void showFormula(boolean show);
}
public class MyActivity implements ShowFormula {
...
#Override
public void showFormula(boolean show) {
/** Your Code **/
}
...
}
public class MyFragment {
private ShowFormula listener;
...
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (ShowFormula) activity;
// listener.showFormula(show?);
} catch (ClassCastException castException) {
/** The activity does not implement the listener. **/
}
}
...
}
simple thing make public method in fragments then call it on from your activity.
e.g
MyFragment fragment = new MyFragment();
fragment.doSomeThing();
doSomeThing() is a public method in MyFragment.
Activity to Fragment Communication via Interface:
public class MyActivity {
private ShowFormula showFormulaListener;
public interface ShowFormula {
public void showFormula(boolean show);
}
public void setListener(MyFragment myFragment) {
try {
showFormulaListener = myFragment;
} catch(ClassCastException e) {
}
}
}
public class MyFragment implements ShowFormula{
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
((MyActivity) activity).setListener(this);
} catch (ClassCastException e) {
Log.e(TAG, e.toString());
}
}
#Override
public void showFormula(boolean show) {
/** Your Code **/
}
}
Once you are done setting this, you can call 'showFormulaListener.showFormula(boolVal)'

What is the proper implementation of the back button press in same activity?

I want to detect the back button.
However my current implementation does not even detect the back button.
CODE:
#Override
public boolean onTouch(MotionEvent e, int scaledX, int scaledY) {
//... OTHER CODE ...
else if(e.getAction() == MotionEvent.BUTTON_BACK){
System.out.println("BACK BUTTON PRESSED");
setCurrentState(new MenuState());
}
return true;
}
}
You can use onBackPressed() inside your Activity:
#Override
public void onBackPressed() {
//Do something
}
It's written in the documentation:
public static final int BUTTON_BACK
Button constant: Back button pressed (mouse back button). The system may send a KEYCODE_BACK key press to the application when this button is pressed.
You need to override onKeyUp function from the Activity (not from the View):
public boolean onKeyUp(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
//todo
}
}
Use Intent inside onBackPressed()like this:
#Override
public void onBackPressed()
{
Intent BackIntent = new Intent(getApplicationContext(), NewActivity.class);
startActivityForResult(BackIntent);
finish();
}

vaadin viewchangelistener change newView

I try to change the newView of a navigation if the user is not authenticated and the newView is an instance of SecuredView. My approach was to check inside the beforeViewChange method if the constraints are given.
public boolean beforeViewChange(ViewChangeEvent event) {
if (event.getNewView().getClass().isInstance(SecuredView.class) && VaadinService.getCurrentRequest().getUserPrincipal() == null) {
event.getNavigator().navigateTo("login");
return false;
}
return true;
}
}
But that will result in a endless loop of redirection... How can i change the newView and stop the current navigation event?
1) If your View is not 'a correct view' it will end up in an endless loop. Try this simple view:
public class SecuredView extends VerticalLayout implements View {
public SecureView() {
addComponent(new Label("Secured View"));
}
#Override
public void enter(ViewChangeEvent event) {
}
}
2) Your if statement needs to be changed:
instead of:
event.getNewView().getClass().isInstance(SecuredView.class)
write:
SecuredView.class.isInstance(event.getNewView());

Categories