I have a spinner that has numbers from 1 - 10. If the user selects anything above 1, a certain EditText that is INVISBLE becomes VISIBLE, this is what I want. But when I change it from portrait to landscape, it goes back to INVISIBLE.
This is where the changing happens
btn_Calc.setOnClickListener(new View.OnClickListener() {
#Override
if (split > 1) {
et_APP.setVisibility(View.VISIBLE);
tv_app.setVisibility(View.VISIBLE);
vis = 1;
}
else{
et_APP.setVisibility(View.INVISIBLE);
tv_app.setVisibility(View.INVISIBLE);
vis = 2;
}
});
And I tried to do onSaveInstanceState like this
if(savedInstanceState != null) {
int isVis = savedInstanceState.getInt("vis", 2);
if(isVis == 1){
et_APP.setVisibility(View.VISIBLE);
tv_app.setVisibility(View.VISIBLE);
}
else{
et_APP.setVisibility(View.INVISIBLE);
tv_app.setVisibility(View.INVISIBLE);
}
}
public void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("getVisible", vis);
}
Sorry for poor formatting, I cut out unrelated code.
It works that if the selected item in the spinner is greater than 1 and I click the calc button, it shows the fields I want but when I change orientation they dissapear again. Any ideas on how I can get to stay visible when I change the orientation?
The names of your keys don't match between save and load.
Saving:
savedInstanceState.putInt("getVisible", vis);
Restoring:
int isVis = savedInstanceState.getInt("vis", 2);
The layout is being recreated if you don't want Android to do anything add the following line:`android:configChanges="keyboardHidden|orientation|screenSize"' to the activity in the manifest.
Related
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
I'm Making simple app for project
That App contains lot of text so i want,
"when a button is pressed, text should Change in same layout"
like PowerPoint slide.
I want change text only not scroll.
Now i made my app, have lots of Windows or Layouts.
It is not looking good, too much layout in simple app so please help me .
Thanks in advance
Doing this is very easy, I will quickly walk you through the Algorithm:
Set a class level variable called as FLAG initialize it to 1.
Let us assume that FLAG = 1 will represent the first slide. FLAG = 2 the second slide and so on.
Now in your button click you can use a switch case or an if else condition, based on the value of the flag display the relevant text in textview.
Once done, increment the flag, for the next set of sentence(s).
Class level:
int FLAG = 1;
onCreate:
Initialize your textView:
TextView mtv = (TextView)findViewById(R.id.yourid);
Set a button click listener:
private View.OnClickListener slides = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(FLAG ==1)
mtv.setText("First slide");
else if(FLAG ==2)
mtv.setText("Second Slide");
//and so on...
FLAG = FLAG+1;//increment flag
}
};
What is so special about Edittext that it can retain the value but not Textview and some other widgets and we have to use onSavedInstance() method for them.
What is the magic behind EditText specially that it can retain the values?
If someone can tell how it works internally.
<----Update---->
How it works internally, Please point to that part of the code which explains this scenario.
What is the magic behind EditText specially that it can retain the
values? How it works internally, Please point to that part of the code
which explains this scenario.
It is the selectable property which brings the difference. The following if condition in TextView.onSaveInstanceState takes care of it.
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
// Save state if we are forced to
boolean save = mFreezesText;
int start = 0;
int end = 0;
if (mText != null) {
start = getSelectionStart();
end = getSelectionEnd();
if (start >= 0 || end >= 0) {
// Or save state if there is a selection
save = true;
}
}
...
}
By default TextView can't be selected. Hence getSelectionStart() and getSelectionEnd() returns -1, there by save variable holds false value. To make it retain it's content on orientation change, set the attribute textIsSelectable to true.
Since EditText is selectable by default, getSelectionStart() and getSelectionEnd() always return value >=0, there by save variable holds true value and the content gets saved.
Note : By default freezesText is disabled. Hence mFreezesText value is false.
By default, EditText view saves its state - This is accomplished by setting flags in code telling the view to save state when view is not visible or lost focus. The text is automatically saved and restored after rotating device. The automatic saving of state of EditText view can be disabled in the XML layout file by setting the android:saveEnabled property to false:
android:saveEnabled="false"
Or programmatically, call view.setSaveEnabled(false).
saveEnabled controls whether the saving of this view's state is enabled (that is, whether its onSaveInstanceState() method will be called). Note that even if freezing is enabled, the view still must have an id assigned to it (via setId()) for its state to be saved. This flag can only disable the saving of this view; any child views may still have their state saved. saveEnabled attribute is part of android View - View Code. Here is related parts of code:
public boolean isSaveEnabled() {
return (mViewFlags & SAVE_DISABLED_MASK) != SAVE_DISABLED;
}
...
public void setSaveEnabled(boolean enabled) {
setFlags(enabled ? 0 : SAVE_DISABLED, SAVE_DISABLED_MASK);
}
...
void setFlags(int flags, int mask) {
int old = mViewFlags;
mViewFlags = (mViewFlags & ~mask) | (flags & mask);
int changed = mViewFlags ^ old;
if (changed == 0) {
return;
}
int privateFlags = mPrivateFlags;
/* Check if the FOCUSABLE bit has changed */
if (((changed & FOCUSABLE_MASK) != 0) &&
((privateFlags & HAS_BOUNDS) !=0)) {
if (((old & FOCUSABLE_MASK) == FOCUSABLE)
&& ((privateFlags & FOCUSED) != 0)) {
/* Give up focus if we are no longer focusable */
clearFocus();
} else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE)
&& ((privateFlags & FOCUSED) == 0)) {
/*
* Tell the view system that we are now available to take focus
* if no one else already has it.
*/
if (mParent != null) mParent.focusableViewAvailable(this);
}
}
....
Quoting from this article:https://tekeye.uk/android/examples/saving-activity-state
"Switching the device from portrait to landscape causes Android to stop and restart the Activity, allowing Activities the opportunity to redraw a screen for the different dimensions. With stopping and starting an Activity a common occurrence users would be annoyed if input kept being lost. Android activites have a pair of methods called onSaveInstanceState(Bundle) and onRestoreInstanceState(Bundle) which are automatically used by input Views to save their data. These methods only work if the Views that take data can be identified, hence the need for the EditText (and all screen items) to have an id. A bonus is that this method pair can be overridden in an Activity so that state variables not associated with input fields can also be saved and restored."
Remove the id from an edittext and try it :)
Try this for your textview I think it may help you
<TextView
...
android:freezesText="true" />
Android View class have protected methods
protected Parcelable onSaveInstanceState ()
protected void onRestoreInstanceState (Parcelable state)
so any view can override those methods and save View's state information with them.
TextView extends View class and have implementation of protected Parcelable onSaveInstanceState() and protected void onRestoreInstanceState (Parcelable state) within it.
lets look at implementation of onSaveInstanceState()
#Override
public Parcelable onSaveInstanceState()
{
Parcelable superState = super.onSaveInstanceState();
// Save state if we are forced to
boolean save = mFreezesText;
int start = 0;
int end = 0;
if (mText != null)
{
start = getSelectionStart();
end = getSelectionEnd();
if (start >= 0 || end >= 0)
{
// Or save state if there is a selection
save = true;
}
}
...
}
as you can see here save feature is depending on single flag "save"
so if user explicitly specify mFreezesText = true then it will save
the text
another possiblity if there is selection cursor then it will at least return getSelectionStart() = 0 and not -1 that will cause TextView to make save=true to save state of TextView and thats what happening with EditText as EditText have selection cursor and it does extends TextView.
What my application first does is it loads ListView whose items have invisible CheckBoxes by setting its visibility View.Gone. When the user tabs a menu button then it will turn on and off the CheckBox visibility and some other layouts. Below is the code, I removed some unnecessary parts:
private void editmodeSwitch(boolean flag){
// get topbar, bottombar, and bottombar2
LinearLayout topbar = (LinearLayout) findViewById(R.id.task_topbar_linearLayout);
LinearLayout bottombar = (LinearLayout) findViewById(R.id.task_bottombar1_linearlayout);
LinearLayout bottombar2 = (LinearLayout) findViewById(R.id.task_bottombar2_linearlayout);
if(flag){
isEditmodeOn = true;
// make topbar and bottombar2 visilble, but bottombar gone
topbar.setVisibility(View.VISIBLE);
bottombar.setVisibility(View.GONE);
bottombar2.setVisibility(View.VISIBLE);
// make checkboxes visible in listview visible as well
for(int i=0; i<listView.getChildCount(); i++){
LinearLayout ll = (LinearLayout) listView.getChildAt(i);
CheckBox cb = (CheckBox) ll.findViewById(R.id.task_row_checkBox1);
cb.setVisibility(View.VISIBLE);
}
}
else{
isEditmodeOn = false;
topbar.setVisibility(View.GONE);
bottombar.setVisibility(View.VISIBLE);
bottombar2.setVisibility(View.GONE);
// set each checkbox false and its visibility gone
for(int i=0; i<listView.getChildCount(); i++){
LinearLayout ll = (LinearLayout) listView.getChildAt(i);
CheckBox cb = (CheckBox) ll.findViewById(R.id.task_row_checkBox1);
cb.setVisibility(View.GONE);
cb.setChecked(false);
}
}
}
It works fine but the problem is the application doesn't work when the screen rotates(changes the screen orientation). Everything worked fine as it displayed some layouts but only CheckBoxes in list items. Below is the code inonCreate()`:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.task_layout);
initialize();
loadDB();
updateListAdapter(list_title, list_date);
// in case of screen rotation
if(savedInstanceState != null){
isEditmodeOn = savedInstanceState.getBoolean(EDITMODE_CHECK);
isItemChecked = savedInstanceState.getBoolean(ITEM_CHECK);
if(isEditmodeOn){
if(!isItemChecked){
Log.i(tag, "item NOT checked");
editmodeSwitch(true);
} else{
//this is something different so please don't mind
deditmodeSwitch(savedInstanceState.getBooleanArray(LIST_CB_CHECK));
}
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save values for rotation
outState.putBoolean(EDITMODE_CHECK, isEditmodeOn);
outState.putBoolean(ITEM_CHECK, isItemChecked);
outState.putBooleanArray(LIST_CB_CHECK, list_cb_check);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Log.i(tag, "you're in onRestoreInstanceState()");
// in case of screen rotation
if(savedInstanceState != null){
isEditmodeOn = savedInstanceState.getBoolean(EDITMODE_CHECK);
isItemChecked = savedInstanceState.getBoolean(ITEM_CHECK);
if(isEditmodeOn){
if(!isItemChecked){
Log.i(tag, "item NOT checked");
editmodeSwitch(true);
} else{
// this is for something else so please ignore this part
editmodeSwitch(savedInstanceState.getBooleanArray(LIST_CB_CHECK));
}
}
}
What I guessed is the ListView is being loaded at the end. Therefore, even if the code in onCreate() makes CheckBoxes visible, the CheckBoxes will become invisible again as its initialization in xml will do so. However, I'm stuck here and need your advice to solve this problem. Can anyone help me?
Just in case, below is the checkbox code of layout xml file for getview.
<CheckBox android:id="#+id/task_row_checkBox1" android:gravity="right"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:visibility="gone"
/>
Override onSaveInstanceState for saving value on screen rotation and onRestoreInstanceState as:
protected void onCreate(Bundle savedInstanceState) {
if(null != savedInstanceState)
{
Boolean IntTest = savedInstanceState.getBoolean("ITEM_CHECK");
Boolean StrTest = savedInstanceState.getBoolean("ITEM_CHECK");
Log.e(TAG, "onCreate get the savedInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save away the CheckBoxes states, so we still have it if the activity
// needs to be killed while paused.
savedInstanceState.putBoolean(EDITMODE_CHECK, 0);
savedInstanceState.putBoolean(ITEM_CHECK, 0);
super.onSaveInstanceState(savedInstanceState);
Log.e(TAG, "onSaveInstanceState");
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Boolean IntTest = savedInstanceState.getBoolean(EDITMODE_CHECK);
Boolean StrTest = savedInstanceState.getBoolean(ITEM_CHECK);
Log.e(TAG, "onRestoreInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);
}
Similar to how you override onCreate, you can override onConfigurationChanged(...) which you can setup to run when the screen changes orientation.
In order for OnConfigurationChanged(...) to be trigger when the screen rotates, you need to to edit your manifest and put that relationship/rule in.
It's easy to do but takes a bit of explaining and it was answered before in this question:
Activity restart on rotation Android
Edit: Here is the dev guide on how to handle configuration changes
http://developer.android.com/guide/topics/resources/runtime-changes.html
Edit #2: First, let me suggest using Imran's solution. It follows the Developer Guide better and the end results will be the same.
Now, for the onConfigurationChanged solution.
Look at what you are doing with your onCreate:
1) Set the view. (Checkboxes are hidden at this point. Right?)
2) Call your DB and determine if you should display checkboxes (edit mode)
3) Make all the checkboxes visible.
Now, onConfigurationChanged also calls setContentView, at which point all your checkboxes are hidden again. So you need to repeat the process of making your checkboxes visible (#3 above). You probably don't need to repeat step #2 because the value should be retained, but I'm not sure how the logic of your app works, so you may need to re-do step #2.
Does that make sense?
Based on my experience, getview seems to be triggered at the end and it was why 'onRestoreInstanceState()' and 'onConfigurationChanged()' could not make it as getview will reset my checkboxes invisible as initialization in the layout xml file.
Therefore, the only solution I could find out was I must control them in getview for the answer.
Here's my MAIN ACTIVITY
public static boolean popupStatus=false;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (savedInstanceState != null){
popupStatus = savedInstanceState.getBoolean("Open");
}
setContentView(R.layout.main);
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean("Open", DateTimePicker.openPopup);
super.onSaveInstanceState(savedInstanceState);
}
I have DateTimePicker.java class which has 1 button and 1 Textview. Clicking on button, my another class Calendar.java get populated in PopupWindow and this Popup window displays my class Calendar.java . I have created different layouts of my Calendar.java class for portrait and landscape mode. Here's DateTimePicker.java some snippet of code,
public static boolean openPopup = false;
textView = new TextView(this.getContext());
this.addView(textView, layoutParams);
button = new Button(this.getContext());
button.setText("C");
this.addView(button, layoutParams1);
button.setOnClickListener(this);
if(Main.popupStatus){
button.performClick();
}
public void onClick(View v) {
if(Main.popupStatus){
new Handler().postDelayed(new Runnable() {
public void run() {
openCalendar();
}
}, 100);
}
else{
openCalendar();
}
private void openCalendar() {
Calendar calendar = new Calendar(this.getContext());
if(portrait.equals(orientation)){
pw = new PopupWindow(calendarLayout, 245, 284, true);
}
else{
pw = new PopupWindow(calendarLayout, 295, 240, true);
}
pw.setOutsideTouchable(false);
pw.showAtLocation(this, Gravity.NO_GRAVITY, 10, 80);
openPopup = true;
}
public void closeCalendar(){
pw.dismiss();
openPopup = false;
}
Main.XML contain DateTimePicker .
Actually I wanted my Popup window to be opened up even when orientation gets changed at run time, so I have done it through setting flag openPopup = true; in openCalendar() method and if it is opened and orientation gets changed at run time, this flag will be saved in onSaveInstanceState() method. After orientation will change, it will be checked in onCreate() and popup will be opened up for respective orientation mode. I hope you got my point.
PROBLEM: Initially When I click on button in Portrait mode, popup window pops up for portrait layout. then without dismissing popup window, I change the orientation to landscape. And after changing, I can see my popup window as intact and appears on screen of landscape layout. Till now it works fine. But IF popup window is opened up in landscape mode and then I change the orientation to portrait, popup window of portrait layout didn't come up and I see FORCE CLOSE message:/ Please help since I am working behind it so long and getting no clue. I would be very grateful to you all. Thanks!
P.S.: Changing orientation means I am pressing ctrl+F11 and changing orientation of Emulator
The emulator has an odd feature (some consider it a bug) in which changing from landscape to portrait in the emulator causes two configuration changes and two restarts of your activity. (One configuration change is the orientation and the other is an emulated change in the keyboard state.) The timing of the configuration changes frequently causes crashes like this. Try adding this attribute:
android:configChanges="keyboard|keyboardHidden"
to your <activity> tag in the manifest. See if that improves the situation.
Make sure you have your layout defined in layout-land folder and ensure onCreate is not called again and again. android:configChanges="keyboard|keyboardHidden" Put this in your manifest file so that the state is retained when you change orientation