Android RelativeLayout problem - android

I have some problem with RelativeLayout positioning:
Now I have this: http://dl.dropbox.com/u/18411570/now.png
And I would like this: http://dl.dropbox.com/u/18411570/expectation.png
Here's my code:
public class ActivityTwo extends Activity {
RelativeLayout myRelativeLayout = null;
ArrayList<ArrayList<EditText>> spreadsheet = new ArrayList<ArrayList<EditText>>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.relativesprsheet);
myRelativeLayout = (RelativeLayout)findViewById(R.id.relativeLayout);
//FIRSTROW
ArrayList<EditText> firstRow = new ArrayList<EditText>();
char columnTitle = 'A';
int prev_id = 0;
for(int i = 0; i < 5; ++i) {
EditText eText = new EditText(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
eText.setWidth(100);
eText.setId(getUniqueCellId(columnTitle,i + 1));
if(i==0) {
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT,eText.getId());
eText.setText("A1");
}
else {
params.addRule(RelativeLayout.RIGHT_OF,prev_id);
eText.setText(Character.toString(columnTitle)+Integer.toString(1));
}
prev_id = getUniqueCellId(columnTitle,i + 1);
firstRow.add(eText);
myRelativeLayout.addView(eText,params);
columnTitle++;
}
spreadsheet.add(firstRow);
//SECONDROW
ArrayList<EditText> second_row = new ArrayList<EditText>();
EditText a2 = new EditText(this);
a2.setId(getUniqueCellId('A',2));
a2.setWidth(100);
a2.setText("A2");
RelativeLayout.LayoutParams a2params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
a2params.addRule(RelativeLayout.BELOW, getUniqueCellId('A', 1));
myRelativeLayout.addView(a2, a2params);
second_row.add(a2);
EditText bigView = new EditText(this);
bigView.setId(getUniqueCellId('B', 2));
bigView.setWidth(300);
bigView.setText("B2");
RelativeLayout.LayoutParams b2params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
b2params.addRule(RelativeLayout.RIGHT_OF, getUniqueCellId('A', 2));
b2params.addRule(RelativeLayout.ALIGN_TOP,getUniqueCellId('A', 2));
b2params.addRule(RelativeLayout.ALIGN_BOTTOM,getUniqueCellId('A', 4));
b2params.addRule(RelativeLayout.ALIGN_RIGHT,getUniqueCellId('D',5));
myRelativeLayout.addView(bigView, b2params);
second_row.add(bigView);
spreadsheet.add(second_row);
//THIRDROW
ArrayList<EditText> third_row = new ArrayList<EditText>();
EditText a3 = new EditText(this);
a3.setId(getUniqueCellId('A',3));
a3.setWidth(100);
a3.setText("A3");
RelativeLayout.LayoutParams a3params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
a3params.addRule(RelativeLayout.BELOW, getUniqueCellId('A', 2));
myRelativeLayout.addView(a3, a3params);
third_row.add(a3);
spreadsheet.add(third_row);
//FOURTHROW
ArrayList<EditText> fourth_row = new ArrayList<EditText>();
EditText a4 = new EditText(this);
a4.setId(getUniqueCellId('A',4));
a4.setWidth(100);
a4.setText("A4");
RelativeLayout.LayoutParams a4params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
a4params.addRule(RelativeLayout.BELOW, getUniqueCellId('A', 3));
myRelativeLayout.addView(a4, a4params);
fourth_row.add(a4);
spreadsheet.add(fourth_row);
//FIFTHROW
ArrayList<EditText> fifth_row = new ArrayList<EditText>();
EditText a5 = new EditText(this);
a5.setId(getUniqueCellId('A',5));
a5.setWidth(100);
a5.setText("A5");
RelativeLayout.LayoutParams a5params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
a5params.addRule(RelativeLayout.BELOW, getUniqueCellId('A', 4));
myRelativeLayout.addView(a5, a5params);
fifth_row.add(a5);
char c2 = 'B';
for(int i = 1; i < 5; ++i) {
EditText temp5Text = new EditText(this);
temp5Text.setId(getUniqueCellId(c2,5));
temp5Text.setWidth(100);
temp5Text.setText(Character.toString(c2)+"5");
RelativeLayout.LayoutParams temp5Textparams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
temp5Textparams.addRule(RelativeLayout.RIGHT_OF, getUniqueCellId((char)(c2-1), 5));
temp5Textparams.addRule(RelativeLayout.ALIGN_TOP, getUniqueCellId((char)(c2-1), 5));
myRelativeLayout.addView(temp5Text, temp5Textparams);
fifth_row.add(temp5Text);
c2++;
}
spreadsheet.add(fifth_row);
}
private int getUniqueCellId(char c, int i) {
return Integer.valueOf(c) * 10369 + i;
}
}
And here is the layout xml:
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</RelativeLayout>
</ScrollView>
</HorizontalScrollView>
I can't understand, why the first row is broken and the fifth is not, and how could i fix it... please help me if you can, thx!
Edit1: I didn't mention that I would like to do it programmatically Edit2: I changed the links, I hope it will work for everybody

