Must be one of: View.VISIBLE, View.INVISIBLE, View.GONE [duplicate] - android

This question already has answers here:
Not able to dynamically set the setVisibility() parameter
(3 answers)
Closed 7 years ago.
I am saving and restoring a views visibility in one of my activities. I do this by calling mButton.getVisibility() and saving this in a Bundle. In onRestore where I get the int value it is showing an error.
Must be one of: View.VISIBLE, View.INVISIBLE, View.GONE less... (Ctrl+F1)
Reports two types of problems:
- Supplying the wrong type of resource identifier. For example, when calling Resources.getString(int id), you should be passing R.string.something, not R.drawable.something.
- Passing the wrong constant to a method which expects one of a specific set of constants. For example, when calling View#setLayoutDirection, the parameter must be android.view.View.LAYOUT_DIRECTION_LTR or android.view.View.LAYOUT_DIRECTION_RTL.
The code compiles and runs with no errors
code
#Override
public void onSaveInstanceState(#NonNull Bundle savedInstanceState) {
savedInstanceState.putInt("BUTTON_VISIBILITY", mButton.getVisibility());
super.onSaveInstanceState(savedInstanceState);
}
public void onRestoreInstanceState(#NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mButton.setVisibility(savedInstanceState.getInt("BUTTON_VISIBILITY"));
// savedInstanceState.getInt("BUTTON_VISIBILITY") is underlined red
}

As I have just commented, you can add #SuppressWarnings("ResourceType"). Hope this helps!
Alt-Enter

Related

Casting result of findViewById is redundant [duplicate]

This question already has answers here:
No need to cast the result of findViewById?
(6 answers)
Closed 5 years ago.
I'm new to Android and I'm working through some exercises on using various views. One such example is:
TextView messageView = (TextView) findViewById(R.id.message);
My question is this: what would be the benefit of casting TextView? My IDE tells me that casting the method is redundant. Are there any use cases where I would want to cast in this way?
Before API level 26, the method findViewById returned the reference of View class. So you needed to cast it.
//old signature
public View findViewById(int id){
//
}
But starting from API level 26, it has been updated and it returns subclass of View using template so that you can assign the returned reference without casting.
//new signature
public <T extends View > T findViewById(int id){
//
}
The example which you referred used the older API level while building the project, so you can see the casting there. It was compulsory earlier but is not necessary now. So you are getting the warning.

Android switching to layout-land [duplicate]

This question already has answers here:
Handle screen rotation without losing data - Android
(8 answers)
Closed 6 years ago.
I have activity_main.xml layout file and I created landscape layout file in "layout-land" directory. Obviously both files have the same names.
Landscape and main layouts work good, but when I move my phone to swich layout, all my textViews and editTextes changes to default values.
You have to save your information in a bundle and restore it during OnCreate().
https://developer.android.com/training/basics/activity-lifecycle/recreating.html
Every time you rotate your phone, configuration change happen and a new instance of your activity is created. That's why your Textview and Edittext are set to default values. However, if your views have id's set on them in the xml, then the values set on them will not be lost during a configuration change. If you don't want to set id then another way would be to save your Textview and Edittext values in onSaveInstanceState and restoring them in onRestoreInstanceState. For example to save your textview and edittext values follow the following code:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("arg1", textview1.getText());
outState.putString("arg2", edittext1.getText().toString());
......
}
To restore the saved values follow following code:
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
textview1.setText(savedInstanceState.getString("arg1"));
edittext1.setText(savedInstanceState.getString("arg2"));
......
}
You can read more about this here: https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en

Android: Keep screen on [duplicate]

This question already has answers here:
Correct method for setKeepScreenOn / FLAG_KEEP_SCREEN_ON
(5 answers)
Closed 9 years ago.
I try to set the screen to always on however I cant figure out how to do it within a fragment. I have tried to get access to the ViewPager but it returns with a null value. I want the screen to be on for the whole application but it should be able to be changed by the user within the settings of the app.
Here is my code from within my fragment:
private void setIsAlwaysOn(boolean b)
{
ViewPager pager = (ViewPager)getView().findViewById(R.id.pager);
pager.setKeepScreenOn(b);
sharePropertiesEditor.putBoolean(sp_alwaysOn, b);
sharePropertiesEditor.commit();
}
I get a nullpointerexception at line 4 of the visible code above.
Yeah. Can't you use this?
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
For Kotlin, use:
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

EditText not automatically saved on screen orientation change

