Saving TextView's settings on Orientation Changes - Android? - 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");
}

Related

Unable to set ImageResource of Button after orientation change

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.

Styled text lost in Android IME

I'm developing an IME for Android, which includes some highlighting of the text input by the user with a background colour (using SpannableString).
When the device is rotated and the keyboard is redrawn, the text remains in the input box as entered by the user, however, all styling (i.e. background colour) is lost.
Any ideas why this might be happening and how to circumvent it?
I have found a solution, which is not perfect, but it works.
Set up an ExtractedText variable in the IME service class.
In the OnConfigurationChanged method, get the extracted text. Then in the onStartInputView method, delete the text in the bound editor, and replace it with the extracted text.
#Override
public void onConfigurationChanged (Configuration newConfig)
{
//get what's been input so far
ExtractedTextRequest req = new ExtractedTextRequest();
req.token = 0;
req.flags = InputConnection.GET_TEXT_WITH_STYLES;
extractedText = ic.getExtractedText(req, 0);
super.onConfigurationChanged(newConfig);
}
#Override public void onStartInputView(EditorInfo attribute, boolean restarting) {
...
if(extractedText!=null)
{
if(ic.deleteSurroundingText(9999, 0))
{
ic.commitText(extractedText.text, 1);
Log.i("onStartInputView", "Text Replaced");
}
else
{
Log.i("onStartInputView", "IC not valid");
}
}
super.onStartInputView(attribute, restarting);
}

Application label font not preserved on orientation change

I am not able to preserve the font for my application label on screen orientation change. Currently I am setting the font using the below code in the onCreate method of SherlockFragmentActivity.
titleId = Resources.getSystem().getIdentifier("action_bar_title", "id", "android");
if(titleId == 0)
titleId = com.actionbarsherlock.R.id.abs__action_bar_title;
mAppName = (TextView) findViewById(titleId);
Typeface face = Typeface.createFromAsset(getAssets(), "fonts/handsean.ttf");
mAppName.setTypeface(face);
On Orientation change the font reverts back to the default. I tried preserving state using manifest.xml but it didnot help. it preserves everything except the label font. Can someone suggest how this can be done ?
Thanks for stopping by and reading this post.
Did you tried setting android:configChanges="orientation" and handling the orientation change with onConfigurationChanged()?
edit: also explained here why it's not functioning.
**Yes we can do this.
Override onConfigurationChanged
set the action bar title inside a handler with a delay of 200.**
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//your code to set the action bar title
setActionBarTitle(title);
}
}, 200);
}

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?

CheckBoxes in ListView disappear when the screen rotates

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.

Categories

Resources