I suggest you use your XML layout file for this. Set up things so they are laid out properly, and then hook up non-layout stuff like click handlers or changing text later.

Related

Radio button text to top of the button programmatically

Is there any way to align the text of radio button to the top like below programmatically.
i used the below code for creating radio group
final RadioButton[] rb = new RadioButton[5];
RadioGroup rg = new RadioGroup(getActivity()); //create the RadioGroup
rg.setOrientation(RadioGroup.VERTICAL);//or RadioGroup.VERTICAL
rg.setLayoutParams(radioparams);
for (int i = 0; i < 5; i++) {
rb[i] = new RadioButton(getActivity());
rb[i].setText("Radiobtn " + i);
rb[i].setId(i + 100);
rg.addView(rb[i]);
}
layout.addView(rg);
but i get the text to the right side of each button.
final RadioButton[] rb = new RadioButton[5];
RadioGroup rg = new RadioGroup(getActivity()); //create the RadioGroup
rg.setOrientation(RadioGroup.VERTICAL);//or RadioGroup.VERTICAL
rg.setLayoutParams(radioparams);
for (int i = 0; i < 5; i++) {
rb[i] = new RadioButton(getActivity());
rb[i].setText("Radiobtn " + i);
rb[i].setId(i + 100);
rb[i].setButtonDrawable(null);
TypedArray a = getTheme().obtainStyledAttributes(R.style.AppTheme, new int[] {android.R.attr.listChoiceIndicatorSingle});
int attributeResourceId = a.getResourceId(0, 0);
Drawable drawable = getResources().getDrawable(attributeResourceId);
rb[i].setCompoundDrawablesWithIntrinsicBounds(null, null, null, drawable);
rb[i].setGravity(Gravity.CENTER | Gravity.BOTTOM);
rg.addView(rb[i]);
}
layout.addView(rg);
Try this way you can do a trick
make your layout like this
<LinearLayout
android:id="#+id/lnrView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:orientation="horizontal">
</LinearLayout>
than add programatically RadioButton like this
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LinearLayout layout = new LinearLayout(MainActivity.this);
layout.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
LinearLayout layout2 = new LinearLayout(MainActivity.this);
layout2.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
final ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final TextView textView = new TextView(MainActivity.this);
int id = 0;
textView.setId(id);
textView.setTextSize(14);
textView.setTextColor(Color.rgb(0, 0, 0));
textView.setMaxEms(2);
textView.setText("NIlu");
layout2.addView(textView);
RadioButton radioButton = new RadioButton(MainActivity.this);
layout2.addView(radioButton);
layout.setLayoutParams(lp);
lnrView.addView(layout2);
}
});

TextView on the right of dynamically created Buttons

