Android toggle button display wrong value after orientation change - android

Here is my problem.
I've got a simple activity which set a layout, and add rows in a table-layout(itself in a scroll view).
Those table-rows have a custom layout with a text-field and a toggle button.
Each toggle button has a value taken from a database, and when I first create the activity, the values are OK. But when I turn the device and then change the orientation, all the toggles-button take "false" value. I printed the values that I set in the Logcat, and the values are the good ones (those in the database).
I thought something like the layout I want is hidden behind another layout, but I made some tests and the text-fields change with new values, so I really don't understand why the toggle buttons don't work.
Here is the code :
TableRow layout :
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<RelativeLayout
android:id="#+id/relativelayout_row_parametres"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_weight="1.0">
<TextView
android:id="#+id/textview_row_parametres"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/black"
android:textStyle="bold"
android:textSize="20sp"
android:layout_marginLeft="2dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
/>
<ToggleButton
android:id="#+id/togglebutton_row_parametres"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="2dp"
android:textOn="#string/togglebutton_on"
android:textOff="#string/togglebutton_off" />
</RelativeLayout>
</TableRow>
Activity Layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ImageView style="#style/header" />
<LinearLayout
android:layout_width="fill_parent" android:layout_height="0dp"
android:layout_weight="0.8"
android:background="#drawable/gradient_bg"
android:padding="10dip"
android:orientation="vertical">
<ScrollView
android:layout_width="fill_parent" android:layout_height="0dp"
android:layout_weight="0.85"
android:fillViewport="true"
android:padding="10dip"
android:layout_gravity="center">
<TableLayout
android:id="#+id/tablelayout_parametres"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/cornered_bg"
android:paddingTop="5dip"
android:paddingBottom="5dip">
</TableLayout>
</ScrollView>
<Button
android:id="#+id/button_parametres_accept"
android:gravity="center"
android:text="#string/accept_changes"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="0.15"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</LinearLayout>
And the activity code:
public class Parameters extends Activity {
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Map<String, Boolean> changes = new HashMap<String, Boolean>();
final Context ctx = getApplicationContext();
LanguageManager.updateConfig(this);
setContentView(R.layout.parametres);
CountryDB[] countries = Database.instance(getApplicationContext()).getCountries();
TableLayout tabLayout = (TableLayout) findViewById(R.id.tablelayout_parametres);
for(int i =0; i<countries.length; i++){
TableRow newRow = (TableRow) getLayoutInflater().inflate(R.layout.row_parametres, null);
TextView textView = (TextView) newRow.findViewById(R.id.textview_row_parametres);
ToggleButton toggleButton = (ToggleButton) newRow.findViewById(R.id.togglebutton_row_parametres);
toggleButton.setChecked(countries[i].isToSynchronize());
toggleButton.setTag(countries[i]);
Log.e("setChecked",""+toggleButton.getId()+"/"+countries[i].isToSynchronize());
textView.setText(countries[i].getLabel());
toggleButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
CountryDB countryTemp = (CountryDB) v.getTag();
changes.put(countryTemp.getLabel(), ((ToggleButton)v).isChecked());
}
});
tabLayout.addView(newRow);
TableRow rowDivider = (TableRow) getLayoutInflater().inflate(R.layout.row_divider, null);
tabLayout.addView(rowDivider);
}
Button buttonValidation = (Button) findViewById(R.id.button_parameters_accept);
buttonValidation.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Iterator<String> iterator = changes.keySet().iterator();
while(iterator.hasNext()){
String stringTemp = iterator.next();
Database.instance(ctx).updateCountry(stringTemp, changes.get(stringTemp));
}
Intent intent = new Intent(ctx, Splash.class);
String result = "restart";
String from = "parameters";
Intent returnIntent = new Intent();
returnIntent.putExtra("result", result);
returnIntent.putExtra("from", from);
setResult(RESULT_OK, returnIntent);
startActivity(intent);
}
});
}
}
In the Log.e, I print the values, and they are good, the display on togglebuttons is wrong, they are just all "false".
Thanks for your help.

Between onCreate() and onResume() , Android tries to restore the old state of the toggle Buttons. Since they don't have unique ID's , Android wont succeed and everything is false again. Try to move your setChecked() calls into onResume() ( maybe onStart() works too).
Here is a pretty good answer to the same Question:
ToggleButton change state on orientation changed

