MonoDroid OnBackPressed Not Working - android

It is definitely firing because I can for only a moment see the dialog pop up, but then the screen backs out anyway. How do I stop the back button from working? My device is on Gingerbread and my Min SDK is 10.
public override void OnBackPressed()
{
base.OnBackPressed();
TableLayout tl = (TableLayout)FindViewById(Resource.Id.myEquip);
int cnt = tl.ChildCount;
for (var i = 0; i < cnt; i++)
{
TableRow tr = (TableRow)tl.GetChildAt(i);
TextView tv = (TextView)tr.GetChildAt(0);
if (tv.Text != "Equipment not found at current store")
{
Dialog d = inst2.showBuilder(this, "test", tv.Text);
d.Show();
}
}
return;
}

You're calling base.OnBackPressed(), which is why you're still getting the default behavior. If you don't want the system to handle the back button, you shouldn't call that method. That said, in most cases you shouldn't be preventing the back button from working since that can be very weird for user experience. One example where it makes sense is if you were building a web browser: pressing back will go back to the previous page if there was one, and call base.OnBackPressed() if there are no more pages left.

Related

Question about CheckBox in Java in Android Studio

I am creating a project in Android Studio, in which there is a small home screen with a button. When a user clicks this button on the home screen, the application must go to another screen, which contains several checkboxes.
However, I am having two problems:
The code accesses the main page. But when you click on a button to go to another page, the application leaves the screen instead of going to another page. I already put the name of the method that is on another page, which I want you to execute, in the onclick attribute but it still doesn't work.
I would like that after a user clicks on a button that is on the home screen, opens a screen that contains several checkboxes (this screen is already made). Each check box contains a value. When a user clicks on a checkbox, I created a variable that adds up.
When the user clicks on the checkboxes the user wants, and after the user clicks the send button, the sum of the checkbox values ​​will appear in a textView.
This is the checkbox code:
int result = 0;
private CheckBox blue;
private CheckBox red;
private CheckBox yellow;
private CheckBox green;
private CheckBox black;
private CheckBox white;
private CheckBox orange;
private CheckBox purple;
private CheckBox gray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.id.interfacegraphicalname);
blue = findViewById(R.id.blue);
red = findViewById(R.id.red);
yellow = findViewById(R.id.yellow);
green = findViewById(R.id.green);
black = findViewById(R.id.black);
white = findViewById(R.id.white);
orange = findViewById(R.id.orange);
purple = findViewById(R.id.purple);
gray = findViewById(R.id.gray);
testFinalResult(result);
}
public void check() {
if (blue.isChecked()) {
result += 30;
} else if (red.isChecked()) {
result += 30;
} else if (green.isChecked()) {
result += 30;
} else ig (yellow.isChecked()) {
result += 20;
} else if (black.isChecked()) {
result += 20;
} else if (white.isChecked()) {
result +=20;
} else if (orange.isChecked()) {
result += 10;
} else if (purple.isChecked()) {
result += 10;
} else if (gray.isChecked()) {
result +=10;
}
int testResult = check();
public void finalTestResult(int testResult) {
if (testResult <= 60) {
finalResultText.setText("low value");
} else if (testResult <= 120) {
finalResultText.setText("medium value");
} else if (testResult<= 180) {
finalResultText.setText("high value");
}
}
}
But as the code contains one more error that when you click a button on the home screen, the application is not going to the next screen for some reason, I would like to show you all the code (which is too much big to insert here on Stack OverFlow) for you to check out what is going wrong, that I'm not able to run the code normally at all, ok?
Please, could you check?
I've been working on this project for a long time, and I'm not getting the code to run normally on the smartphone.
The code link is:
https://github.com/AvaianoFC1/OficialTestProject
/Checked out your code on github here is my initial findings
hopefully it will help you resolve your issue in your Calc.java class you need to setcontentview to entries layout instead of referring back to main layout*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
setContentView(R.layout.entries);
you are referring back to main activity layout which only has the layout for one button, so your button is working but its taking you back to activity main - you need to display entries layout and get all your values from that layout and then move ahead accordingly
another error from my inital lookup that i noticed is this
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/holo_blue_bright"
android:onClick="sendMessage2"
android:text="OPEN PAGE 2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.647"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.237" />
android:onClick="sendMessage2" -> you are calling the sendMessage2 function which you have not defined you need to call the openPage2 function
also you do not need the openPage1 and openPage2 in your main activity class
Let me know if this helps you these are the few errors that are flatout - also i would recommend adding a snackbar or a toast message on button click before implementing the functionality just to make sure thats its working as intended

100 Buttons and only 1 Active

