I have a view in android that shows a number of check boxes. They are all added dynamically and I set a text for each one in part.
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
LayoutInflater inflater = getLayoutInflater();
for (String string : getResources().getStringArray(R.array.string_array)) {
LinearLayout searchField = (LinearLayout) inflater.inflate(R.layout.cb, null);
CheckBox checkBox = (CheckBox) searchField.findViewById(R.id.checkBox1);
checkBox.setText(string);
layout.addView(searchField, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
}
}
}
AS you can see from the code, I have an array of strings and for each of the strings in the array I add an check box. When the view is first shown, all the check boxes have the correct text, but after I rotate the device to landscape or portrait mode, all the check boxes have the same text (from the last check box). Any rotations (to redraw the screen) do not affect the text anymore. All of them remain with the text of the last check box.
I have looked in the debugger, the check box object is a new one for each string, so I am not working with the same instance of an object. I am currently out of ideas.
Do you have any idea why this is happening?
When you rotate the screen, runtime Resource is changed, and Activity is relaunched. Two ways to fix your problem:
Hold the value of all your checkbox in OnCheckedChangeListener and reset them back in onResume.
Handle onConfigurationChanged by yourself, according to https://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange
Related
I am currently working on a project which requires me to dynamically add textView objects to a LinearLayout based on the contents of an array.
chapter = Home.chapters.get(index);
layout.removeAllViews();
String dataText = chapter.content;
String[] dataArray = dataText.split("~");
for (int i = 0; i < dataArray.length; i++) {
String paragraph = dataArray[i];
String outputParagraph = paragraph.replace("`", "\n");
View view = getLayoutInflater().inflate(R.layout.ttc_text, null);
final TextView tv = (TextView) view.findViewById(R.id.textView);
tv.setText(outputParagraph);
//tv.setTextIsSelectable(true);
layout.addView(view);
}
TextView titleView = (TextView) findViewById(R.id.title);
titleView.setText("Chapter " + chapter.title);
layout.setOnTouchListener(new OnSwipeTouchListener(getBaseContext()) {
public void onSwipeRight() {
retreatBackward();
}
public void onSwipeLeft() {
advanceForward();
}
});
I have configured saveOnItemStateChanged in order to restore the correct contents of the textViews when the screen is rotated.
if (savedInstanceState != null) {
index = savedInstanceState.getInt("Chapter");
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("Chapter", index);
super.onSaveInstanceState(savedInstanceState);
}
However, whenever the screen is rotated, the textViews present within the parent layout do not display their original contents. Instead, the same number of textViews in the original layout all display identical contents, that is, the contents of the final textView added to the layout.
This issue only presents when the text within the TextViews is designated as selectable, either through the setTextIsSelectable() function or through the XML markup. As such, the selectability of the text must be somewhat impacting the way in which the contents of the TextViews are repopulated after a rotation, although I cannot seem to establish exactly why. Any assistance would be much appreciated.
I think the problem is due to your device's configuration change. When you rotate your device a configuration change event occur. Add the following code to your Manifest.xml and your activity class. Hope, that will solve your problem.
Changes to Manifest.xml file ---> (Suppose XYZ is your activity class)
<activity android:name=".activities.XYZ"
android:configChanges="orientation|screenSize"/>
Add this to your XYZ activity class --->
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
1st
super.onSavedInstanceState(...) should be the first thing called. Your 'save' stuff should come after.
2nd
You will most likely need to save all of the textviews, so you can repopulate them, or save the array and repopulate based on that.
I found this site to be very good for explaining the ins and out of save-instance-state handling.
http://www.intertech.com/Blog/saving-and-retrieving-android-instance-state-part-1/
I have extended EditTextPreference, but the Dialog Message won't display. This happens if I add the dialogMessage programatically or in the the preferences.xml.
Here is my onBindDialogView:
AutoCompleteTextView editText = mEditText;
editText.setText(getText());
ViewParent oldParent = editText.getParent();
if (oldParent != view) {
if (oldParent != null) {
((ViewGroup) oldParent).removeView(editText);
}
onAddEditTextToDialogView(view, editText);
}
Is the dialog message really absent? It's probably there but its text color might make it less (or not) visible. (Or try to dismiss software keyboard). Try experimenting with dialog messages having a number of "\n" characters and see if that affects dialog layout. If so, it means the dialog message is actually there but camouflaged too well.
EditTextPreference brings a text view (in the preference_dialog_edittext.xml) that replaces the existing one (in the alert_dialog.xml) for the dialog message, but unfortunately with different text style, which might cause a visibility problem under certain themes. Even their sizes are different.
One solution might be to obtain the text color and size from the original text view to be replaced and apply them to the new one, but I would suggest retaining the original text view instead, because it's more likely to be visually consistent if there are any future UI changes. Try adding the following overrides
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
builder.setMessage(getDialogMessage()); // bring back the original text view
}
protected void onAddEditTextToDialogView(View dialogView, EditText editText) {
int id = getContext().getResources().getIdentifier("edittext_container", "id", "android");
ViewGroup container = (ViewGroup) dialogView.findViewById(id);
container.removeAllViews(); // remove the new text view
super.onAddEditTextToDialogView(dialogView, editText);
}
If you think the dialog message and the edittext view is too far apart, they can be brought together a little closer by adding another override:
protected void showDialog(Bundle state) {
super.showDialog(state);
int id = getContext().getResources().getIdentifier("message", "id", "android");
TextView message = (TextView) getDialog().findViewById(id);
message.setPadding(message.getPaddingLeft(), message.getPaddingTop(), message.getPaddingRight(), 0);
}
and add the following line in the onAddEditTextToDialogView method after calling removeAllViews:
container.setPadding(container.getPaddingLeft(), 0, container.getPaddingRight(), container.getPaddingBottom());
I want to implement a feature that allows user to change the textSize of a textView in another view inside the app,
So I have a button with its "onClick" property set to:
Class mainActivity
public void increaseFont(View view)
{
MainViewPager.changeTextViewTextSize(mTextSize);
}
Class MainViewPager
static public void changeTextViewTextSize(int aTextSize)
{
View detailView = (View) LayoutInflater.from(mContext).inflate(R.layout.details, null);
TextView description = (TextView) detailView.findViewById(R.id.story_description);
description.setTextSize(aTextSize);
}
QUESTIONS is the textSize can't be changed when clicking the button. So how to?
The text size can changed at run time of course. You issue is related to the method changeTextViewTextSize. Using the inflater you are creating a new instance of R.layout.details, and through it, you are looking for the TextView you want to change the text size. But that layout is not at screen. It is not what you are seeing.
I have a button to which I attach an onClickListener via code. I have to to this through code because it's in a fragment.
The listener works fine when in landscape mode, but when it's in portrait it doesn't. There's no "click" sound even.
In my xml file, I set the initial visibility of the button to invisible and then make it visible later when the user clicks a radio button in the same Viewgroup as the button. The onclicklisteners of the radiobuttons are working just fine in both portrait and landscape mode.
Now if I remove the "android:visibility="invisible" code in xml, the onclickstener works fine in portrait mode! But of course I need it invisible till the user clicks a radiobutton otherwise the UI doesn't make sense. Very weird indeed.
Here's my code:
private void setOnClickForSaveButton(View v) {
Button changeFundsSave = (Button) v.findViewById(R.id.change_funds_save);
changeFundsSave.setOnClickListener(saveListener);
}
Button.OnClickListener saveListener = new Button.OnClickListener() {
#Override
public void onClick(View v) {
//Get the rootview
View rootView = v.getRootView();
EditText changeFundsEdit = (EditText) rootView.findViewById(R.id.change_funds_edit);
if(changeFundsEdit.getText().toString().equals("")) {
new AlertDialog.Builder(getActivity())
.setTitle( "" )
.setMessage( "Enter the number of units" )
.setPositiveButton( "Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
return;
}
}
};
private void setOnClicksForRadioButtons(View v) {
RadioButton rb1 = (RadioButton)v.findViewById(R.id.add_units);
RadioButton rb2 = (RadioButton)v.findViewById(R.id.remove_units);
RadioButton rb3 = (RadioButton)v.findViewById(R.id.set_units);
rb1.setOnClickListener(addRemoveSetButtonListener);
rb2.setOnClickListener(addRemoveSetButtonListener);
rb3.setOnClickListener(addRemoveSetButtonListener);
}
OnClickListener addRemoveSetButtonListener = new OnClickListener() {
#Override
public void onClick(View v) {
// Since we only have the radiobutton view, we need to get the parent
View rootView = v.getRootView();
//Make the controls visible
TextView changeFundsText = (TextView) rootView.findViewById(R.id.change_funds_text);
EditText changeFundsEdit = (EditText) rootView.findViewById(R.id.change_funds_edit);
Button changeFundsSave = (Button) rootView.findViewById(R.id.change_funds_save);
changeFundsText.setVisibility(View.VISIBLE);
changeFundsEdit.setVisibility(View.VISIBLE);
changeFundsSave.setVisibility(View.VISIBLE);
}
};
}
Solved the problem! In portrait mode, like everyone else I load one fragment in a separate activity. Out of habit I was calling setContentView(something) before loading the fragment! So ultimately the two layouts were overlapping each other and the visible and invisible buttons were overlapping each other and things must have gotten messed up. Damn, I'm not sure if I like the concept of fragments at all. My first time using them. But maybe I just need to learn how to wire them up properly before I get used to them :) Thank you so much for your help
my guess is that
1) do you findViewById again for the view you passed in setOnClickForSaveButton? since the old view will be destroyed and a view will be created when you change screen orientation
2) do you have multiple ids for R.id.change_funds_save
3) add a log at the first line of onclick(v) to see if it is called but goto another branch you didnt expect.
Unless you are loading two separate xml layout files from layout-land and layout-port, there shouldn't be much difference between landscape mode and portrait mode. That being said, I'm going to take a wild guess and say that your app is probably not working correctly due to configuration changes. Let me know if this is actually true... i.e. does your app work at first, but stops working when you rotate the screen?
If this is true, you should look into how the Activity lifecycle is affecting your views and onClickListeners.
Im confused.
I have a layout (LinearLayout) holding a TextView and EditText.
Somewhere in my code i create (programatically) a RelativeLayout and push in it several of this LinearLayouts. To each one of them i set an ID and values for TextView and EditText.
The problem is when i change screen orientation. All EditText controls gets the same value (from the last EditText). If i set a breakpoint all seems fine. I even inspected all elemets before setContentView is called and all values seem fine.
Any idea?
Here is the relevant part of code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
csWgs84 = getCoordinateSystem();
wgs84C = getCoordinates();
sView = new ScrollView(this);
layout = getLayoutInflater().inflate(R.layout.location_calculator, null);
View control1 = getLayoutInflater().inflate(R.layout.text_edit, null);
control1.setId(1);
TextView title1 = (TextView) control1.findViewById(R.id.title);
title1.setText(csWgs84.axisInfo.yAxisAbbreaviation + " [°] :");
EditText value1 = (EditText) control1.findViewById(R.id.input);
value1.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
value1.setText(cutValue(RSimpleFormatter.formatNumber(wgs84C.y, 1, 7, '.'), 12));
RelativeLayout.LayoutParams viewLayoutParams1 = new RelativeLayout.LayoutParams
(RelativeLayout.LayoutParams.FILL_PARENT,RelativeLayout.LayoutParams.WRAP_CONTENT );
viewLayoutParams1.addRule(RelativeLayout.BELOW, group.getId());
((RelativeLayout) layout).addView(control1, viewLayoutParams1);
View control2 = getLayoutInflater().inflate(R.layout.text_edit, null);
control2.setId(2);
TextView title2 = (TextView) control2.findViewById(R.id.title);
title2.setText(csWgs84.axisInfo.xAxisAbbreaviation + " [°] :");
EditText value2 = (EditText) control2.findViewById(R.id.input);
value2.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
value2.setText(cutValue(RSimpleFormatter.formatNumber(wgs84C.x, 1, 7, '.'), 12));
RelativeLayout.LayoutParams viewLayoutParams2 = new RelativeLayout.LayoutParams
(RelativeLayout.LayoutParams.FILL_PARENT,RelativeLayout.LayoutParams.WRAP_CONTENT );
viewLayoutParams2.addRule(RelativeLayout.BELOW, control1.getId());
((RelativeLayout) layout).addView(control2, viewLayoutParams2);
sView.addView(layout, scrollViewLayoutParams);
setContentView(sView);
}
I had the same problem. I don't know why it happens; it happens in one of my activities but not in another one that I think is almost identical. I haven't investigated it extensively though.
However, I came up with a workaround: Populate the EditTexts in onResume() instead of in onCreate(). (I also tried to populate them in onStart, but then I got the same fault.) I hope that may work for you or anyone else reading this thread.
If the (admittedly usually very clever) default onPause() method isn't dealing well your activity being pushed to memory and being reloaded from it then you need to override it.
Use onPause to save the value's of your programatically created fields in a bundle. In your onCreate method check for the presence of a Bundle and create you're view's from this.
Activity Lifecycle
Be careful with the references. Maybe you are creating all the EditText "programatically", and then just modifying the last one several times.
Posting the code will be helpful.
Check this or this. I think you are not saving EditText content during orientation change.
The underlying problem is that the views in your custom layout, which is inflated and added multiple times, all have the same IDs (R.id.title and R.id.input). When Android saves their state, each one overwrites the previous one because of the same ID.
What you could do is to define some unique IDs which are generated by Android and assign those to the fields programmatically.
Not sure if this is the case, but I was able to fix this issue by removing
android:textIsSelectable="true"
from my XML layout.