you have to save data before Orientation.
Android have method onSaveImstamceState(Bundle outState) and onRestoreInstanceState(BundleInstaceState)
override these method in Activity.

There's a simpler solution: you only need to add configChanges property to your activity declaration, like stated here. This way you can prevent Activity restart when orientation changes. So in your manifest you should have something like
<activity android:name=".Parameters"
android:configChanges="orientation|keyboardHidden">
or if your buildTarget>=13
<activity android:name=".Parameters"
android:configChanges="orientation|keyboardHidden|screenSize">
Edit: Like reported on comments below, this is not an optimal solution. The main drawback is reported in a note of the document linked above:
Note: Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.

Related

How to let user know, an ImageView is clickable

I have an ImageView(see image below), which is clickable. When the user clicks on the ImageView, he gets redirected to website. This is all running fine.
My question is, how to let user know, he can click the image, how to make this feature visible?
I can add text under the image, but thats not, what i want. I would like some small icon or window(like dialog), which can be closed.
Thanks!
you can check by bellow:
imageViewObject.isClickable();
Maybe you could animate a small finger/hand icon tapping the image when the ImageView shows up to indicate the element is clickable.
Like this: http://cmsresources.windowsphone.com/windowsphone/en-us/How-to/wp7/block/gettingstarted-concept-tap-and-hold-gesture.png
Or you could use gradients and shadows to give the image a button look.
So I searched and found this. This is #kgandroid suggested.
I add a little bit of code:
private FrameLayout mFrame;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFrame = new FrameLayout(this);
mFrame.addView(LayoutInflater.from(getBaseContext()).inflate(R.layout.activity_single_list_view, null));
setContentView(mFrame);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean overlayShown = settings.getBoolean("overlayShown", false);
if(!overlayShown){
setupHelpOverlay();
}
...
}
private void setupHelpOverlay(){
final View tutView = LayoutInflater.from(getBaseContext()).inflate(R.layout.activity_detail_overlay, null);
if(mFrame != null){
mFrame.addView(tutView);
}
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("overlayShown", true);
// Commit the edits!
editor.commit();
Button btnDismiss = (Button) tutView.findViewById(R.id.button_overlay);
btnDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
mFrame.removeView(tutView);
}
});
}
And the activity_deatil_overlay.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/transparent_gray" >
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView1"
android:layout_centerHorizontal="true"
android:textSize="20sp"
android:gravity="center"
android:textColor="#color/white"
android:text="#string/overlay_text"
android:paddingBottom="10dp" />
<View
android:id="#+id/textView1"
android:layout_width="1dp"
android:layout_height="1dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<Button
android:id="#+id/button_overlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:layout_centerHorizontal="true"
android:text="#string/overlay_button"
android:textColor="#color/white"
android:paddingTop="10dp" />
</RelativeLayout>
On the first start, it shows help overlay.
You could put a bar around the Image and change its color when the image is pressed. So it looks like a button.

Android: Unable to Prevent buttons from increasing size and overlapping with other buttons

I am new to Android Programming, what I am trying to do in this Android Application is to create a xml page filled with buttons.
When I click the button, the button would change to light green color and when I click it again, it would change to light grey
The error: I am getting is when I click the button, it increases in size and overlaps with the other buttons, please help me out here, it is not user friendly in this case
attached below is the code:
lockerbooking.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/sisButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dp"
android:layout_marginTop="28dp"
android:text="#string/sis"
/>
<Button
android:id="#+id/solButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/soeButton"
android:layout_alignBottom="#+id/soeButton"
android:layout_alignParentRight="true"
android:text="#string/sol" />
<Button
android:id="#+id/soeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/sisButton"
android:layout_alignBottom="#+id/sisButton"
android:layout_centerHorizontal="true"
android:text="#string/soe" />
</RelativeLayout>
Code:
makeBooking.java
public class makeBooking extends Activity {
Button sisButton;
Button solButton;
Button soeButton;
Button sobButton;
super.onCreate(savedInstanceState);
// Get the message from the intent
setContentView(R.layout.lockerbookpage);
Intent intent = getIntent();
// Initialize TextViews
sisButton = (Button) findViewById(R.id.sisButton);
solButton = (Button) findViewById(R.id.solButton);
soeButton = (Button) findViewById(R.id.soeButton);
sobButton = (Button) findViewById(R.id.sobButton);
}
public OnClickListener solButtonListener = new OnClickListener(){
boolean flag = true;
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(flag){
solButton.setBackgroundColor(Color.GREEN);
}
else{
solButton.setBackgroundColor(Color.LTGRAY);
}
flag=!flag;
}
};
...The code goes on
Please help me out here, I am eager to learn
to avoid overlapping of buttons, use fixed width and height for buttons:
change this:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
to some this like this:
android:layout_width="100dp" //what ever size suits your layout
android:layout_height="50dp" //fixing this,will not overlap the buttons

