Unable to set ImageResource of Button after orientation change - android

the aim is to change the image resource of the button. If I don't change the orientation it works correctly, but if I change the orientation, the image resource is not set (or probably not updated).
I observe in DebugMode that the following code (toggleButton method) is always executed, regardless the screen orientation is changed. The buttonIconID is also always correct. The problem is, that the image resource of the button is not set after changing the orientation.
#Override
public void onCreate(Bundle savedInstanceState) {
...
mTopBar = new TopBar(this);
...
}
TopBar constructor:
public TopBar(MainActivity mainActivity) {
this.mainActivity = mainActivity;
mButton = (ImageButton) mainActivity
.findViewById(R.id.toggleButton);
mButton.setOnTouchListener(this);
...
}
toggleButton method in TopBar:
public void toggleButton(final int buttonIconID) {
mainActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
mButton.setImageResource(buttonIconID);
}
});
}
Thanks for your help!

An Activity is recreated every time you change the orientation. So when you change the orientation all views are reseted to their standard configuration (or the settings you have set in the onCreate()/onResume() etc methods.
So if you want to keep the image resource you have set programmatically after changing the orientation, you should buffer the data and set it again in the onCreate() or onResume() method.

Related

How to use a Drawable in If/else statement for setImageResource?

I'm new at androidstudio and want to compare a imageView by the following:
I have 2 imageView, both are using a drawable i named "blank" at the start of the app, using if/else I want to chance those images to another drawable i have, i tried the following:
private ImageView equipament1;
private ImageView equipament2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_analise)
equipament1 = findViewById(R.id.equipamento1);
equipament2 = findViewById(R.id.equipamento2);
public void sentImg() {
if (equipament1.equals(R.drawable.blank)){
equipament1.setImageResource(R.drawable.reactor);
}
else if (equipament2.equals(R.drawable.blank)){
equipament2.setImageResource(R.drawable.reactor);
} else {finish();}
but it doesn't work, the app just replaces the first image and if i click on the button again, nothing happens (this if/else is inside a button).
I want to check if the first image is blank, if it is, the app should replace the blank image with the image "reactor" or, if is not blank, the app should move to the second blank image, and replace it and this go on for more 2 blank spaces.
I'm doing this because I'm building an program similar to LucidChart where you put your equipments in the app.
The problem is that the second time you have already changed the value of the comparator.
If the objective is just to change the images you don't need the if/else.
private ImageView equipament1;
private ImageView equipament2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_analise)
equipament1 = findViewById(R.id.equipamento1);
equipament2 = findViewById(R.id.equipamento2);
public void sentImg() {
equipament1.setImageResource(R.drawable.reactor);
equipament2.setImageResource(R.drawable.reactor);
}
When the user clicks your button, you want to do 2 things. You want to show some images, or you want to call finish().
I would suggest using a boolean as a flag the the state and compare that instead of comparing the ImageView itself. This'll be easier, and make your code easier to read.
I created a flag called firstClick that is set to true by default. When the user clicks your button (button1 in this example), we check against that and show the images. Then we set it to false,
so the next click will call finish().
private ImageView equipament1;
private ImageView equipament2;
// The current state of the Activity
private boolean firstClick = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_analise)
equipament1 = findViewById(R.id.equipamento1);
equipament2 = findViewById(R.id.equipamento2);
// Setting your OnClickListener
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if( firstClick ) {
firstClick = false;
sentImg();
} else {
finish();
}
}
});
}
public void sentImg() {
equipament1.setImageResource(R.drawable.reactor);
equipament2.setImageResource(R.drawable.reactor);
}

Refresh android ImageButton after rotation