As seen in the picture, everything works fine except that myTextView, instead of appearing just on the right of the last Button, it does on top of 16, 17 and 18. I can’t manage these 3 Buttons to appear bellow the rest. Here is my essential code, where I create dynamically the Buttons and myTextView:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout layout = (LinearLayout) findViewById(R.id.layout1); // id del XML
layout.setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i < 4; i++) {
LinearLayout fila = new LinearLayout(this);
fila.setLayoutParams(new
LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
for (int j = 0; j < 5; j++) {
if (i==3 && j==3){
TextView myTextView = new TextView(this);
LinearLayout.LayoutParams layoutParams=newLinearLayout.LayoutParams(490, 40);
layoutParams.setMargins(870, 30, 0, 0);
myTextView.setTextSize(26);
myTextView.setLayoutParams(layoutParams);
layout.addView(myTextView);
break;
}
Button btnTag = new Button(this); //
btnTag.setBackgroundColor(Color.TRANSPARENT);
btnTag.setLayoutParams(new LinearLayout.LayoutParams(255, 166));
fila.addView(btnTag);
btnTag.setId(j + 1 + (i * 5));
btnTag.setOnClickListener(prueba);
}
layout.addView(fila);
}
}
At last I have solved the problem. Instead of a LinearLayout I have to use a RelativeLayout. Like this, I can set the TextView wherever I want on the screen throughout the xml. Here is the code, where with rel_btn I set the Buttons wherever I want, too:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_main);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.layout1); // id del XML
for (int i = 1; i < 19; i++) {
RelativeLayout.LayoutParams rel_btn = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
switch(i) {
case 1: rel_btn.leftMargin = 0; rel_btn.topMargin = 0; break;
case 2: rel_btn.leftMargin = 255; rel_btn.topMargin = 0; break;
case 3: rel_btn.leftMargin = 510; rel_btn.topMargin = 0; break;
…… as many as Buttons requiered
}
rel_btn.width = 255; rel_btn.height = 165;
Button btnTag = new Button(this);
btnTag.setLayoutParams(rel_btn);
btnTag.setBackgroundColor(Color.TRANSPARENT);
btnTag.setId(0+i); // les pone el ID
btnTag.setOnClickListener(prueba);
layout.addView(btnTag);
}
}
1. Set layout weight sum
fila.setWeightSum(5);
2. Set width = 0dp and weight = 1 for all buttons
btnTag.setLayoutParams(new LinearLayout.LayoutParams(0, 166, weight));
3. Set width=0dp and weight = 2 for textview
LinearLayout.LayoutParams layoutParams= new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 40);
layoutParams.weight = 2;
//layoutParams.setMargins(870, 30, 0, 0);
myTextView.setTextSize(26);
myTextView.setLayoutParams(layoutParams);
Updated onCreate method
public void onCreate(Bundle savedInstanceState) {
LinearLayout layout = (LinearLayout) findViewById(R.id.layout1); // id del XML
layout.setOrientation(LinearLayout.VERTICAL);
int width = 0; //0dp, we will use weight to set width
int weight = 1;
for (int i = 0; i < 4; i++) {
LinearLayout fila = new LinearLayout(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, weight);
fila.setLayoutParams(params);
fila.setWeightSum(5);
for (int j = 0; j < 5; j++) {
if (i==3 && j==3){
TextView myTextView = new TextView(this);
LinearLayout.LayoutParams layoutParams= new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 40);
layoutParams.weight = 2;
//layoutParams.setMargins(870, 30, 0, 0);
myTextView.setTextSize(26);
myTextView.setLayoutParams(layoutParams);
layout.addView(myTextView);
break;
}
Button btnTag = new Button(this); //
btnTag.setBackgroundColor(Color.TRANSPARENT);
btnTag.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 166, weight));
fila.addView(btnTag);
btnTag.setId(j + 1 + (i * 5));
btnTag.setOnClickListener(prueba);
}
layout.addView(fila);
}
}

Creating Buttons Programmatically on Android

I want to dynamically create 10 Buttons with Margin between each Button but things I tried won't work.
Here is the code I'm using:
//Create Button
for(int i = 1; i <= 10; i++){
MarginLayoutParams params = new MarginLayoutParams(MarginLayoutParams.MATCH_PARENT, MarginLayoutParams.MATCH_PARENT);
params.setMargins(10, 0, 10, 0);
params.leftMargin = xpos;
params.topMargin = ypos;
params.width = 250;
params.height = 150;
Button btn = new Button(this);
btn.setId(i);
final int _id = btn.getId();
btn.setLayoutParams(params);
btn.setText("Button " + _id);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(v.getContext(), "Button clicked index =" + _id, Toast.LENGTH_LONG).show();
//Intent einauslagern = new Intent(v.getContext(), JockeyEinauslagern.class);
//startActivityForResult(einauslagern, 0);
}
});
xpos += 20;
ypos += 50;
this.addContentView(btn, params);
}
You might want to get a container in your Activity class like this. (let it be LinearLayout for example).
Your XML -
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/container"
android:orienation="vertical"
/>
Your Java -
LinearLayout container = (LinearLayout) findViewById(R.id.container);
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
//set your margins here
for (int i = 0; i < 10; i++) {
Button button = new Button(this);
// some stuff
container.addView(button, llp);
}
With minor modifications this should work mostly fine.
Try this
for (int i = 0; i < count; i++) {
// creates button
final Button btn = new Button(this);
btn.setLayoutParams(new ViewGroup.LayoutParams(
250,150));
btn.setPadding(0, 8, 0, 8); //or set margin if u need
btn.setTag(i);
yourContainserView.addView(channelBtn, i);
}

Add multiple views in ScrollView?