How to make a button redirect to another XML layout

I'm making a button in xml(res / layout / activity_home.xml), like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeActivity" >
<ImageView
android:id="#+id/imageView1"
android:src="#drawable/schkopwide"
android:contentDescription="#string/HTI"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="78dp"
android:onclick="Intent i = new Intent(activity_store.xml);
startActivity(i);"
android:text="#string/HTI" />
</RelativeLayout>
so what should I add into this xml to let it redirect to another xml page (res / layout / activity_store.xml)?
Thank you
If you Want to show two different layouts in Same Activity, then ViewSwitcher is best layout.
You can add multiple layouts in ViewSwithcher. And Replace them by using viewswitcher.next(); function.
<ViewSwitcher
android:id="#+id/viewswitcher"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- Add Two View’s Here -- >
</ViewSwitcher>
You can take reference from this link: http://abhiandroid.com/ui/viewswitcher
Try out as below:
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="78dp"
android:onclick="start"
android:text="#string/HTI" />
In your main activity :
Button button = (Button)findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(this, ActivityStore.class);
startActivity(i);
}
});
Here is your ActivityStore Class code:
public class ActivityStore extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_store);
}
}
Also add the activity into your mainfest file.
<activity
android:name=".ActivityStore"
android:label="#string/app_name"/ >
You can't add the launch of an Intent inside the onclick parameter in XML. You have to do it by code.
In your code:
Button button = (Button)findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(this, ActivityStore.class);
startActivity(i);
}
});
And in the OnCreate of the ActivityStore class, put this
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_store);
}
NOTE: I supposed that yous activity_store class is called ActivityStore
You need to check on Android documentation :
Activity
OnClickListener
Intent
http://developer.android.com/training/index.html
Good luck.
Try this,
Statically include XML layouts inside other XML layouts. use include. Add the below code in your activity_store.xml
<include layout="#layout/activity_home"/>
Sure you will get solution.
A simple way would be to create an Activity with another xml attached to it and then use intent.

android -- make calculations with input data (numeric) -- (show graphs?)

I am starting to learn android and i have a few questions.
I have my main program as:
public class Radiation_overflowActivity extends Activity implements OnClickListener {
EditText init_cores;
View final_cores;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Set up click listeners
init_cores=(EditText) findViewById(R.id.init_cores);
//init_cores.setOnClickListener(this);
final_cores=(View) findViewById(R.id.final_cores);
final_cores.setOnClickListener(this);
}
//called when a button is clicked
public void onClick(View v) {
switch (v.getId()){
case R.id.final_cores:
//int r = Integer.parseInt(init_cores.getText().toString().trim());
double initcores=Double.parseDouble(init_cores.getText().toString().trim());
double l=2,t=2;
double fcores=initcores*Math.exp(-l*t);
Intent i=new Intent(this,calcs.class);
i.putExtra("value",fcores);
startActivity(i);
break;
}
}
}
Also, my main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/initial_cores" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/init_cores"
android:inputType="numberDecimal" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/final_cores"
android:text="#string/calculate" />
</LinearLayout>
My calcs.java:
public class calcs extends Activity{
TextView calcs_final;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calcs);
calcs_final=(TextView) findViewById(R.id.calcs_final);
double f=getIntent().getExtras().getDouble("value");
calcs_final.setText(Double.toString(f));
}
}
My calcs.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/calcs_final"
android:text="#string/result" />
</LinearLayout>
I want to do this:
The user enters data into the edittext (init_cores) and then i want to make some calculations to compute the final_cores and show it to the user.
I have trouble for showing the results.I am starting another activity (calcs.class and calcs.xml).
Where i must do the calculations?To the calcs.class?
Right now,the user enters a number ,presses the "Calculate" button and then it shows the text (from the strings.xml) "Number of cores"" ,but not the result.
Also, can i use the input from the data and from my calculations and make a plot?If you could give me some directions to this.
Finally,is my approach right?
Thank you!
For plotting your data, you can use the AChartEngine library, which is quite extensive and easy to use.
As per I think your final_cores is a view on which, you want to get your edittext's value for calculation(Hope I am not wrong)
So, just do Something like,
public void OnClick(View v) {
switch (v.getId()){
case R.id.final_cores:
int r = Integer.parseInt(init_cores.getText().toString().trim());
Intent i=new Intent(this,calcs.class);
i.putExtra("value",r);
startActivity(i);
break;
}
}
Remove onClickListener from your init_cores edittext. And get values of r in your Calcs.class using
int r = getIntent().getExtras().getInt("value");
Also be sure in your edit text always you are entering numeric values so it can be parsable into Integer..
Try this and let me know what happen..
Thanks,