I read that Android automatically saves the content of EditText objects when an application is about to be stopped or killed. However, in my app the content of an EditText is lost when screen orientation changes.
Is it normal behaviour? Do I then have to manually save/restore its content with onSaveInstanceState/onRestoreInstanceState? Or is there an easier method to tell Android to save it end restore it?
Edit:
I create the EditText object programmatically, not in XML. This turns out to be related to the problem (see accepted answer below).
This is not normal behavior.
First and foremost, ensure that you have IDs assigned to your EditText controls in the layout XML.
Edit 1: It just needs an ID, period. If you're doing this programmatically, it will lose state unless it has an ID.
So using this as a quick & dirty example:
// Find my layout
LinearLayout mLinearLayout = (LinearLayout) findViewById(R.id.ll1);
// Add a new EditText with default text of "test"
EditText testText = new EditText(this.getApplicationContext());
testText.setText("test");
// This line is the key; without it, any additional text changes will
// be lost on rotation. Try it with and without the setId, text will revert
// to just "test" when you rotate.
testText.setId(100);
// Add your new EditText to the view.
mLinearLayout.addView(testText);
That will solve your problem.
Should that fail, you'll need to save and restore state yourself.
Override onSaveInstanceState like so:
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("textKey", mEditText.getText().toString());
}
And then restore in OnCreate:
public void onCreate(Bundle savedInstanceState) {
if(savedInstanceState != null)
{
mEditText.setText(savedInstanceState.getString("textKey"));
}
}
Also, please don't use android:configChanges="orientation" to try to accomplish this, it's the wrong way to go.
could you use android:freezesText="true" in the xml layout?
The easiest way I found to save an object on onSaveInstanceState is to implement serializable and put in bundle
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("myObj", myObj);
}
where myObj class implements serializable and in onCreate() method
if (savedInstanceState != null && savedInstanceState.getSerializable("myObj") != null) {
myObj = ((MyObj) savedInstanceState.getSerializable("myObj"));
}
One possible cause is that you override onSaveInstanceState but you forget to call the same for super class
super.onSaveInstanceState(outState);
State of all views in activity is auto saved UNLESS you override this functionality. Even if this is obvious, mistakes are possible.
You just need UNIQUE ID for the edit text. Make sure if you dynamically add edit text, chances of having same id can cause not restoring the text.
Same way if you add in xml, use unique id. Hope it will help someone.
FYI: EditText by default having setFreezesText as true

Android: Better way of using Fragments

I couldn't think of a better question title :(
In my application I need to have a questioner like thing with 10+ questions, 1 question each time.
What I did is:
Have 1 Activity say MainActivity, in its onCreate() programatically add a Fragment say Frag_1
In Frag_1 i have an Interface onButtonClickedListener with a method onClicked to get a call back to the Activity to know which option is clicked etc..,
Implemented the method onClicked of this Interface in my MainActivity and in that Method i changed the Fragment to Frag_2 (2nd question) and so on.
The problem is:
I ended up having 10 Fragments and my MainActivity implements 10 interfaces 1 each of these Fragments. In future I may have 30-40 question.
Edit:
Every question will not be similar. Answer options for questions are EditText/Spinner/RadioButtons etc.., so i cannot use the same Fragment and just change the Question and Answer options Text.
Is there a better and more efficient way to approach this
Thank You
You're almost there.
Make a more broad/generic interface for the MainActivity to implement.
Maybe something like that public void fragClickCallback(int fragId, Bundle data);
that way on you implementation you can make a switch() case to know which question is from and your bundle can pack different keys for different types of answers (int for radion button/spinners, String for open answer, etc).
And mare sure that on every fragment transaction you use .replace(...) to remove the fragment before.
edit
furthermore, there are some clever ways you can built your fragments to not have to create billions of them. How many different types of questions there can be? let's count:
multiple choice (single answer) -> integer (index)
multiple choice (multiple answers) -> integer (flags)
Number input -> float/double
Edit Text -> String
Date Picker -> long (epoch)
time picker -> 3 integers(?)
so we have 6 fragments and 6 ways of handling the switch statement, now it's just pass the right parameters to the fragments
edit:
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("curChoice", mCurCheckPosition);
}
and then on your Fragment ActivityCreated()
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
// Restore last state for checked position.
mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
}
}
those code was copied from http://developer.android.com/reference/android/app/Fragment.html I suggest you further reading that page.
That example is restoring a cursor position, but you can use it to restore your previous user answers (text, integer, float, whatever).

Categories

Resources