I am working on an Android App. I have some problem..
Here is my app :
The pink rectangle is a ScrollView. I want to add TextView to the same ScrollView. I know I need a LinearLayout and add my Views inside this layout. After I need to add the LinearLayout to my ScrollView. Here is my ScrollView class with my methods setClassicLabel to implement TextViewand setClassicButton to implement Button in my ScrollView.
Here is my ScrollView.java :
public class MyScrollView extends ScrollView {
private JSONParser jParser;
private JSONObject contenuScrollView;
private Context context;
#SuppressLint("NewApi")
public MyScrollView(Context context, JSONArray listScrollView) throws JSONException {
super(context);
this.context = context;
}
public void onCreate(Bundle savedInstanceState) throws JSONException {
}
/* Création de TextView */
public void setClassicLabel(JSONArray listLabel, LinearLayout ll) throws JSONException {
if (listLabel.length() > 0)
{
DisplayMetrics metrics = new DisplayMetrics();
ll = new LinearLayout(getContext());
ll.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams paramsll = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
for (int i = 0; i < listLabel.length(); i++) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams((int) (getContext().getResources().getDisplayMetrics().widthPixels * listLabel.getJSONObject(i).getDouble("size_x")),
(int) (getContext().getResources().getDisplayMetrics().heightPixels * listLabel.getJSONObject(i).getDouble("size_y")));
params.leftMargin = (int) (getContext().getResources().getDisplayMetrics().widthPixels * listLabel.getJSONObject(i).getDouble("position_x"));
params.topMargin = (int) (getContext().getResources().getDisplayMetrics().heightPixels * listLabel.getJSONObject(i).getDouble("position_y"));
TextView tv = new TextView(context);
tv.setText(listLabel.getJSONObject(i).getString("text"));
tv.setTextSize(listLabel.getJSONObject(i).getInt("police_size"));
tv.setTextColor(Color.parseColor(listLabel.getJSONObject(i).getString("colortext")));
tv.setBackgroundColor(Color.parseColor(listLabel.getJSONObject(i).getString("color")));
ll.addView(tv, params);
}
this.addView(ll, paramsll);
}
}
#SuppressWarnings("deprecation")
public void setClassicButton(JSONArray listButton, LinearLayout ll) throws JSONException {
if (listButton.length() > 0)
{
DisplayMetrics metrics = new DisplayMetrics();
ll = new LinearLayout(getContext());
ll.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams paramsll = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
for (int i = 0; i < listButton.length(); i++) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams((int) (getContext().getResources().getDisplayMetrics().widthPixels * listButton.getJSONObject(i).getDouble("size_x")),
(int) (getContext().getResources().getDisplayMetrics().heightPixels * listButton.getJSONObject(i).getDouble("size_y")));
params.leftMargin = (int) (getContext().getResources().getDisplayMetrics().widthPixels * listButton.getJSONObject(i).getDouble("position_x"));
params.topMargin = (int) (getContext().getResources().getDisplayMetrics().heightPixels * listButton.getJSONObject(i).getDouble("position_y"));
int dest = listButton.getJSONObject(i).getInt("dest");
MyButton myButton = new MyButton(context, dest);
RoundRectShape rect = new RoundRectShape(
new float[] {50,50, 50,50, 50,50, 50,50},
null,
null);
ShapeDrawable bg = new ShapeDrawable(rect);
bg.getPaint().setColor(Color.parseColor(listButton.getJSONObject(i).getString("color")));
myButton.setBackgroundDrawable(bg);
myButton.setTextColor(Color.parseColor(listButton.getJSONObject(i).getString("colortext")));
//BitmapDrawable bdra = new BitmapDrawable(downloadBitmap(listButton.getJSONObject(i).getString("http")));
myButton.setText(listButton.getJSONObject(i).getString("text"));
myButton.getBackground().setAlpha(30);
myButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
MyButton button = (MyButton)view;
Intent intent = new Intent(context, ClassicView.class);
Content content = new Content(button.getDestination());
intent.putExtra("CONTENT", content);
context.startActivity(intent);
}
});
ll.addView(myButton, params);
}
this.addView(ll, paramsll);
}
}
}
MyScrollView heritates from ScrollView. The problem is the next :
When I create my ScrollView with the method setClassicScrollView, i call my methods setClassicLabel and setClassicButton to implements theses two views in my ScrollView. But i can only set Button or Label. I can't set one label and one button. I must have a problem who comes from a layout.. I am on it for two days
Here is my method setClassicScrollView :
public void setClassicScrollView(JSONArray listScrollView, RelativeLayout rl) throws JSONException {
if (listScrollView.length() > 0) {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
for (int i = 0; i < listScrollView.length(); i++) {
MyScrollView myScrollView = new MyScrollView(this, listScrollView);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams paramsll = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int) (metrics.widthPixels * listScrollView.getJSONObject(i).getDouble("size_x")), (int) (metrics.heightPixels * listScrollView.getJSONObject(i).getDouble("size_y")));
params.leftMargin = (int) (metrics.widthPixels * listScrollView.getJSONObject(i).getDouble("position_x"));
params.topMargin = (int) (metrics.heightPixels * listScrollView.getJSONObject(i).getDouble("position_y"));
myScrollView.setBackgroundColor(Color.RED);
myScrollView.setLayoutParams(params);
myScrollView.setHorizontalScrollBarEnabled(true);
myScrollView.getMaxScrollAmount();
myScrollView.getBackground().setAlpha(50);
//myScrollView.setClassicLabel(listScrollView.getJSONObject(i).getJSONArray("Label"), ll);
myScrollView.setClassicButton(listScrollView.getJSONObject(i).getJSONArray("Button"), ll);
rl.addView(myScrollView);
}
}
}
Someone has an idea of how I can set TextViews and Buttons in the same ScrollView ?
Here's the layout for your scroll view.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Spinner
android:id="#+id/spending_report_cycle_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<View
android:id="#+id/SomeView2"
android:layout_width="wrap_content"
android:layout_height="5dp"
android:layout_gravity="center_horizontal"
android:background="#008080"
android:orientation="vertical" />
<fragment
android:id="#+id/fragment_content_1"
android:name="com.mike.passintents.Fragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<View
android:id="#+id/SomeView2"
android:layout_width="wrap_content"
android:layout_height="5dp"
android:layout_gravity="center_horizontal"
android:background="#008080"
android:orientation="vertical" />
<ListView
android:id="#+id/spending_report_listview"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:background="#333333" >
</ListView>
</LinearLayout>
</ScrollView>
Here.. In the scroll view, I have one linear layout as one child and after that I have other views inside the linear layout.