setContentView and EditText

I have two layouts xml and can't get the second layout to work correctly.
A EditText placed on the second layout doesn't work as expected. It doesn't accept characters.
What am i missing here?
Should i use startActivity() instead?
Main.java
public class Main extends Activity implements View.OnClickListener {
EditText box1, box2;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
showXml1();
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
String box11 = box1.getText().toString();
Toast.makeText(this, box11,Toast.LENGTH_SHORT).show();
showXml2();
break;
case R.id.button2:
String box22 = box2.getText().toString();
Toast.makeText(this, box22,Toast.LENGTH_SHORT).show();
showXml1();
break;
}
}
public void showXml2() {
setContentView(R.layout.main2);
box2 = (EditText) findViewById(R.id.editText2);
}
public void showXml1() {
setContentView(R.layout.main);
box1 = (EditText) findViewById(R.id.editText1);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Main1" />
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
android:onClick="onClick"
/>
</LinearLayout>
mail2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Main2" />
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<requestFocus />
</EditText>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2"
android:onClick="onClick"
/>
</LinearLayout>
Use a meta layout xml file with a structure similar to this one:
meta_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<ViewFlipper
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/root">
<include
layout="#layout/main" />
<include
layout="#layout/main2" />
</ViewFlipper>
And then main.java:
public class Main extends Activity implements View.OnClickListener {
EditText box1, box2;
ViewFlipper root;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.meta_main);
box1 = (EditText) findViewById(R.id.editText1);
box2 = (EditText) findViewById(R.id.editText2);
root = (ViewFlipper) findViewById(R.id.root);
}
public void onClick(View v) {
EditText editText = null;
switch (v.getId()) {
case R.id.button1:
editText = box1;
root.showNext();
break;
case R.id.button2:
editText = box2;
root.showPrevious();
break;
}
if(editText != null) {
Toast.makeText(this, editText.getText(), Toast.LENGTH_SHORT).show();
}
}
}
Hope it helps ;)
I don't think you can load a new layout that way.
Just put the two EditTexts in one XML and put one visible and the other invisble and with a button click vice versa.
As an alternative to different activities you might want to look at ViewFlipper http://developer.android.com/reference/android/widget/ViewFlipper.html
You are only allowed to call setContentView() once in your activity.
You can either
Create a "Main" layout that just contains a parent I.E. LinearLayout, or Relative layout
setContentView() on the parent. Then acquire a reference to it with findViewById() and call .addView() on your reference passing the inflated xml from one of these two files. .removeView() will allow you to switch to the other one when you like.
or
Include all of your views in one xml layout, but make half of them Visibility.GONE and when you want to switch just make the ones that were GONE be VISIBLE and vice versa
I think it should work, you have to reinitialize references for example every findViewById needs to be called again after calling setContentView(). You are exactly doing so first you are calling showXml1() & then you are clicking button1 which is executing Case1, you are getting the value of box1 & displaying it & then you are calling showXml2() & so on. I have tried your code & it works, i am wounding why its not working on your side?
Another thing is that it may not be a good idea if you have to call findViewbyId() a LOT OF TIMES, so you should avoid it i guess.

Categories

Resources