I have an ImageButton in my fragment which has its background set to an android drawable icon. In some cases that button needs to be rotated (this works). My problem is that when I come back to the fragment after being in another activity then I want the button to be "reset" to its original position.
Here is how the button is set:
#Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
button = (ImageButton)view.findViewById(R.id.doButtonThing);
button.setOnClickListener(this);
if (condition) {
button.animate().rotation(90f).setInterpolator(new AccelerateDecelerateInterpolator());
}
}
I have tried using:
button.clearAnimation();
button.invalidate();
button.postInvalidate();
inside the onResume() method but none of them work. How can I reset/reload the original button?
The code of clearAnimation()
/**
* Cancels any animations for this view.
*/
public void clearAnimation() {
if (mCurrentAnimation != null) {
mCurrentAnimation.detach();
}
mCurrentAnimation = null;
invalidateParentIfNeeded();
}
which gives me the impression that it clears a currently running animation (Although I'm not sure). Instead of button.clearAnimation();, you can use button.animate().rotation(0.0f); to reverse-rotate the button.
Also instead of onResume(), I suggest you to call the function later on, maybe onStop(). In the lifecycle, onResume() comes after onViewCreated(final View view, Bundle savedInstanceState), calling it in onResume() would invalidate your animation.

Saving TextView's settings on Orientation Changes - Android?

I'm dynamically setting the Background color and text color of a textview component in my app, using a single options menu button "toggle color"
The problem is, as soon as the orientation changes the textview "forgets" what colors it was supposed to use...so it uses default and not those that were set by the options menu.
Here's the original function of the options menu option :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
TextView textView = (TextView) findViewById(R.id.xxtt);
if (Cflag) {
textView.setBackgroundColor(Color.parseColor("#ffffff"));
textView.setTextColor(Color.parseColor("#000000"));
Cflag= false;
} else {
textView.setBackgroundColor(Color.parseColor("#000000"));
textView.setTextColor(Color.parseColor("#ffffff"));
Cflag= true;
}
return super.onOptionsItemSelected(item);
}
^Cflag is "global" boolean, depending on whether true/false the function sets the textviews color. (If it's black on white, it sets it to white text on black background...and vice-versa)
After doing a little research, Here are the extra functions I modified :
Since on orientation change, the app pauses and resumes, I modified onResume to independently change the color according to the variable Cflag.
And also the OnCofigChange, to update the colors if and when the orientation changes. I've tried using both these functions , and I've tried using them one at a time. Nothing helped.
#Override
protected void onResume() {
TextView textView = (TextView) findViewById(R.id.xxtt);
if (Cflag) {
textView.setBackgroundColor(Color.parseColor("#ffffff"));
textView.setTextColor(Color.parseColor("#000000"));
} else {
textView.setBackgroundColor(Color.parseColor("#000000"));
textView.setTextColor(Color.parseColor("#ffffff"));
}
super.onResume();
}
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
TextView textView = (TextView) findViewById(R.id.xxtt);
if (Cflag) {
textView.setBackgroundColor(Color.parseColor("#ffffff"));
textView.setTextColor(Color.parseColor("#000000"));
} else {
textView.setBackgroundColor(Color.parseColor("#000000"));
textView.setTextColor(Color.parseColor("#ffffff"));
}
}
I don't want to unnecessarily use a SharedPreferences object.
I reckon it's a matter of logic only,
If it's black text on white background(default) .... Press the option menu's option, It toggles to white text on black background .... Cflag variable is also toggled.
Now Cflag is constant, we just have to set the text color again according to Cflag.
But I can't get it to work: I change the settings in one orientation, and on switching orientation it goes back to default state(The one I defined in XML, black text on white background..)
What's wrong?
Thank you !
Save them in bundle
#Override
protected void onSaveInstanceState (Bundle outState) {
outState.putBoolean("CFLAG",CFlag);
}
and it will be restored in Activity onCreate.
#Override
protected void onCreate (Bundle savedInstanceState) {
CFlag = savedInstanceState.getBoolean("CFLAG");
}

only change layout color while orientation change android

I have create dialog box which will be displayed first when i start application (which is coded in onCreate method ) and then question and answer will be displayed on textview
so to solve problem of orientation (so dialog box again not displayed when orientation change) i have used Manifest with:
android:configChanges="keyboardHidden|orientation"
I have res/layout-land, res/layout-port
but to change only COLOR of background
I have used onConfigurationChanged in my Activity (it get's called on rotation).
so now when orientation change the dialog box will not appear again and background is redrawn but the question and answer which is initialized on onCreate() will not display
so how to maintain
Using android:configChanges="keyboardHidden|orientation" means that your activity handles a configuration change itself, and the system will not change the layout.. take a lokk at http://developer.android.com/guide/topics/resources/runtime-changes.html
To reset the text view, in case of not using android:configChanges="keyboardHidden|orientation":
#Override
public Object onRetainNonConfigurationInstance() {
final MyDataObject data = collectMyLoadedData();
//here get the text from the text view, and any other info
return data;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();
if (data != null) {
//get the text and set it in the text view
}
}
When you change the orientation of the devide, android continue the execution without calling onCreate again, but if you put the code in onResume, this code will executed again.
In OnCreate add for your main layout as
LinearLayout lv=(LinearLayout)findViewById(R.id.mainlayout);
lv.setBackgroundColor(android.R.color.black); // for default potrait or landscape view and after that add this in that activity
#Override
public void onConfigurationChanged(Configuration newConfig) {
Configuration c = getResources().getConfiguration();
if(c.orientation == Configuration.ORIENTATION_PORTRAIT ) {
// portrait
lv.setBackgroundColor(android.R.color.black);
} else if(c.orientation == Configuration.ORIENTATION_LANDSCAPE ){
// landscape
lv.setBackgroundColor(android.R.color.white);
}
}
and also add this in menifest in your activity defined
android:configChanges="keyboardHidden|orientation"
Did you use onSaveInstanceState to save the data and onRestoreInstanceState for retriving the data?
If you have done this then you can display the same dialog box in onRestoreInstanceState.
Well I have a question for you. How did you kept the background color unchanged when changing the orientations? And what to do if the color is unknown or a random color?

Force Close of Android Popupwindow when changing orientation to portrait at run time, why?

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

Categories

Resources