Re-Adding views to a fragment on onResume returns an IllegalStateException

I'm developing an Android 3.1 Tablet application with fragments.
I've seen that only two fragments are on memory at the same time. When I show a third one, first one calls onDestroyView.
I add EditText to fragment's view programmatically. Those EditText don't show again after fragment's view recreation on onResume method.
I use those EditText to let users add data to a form and I store a reference in firstTable HashMap. I will use that HashMap to retrieve user's values.
Here I create those EditText programmatically:
private LinearLayout createNewFirstTableRow(long articleId)
{
LinearLayout layout = new LinearLayout(mActivity);
LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
parentParams.weight = 1;
layout.setLayoutParams(parentParams);
if (firstTable == null)
firstTable = new HashMap<Long, ArrayList<EditText>>();
ArrayList<EditText> fields = new ArrayList<EditText>(7);
LayoutParams params = new LayoutParams(0, 40);
params.weight = 0.125f;
TextView textView = new TextView(mActivity);
textView.setLayoutParams(params);
textView.setText(new Long(articleId).toString());
layout.addView(textView);
for (int i = 0; i < 7; i++)
{
EditText edit = new EditText(mActivity);
edit.setLayoutParams(params);
edit.setInputType(InputType.TYPE_CLASS_NUMBER);
fields.add(i, edit);
layout.addView(edit);
}
firstTable.put(new Long(articleId), fields);
return layout;
}
firstTable variable is a global variable: private HashMap<Long, ArrayList<EditText>> firstTable;.
To add my EditText I do the following on onResume:
#Override
public void onResume()
{
Log.v("QuantityFragment", "onResume: " + firstTableRowIndex);
if ((firstTable != null) && (secondTable != null))
{
firstTableRowIndex = FIRST_TABLE_ROW_INDEX;
secondTableRowIndex = SECOND_TABLE_ROW_INDEX;
LinearLayout table = (LinearLayout)view.findViewById(R.id.quantityTable);
for (int index = 0; index < firstTable.size(); index++)
{
Long articleId = articleIds.get(index);
table.addView(resumeTable(articleId, secondTable.get(articleId)), secondTableRowIndex);
table.addView(resumeTable(articleId, firstTable.get(articleId)), firstTableRowIndex);
firstTableRowIndex++;
secondTableRowIndex++;
}
}
super.onResume();
}
private LinearLayout resumeTable(Long articleId, ArrayList<EditText> fields)
{
LinearLayout layout = new LinearLayout(mActivity);
LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
parentParams.weight = 1;
layout.setLayoutParams(parentParams);
LayoutParams params = new LayoutParams(0, 40);
params.weight = 0.125f;
TextView textView = new TextView(mActivity);
textView.setLayoutParams(params);
textView.setText(new Long(articleId).toString());
layout.addView(textView);
for (int index = 0; index < fields.size(); index++)
{
layout.addView(fields.get(index));
}
return layout;
}
But, here layout.addView(textView); I get an exception:
IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Is there another way to re-add those EditText?
UPDATE:
I have solved my problem changing resumeTable:
private LinearLayout resumeTable(Long articleId, ArrayList<EditText> fields)
{
LinearLayout layout = new LinearLayout(mActivity);
LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
parentParams.weight = 1;
layout.setLayoutParams(parentParams);
LayoutParams params = new LayoutParams(0, 40);
params.weight = 0.125f;
TextView textView = new TextView(mActivity);
textView.setLayoutParams(params);
textView.setText(new Long(articleId).toString());
layout.addView(textView);
for (int index = 0; index < fields.size(); index++)
{
LinearLayout parent = (LinearLayout)fields.get(index).getParent();
parent.removeView(fields.get(index));
layout.addView(fields.get(index));
}
return layout;
}
This is the important part:
for (int index = 0; index < fields.size(); index++)
{
LinearLayout parent = (LinearLayout)fields.get(index).getParent();
parent.removeView(fields.get(index));
layout.addView(fields.get(index));
}
The question is open, if you have a better solution, please, let me know.
That exception is thrown because you store references to Views(the EditText) that were added to the layout and then later you're again re-adding those Views to a newly constructed parent.
Regarding a solution, I don't know why you decided to store references to those EditTexts. The only data that I see worth storing from those EditTexts is the text entered by the user, in which case you should store that text instead of that particular EditText .Your method would be:
//...
if (firstTable == null) {
// your HashMap now stores text instead of an EditText
firstTable = new HashMap<Long, ArrayList<String>>();// store only the text from the EditText
}
ArrayList<String> fields = new ArrayList<String>(7);
LayoutParams params = new LayoutParams(0, 40);
params.weight = 0.125f;
TextView textView = new TextView(mActivity);
textView.setLayoutParams(params);
textView.setText(new Long(articleId).toString());
layout.addView(textView);
for (int i = 0; i < 7; i++) {
EditText edit = new EditText(mActivity);
edit.setLayoutParams(params);
edit.setInputType(InputType.TYPE_CLASS_NUMBER);
fields.add(i, ""); // the EditText are empty at first
layout.addView(edit);
}
firstTable.put(new Long(articleId), fields);
Then when is time to restore the EditTexts:
private LinearLayout resumeTable(Long articleId, ArrayList<String> fields) {
LinearLayout layout = new LinearLayout(mActivity);
LayoutParams parentParams = new LayoutParams(LayoutParams.MATCH_PARENT, 40);
parentParams.weight = 1;
layout.setLayoutParams(parentParams);
LayoutParams params = new LayoutParams(0, 40);
params.weight = 0.125f;
TextView textView = new TextView(mActivity);
textView.setLayoutParams(params);
textView.setText(new Long(articleId).toString());
layout.addView(textView);
for (int index = 0; index < fields.size(); index++) {
// create new EditTexts
EditText edit = new EditText(mActivity);
edit.setLayoutParams(params);
edit.setInputType(InputType.TYPE_CLASS_NUMBER);
edit.setText(fields.get(index)); // get the text coresponding to this particular EditText
layout.addView(edit);
}
return layout;
}
Of course when the user enters something in the EditTexts you should store it in the firstTable variable at the right position.
I think problen is due to adding the element of fields twice
ArrayList<EditText> fields = new ArrayList<EditText>(7);
1 - in createNewFirstTableRow
for (int i = 0; i < 7; i++)
{
EditText edit = new EditText(mActivity);
edit.setLayoutParams(params);
edit.setInputType(InputType.TYPE_CLASS_NUMBER);
fields.add(i, edit);//<-----------
layout.addView(edit);//<----------- added in layout
}
2- onResume()->resumeTable
for (int index = 0; index < fields.size(); index++)
{
layout.addView(fields.get(index));//<----------------
}
when fields element alreay added on the screen you can't add that twice.......

Categories

Resources