I have one activity and here i have 100 buttons, i want that when i press Button 1 then press another Button the Button 1 should get unpressed.
i know i can make this with
if(Button1.isPressed()) {
Button2.setPressed(false);
Button3.setPressed(false);
Button4.setPressed(false);
Button5.setPressed(false);
Button6.setPressed(false);
Button7.setPressed(false);
Button8.setPressed(false);
......................... }
else { do nothing }
.... BUT!
it's too much code
Coders will kill me or will just laugh on me.
any ideas?
maybe there is a way to unpress the all buttons from the activity?
Not the prettiest solution ever, but you could make an OnClickListener like this:
View.OnClickListener listener = new View.OnClickListener() {
public void onClick(View v) {
ViewGroup parent = (ViewGroup) v.getParent();
for (int i = 0; i < parent.getChildCount(); i++) {
View current = parent.getChildAt(i);
if (current != v && current instanceof Button) {
((Button) current).setPressed(false);
}
}
((Button) v).setPressed(true);
}
}
and attach it to all of your buttons.
Then, whenever a button is clicked, it will iterate over all views that are in the same layout (or actually, view group) as the clicked button, and, for any of those views that are buttons except for the clicked button, it will call setPressed(false).
Note that this only works out of the box if all the buttons are in the same layout. If they are in nested layouts, you will have to adapt it a little.
Off topic: What do you need 100 buttons for? That's a lot of buttons. You may want to redesign your user interface
Ok so instead of looping through all the buttons on over and over again when one button is pressed, you can just store a variable which stores the button number of the button that was last pressed. Now, when the second button is pressed, disable the button that was pressed earlier, you get its index from the saved variable, enable the button that was pressed and store its index in the variable.
Heres an example pseudo code to give you and idea:
int buttonLastPressed = 0;
void onButtonClick(Button buttonPressed){
if(buttonLastPressed != 0){
disableButton(buttonLastPressed);
enableButton(buttonPressed);
buttonLastPressed = buttonPressed.getIndex()
}
}
Saves you from looping through each and every button to disable it.
Define id of button 1 to 100
When press button occurs save it's id in some member variable like previous_pressed
Before updating a previous_pressed value find and unpress previous pressed button like this
Button previous_pressed_button = (Button) findViewById(previous_pressed);
Now you have the previous pressed button, So upress it or whatever.

How to check if the current activity has a dialog in front?

I am using a third-party library and sometimes it pops up a dialog. Before I finish the current activity, I want to check whether there is a dialog popped up in the current context.
Is there any API for this?
You can check it running over the active fragments of that activity and checking if one of them is DialogFragment, meaning that there's a active dialog on the screen:
public static boolean hasOpenedDialogs(FragmentActivity activity) {
List<Fragment> fragments = activity.getSupportFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
if (fragment instanceof DialogFragment) {
return true;
}
}
}
return false;
}
I faced a similar problem, and did not want to modify all locations where dialogs were being created and shown. My solution was to look at whether the view I was showing had window focus via the hasWindowFocus() method. This will not work in all situations, but worked in my particular case (this was for an internal recording app used under fairly restricted circumstances).
This solution was not thoroughly tested for robustness but I figured I would post in in case it helped somebody.
This uses reflection and hidden APIs to get the currently active view roots. If an alert dialog shows this will return an additional view root. But careful as even a toast popup will return an additional view root.
I've confirmed compatibility from Android 4.1 to Android 6.0 but of course this may not work in earlier or later Android versions.
I've not checked the behavior for multi-window modes.
#SuppressWarnings("unchecked")
public static List<ViewParent> getViewRoots() {
List<ViewParent> viewRoots = new ArrayList<>();
try {
Object windowManager;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
windowManager = Class.forName("android.view.WindowManagerGlobal")
.getMethod("getInstance").invoke(null);
} else {
Field f = Class.forName("android.view.WindowManagerImpl")
.getDeclaredField("sWindowManager");
f.setAccessible(true);
windowManager = f.get(null);
}
Field rootsField = windowManager.getClass().getDeclaredField("mRoots");
rootsField.setAccessible(true);
Field stoppedField = Class.forName("android.view.ViewRootImpl")
.getDeclaredField("mStopped");
stoppedField.setAccessible(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
List<ViewParent> viewParents = (List<ViewParent>) rootsField.get(windowManager);
// Filter out inactive view roots
for (ViewParent viewParent : viewParents) {
boolean stopped = (boolean) stoppedField.get(viewParent);
if (!stopped) {
viewRoots.add(viewParent);
}
}
} else {
ViewParent[] viewParents = (ViewParent[]) rootsField.get(windowManager);
// Filter out inactive view roots
for (ViewParent viewParent : viewParents) {
boolean stopped = (boolean) stoppedField.get(viewParent);
if (!stopped) {
viewRoots.add(viewParent);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return viewRoots;
}
AFAIK - there is no public API for this.
Recommended way is to have a reference to the dialog, and check for isShowing() and call dismiss() if necessary, but since you're using a third party library, this may not be an options for you.
Your best bet is to check the documentation for the library you use. If that doesn't help, you're out of luck.
Hint: Activity switches to 'paused' state if a dialog pops up. You may be able to 'abuse' this behavior ;)
You can override activity method onWindowFocusChanged(boolean hasFocus) and track the state of your activity.
Normally, if some alert dialog is shown above your activity, the activity does not get onPause() and onResume() events. But it loses focus on alert dialog shown and gains it when it dismisses.
For anyone reading this and wondering how to detect a Dialog above fragment or activity, my problem was that inside my base fragment I wanted to detect if I'm displaying a Dialog on top of my fragment. The dialog itself was displayed from my activity and I didn't want to reach it there, so the solution I came up with (Thanks to all answers related to this kind of question) was to get the view (or you can get the view.rootView) of my fragment and check whether any of its children have the focus or not. If none of its children have no focus it means that there is something (hopefully a Dialog) being displayed above my fragment.
// Code inside my base fragment:
val dialogIsDisplayed = (view as ViewGroup).children.any { it.hasWindowFocus() }
Solution in kotlin
Inside Fragment
val hasWindowFocus = activity?.hasWindowFocus()
In Activity
val hasWindowFocus = hasWindowFocus()
If true, there is no Dialog in the foreground
if FALSE , there is a view/dialog in the foreground and has focus.
I am assuming, you are dealing with third party library and you don't have access to dialog object.
You can get the root view from the activity,
Then you can use tree traversal algorithm to see if you can reach any of the child view. You should not reach any of your child view if alert box is displayed.
When alert view is displayed ( check with Ui Automator ), the only element present in UI tree are from DialogBox / DialogActivity. You can use this trick to see if dialog is displayed on the screen. Though it sounds expensive, it could be optimized.
If you are using Kotlin just:
supportFragmentManager.fragments.any { it is DialogFragment }

Some alternative to hundreds of buttons

Im going to write some android app, which will basically consists of two activities. So first should have a lot of buttons (100+) and on click on any of them I will just get some special id and move to second activity. But is there any alternative to declare that hundreds of buttons and copy/paste one piece of code to every of them setting almost same onClickLister? Is there any special construction? Thanks
Edit: every of buttons are actually indexed from 1 to n. And on the click second activity will be launched and get that index to show it. I cant basically use any spinner or smth else, because there will be 3 rows of clickable things and each of them carring different images
Edit 2: so, to give you an idea, im going to do some table of buttons like in Angry Birds menu when you actually choosing the level you want to play. So, on click you will get id of button and start second activity
Call the method to add buttons
private void addButton(){
LinearLayout view = (LinearLayout) findViewById(R.id.linear_layout_id_here);
Button btn = null;
int w = 50;
int h = 25;
for(int i=1; i<100; i++) {
btn = new Button(this);
btn.setLayoutParams(new LayoutParams(w,h));
btn.setText("button " +i);
btn.setTag(""+i);
btn.setOnClickListener(onClickBtn);
view.addView(btn);
btn = null;
}
}
Call this method for handling onclick on button
private View.OnClickListener onClickBtn = new View.OnClickListener() {
public void onClick(View view) {
final int tag = Integer.parseInt(view.getTag().toString());
switch (tag) {
case 1:
// Do stuff
break;
case 2:
// Do stuff
break;
default:
break;
}
}
};
You should use a ListView.
ListViews are great for handling a lot of items at the same time. They are also natural for the user. Additionally, you use only one click listener - OnItemClickListener.
There's a useful example on how to work with ListViews in the Android Referenence.
You may add buttons in code, something like this:
#Override
public void onCreate(Bundle savedInstanceState) {
/*your code here*/
GroupView gw =findViewById(R.id.pnlButtonscontainer); //find the panel to add the buttons
for(int i=0; i<100; i++) {
Button b = new Button(this);
b.setLayoutParameters(new LayoutParameters(w,h));
b.settext = i+"";
b.setOnClickListener(new OnClickListener(){
});
}
}
I coded directly into browser, so some syntax error may appear in my code, but this is the point, a way, not the only one, to add 100 buttons.

Stopping a button being pressed whilst work being performed

I have a button on an activity which when pressed loops through a list of items, adds them to a database and then closes the activity.
My problem is that sometimes on slow phones and a lot of list items the user can press the button again before the activity closes, causing a duplicate insertion.
What is the recommended way of stopping this from happening, I've tried disabling the button on press but it does not get refreshed on the screen.
buttonAddChecked.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
SparseBooleanArray CheckedItemIDs = listViewFavorites.getCheckedItemPositions();
for (int i = 0; i < CheckedItemIDs.size(); i++) {
View element = listViewFavorites.getAdapter().getView(CheckedItemIDs.keyAt(i),
null, null);
ShoppingListItem sli;
sli = (ShoppingListItem) element.getTag();
db.insertItem(sli.itemName, 0, sli.itemNotes,
sli.categoryID);
} // looped round all checked items
finish();
}
});
use progressDialog
to stop user interaction once it presses the button.

Categories

Resources