How to get the id from programmatically linear layout item - android

I don't know how to get the id of an item in a programmatically created linear layout. I want to "catch" the right id of a button and associate that with fields.
LinearLayout layout = (LinearLayout) findViewById(R.id.content_doodle_linearlayout3);
layout.setOrientation(LinearLayout.VERTICAL);
String[] data = {"1","2","3","4"};
String[] users = {"1","2","3"};
for (int i = 0; i < users.length; i++) {
row = new LinearLayout(this);
row.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
text = new TextView(this);
text.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
text.setText("Name " + (i));
text.setId(1000 + i);
row.addView(text);
int ergebnis = -1;
for (int j = 0; j < daten.length; j++) {
CheckBox btnTag = new CheckBox(this);
btnTag.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
//btnTag.setText("Button " + (j + 1 + (i * 4)));
btnTag.setId(j + 1 + (i * 4));
row.addView(btnTag);
}
layout.addView(row);
}
The Buttons can't not be found, because there "isn't" a (R.id.{XML-Field}).
How can i "find" the clicked button from the specific row. Do i have to code every button?

You can set a specified tag for each child view in your layout in this way:
View childView = ...;
childView.setTag("Some tag");
And then in your onClickListener:
child.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Object tag = view.getTag();
if (tag instanceof String) {
String stringTag = (String) tag;
if (stringTag.equals("Some tag") {
// do something
}
}
}
});

Related

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);
}

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.......

Setting gravity for auto generated TextView and Button

How can I set the gravity and margin for auto-generated(within the code) TextViews and Buttons? They are inside a LinearLayout.
Here is my generation code:
for(int i=0; i<num_enter; i++){
final int cuco = i;
LinearLayout linlay = new LinearLayout(this);
linlay.setOrientation(0);
TextView text = new TextView(this);
text.setText(name[cuco] + " ");
linlay.addView(text);
TextView num = new TextView(this);
num.setId(cuco);
num.setText("" + current[cuco]);
linlay.addView(num);
Button minus = new Button(this);
minus.setText("-");
minus.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int cval = current[cuco];
int currentF = current[cuco] - 1;
current[cuco] = current[cuco] -1;
SetSql update = new SetSql(SpellCast.this);
update.open();
update.changeCurrent(currentF, cval, name[cuco]);
update.close();
((TextView) findViewById(cuco)).setText("" + currentF);
}
});
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.RIGHT);
minus.setLayoutParams(p);
linlay.addView(minus);
Button plus = new Button(this);
plus.setText("+");
plus.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int cval = current[cuco];
int currentF = current[cuco] + 1;
current[cuco] = current[cuco] + 1;
SetSql update = new SetSql(SpellCast.this);
update.open();
update.changeCurrent(currentF, cval, name[cuco]);
update.close();
((TextView) findViewById(cuco)).setText("" + currentF);
}
});
LinearLayout.LayoutParams w = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.RIGHT);
plus.setHeight(LayoutParams.WRAP_CONTENT);
plus.setWidth(50);
plus.setLayoutParams(w);
linlay.addView(plus);
main.addView(linlay);
}
Hope you find a way to set the button gravity without changing it size.
1) Get Reference of TextView say tv.
2) tv.setGravity(Gravity.CENTER);
It is not sure work with LinearLayout.. Try Relative Or Absolute
Use View.setLayoutParams(ViewGroup.LayoutParams params). Look at http://developer.android.com/reference/android/R.styleable.html#ViewGroup_Layout for the LayoutParams.
Since nobody has addressed margins
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
p.setMargins(10, 10,10,10);
p.gravity = Gravity.CENTER;
textView.setLayoutParams(p);
When using setLayoutParams make sure the type of layout params matches the parent view which, in this case, is LinearLayout
setGravity(Gravity.CENTER); Will set the gravity of the text within the view

Dynamic TextView in Relative layout

I am triying to use dynamic layout for comment part of my project but when i settext of textview dynamicly the output only appears in top of the screen. And it puts the output over the other outputs
RelativeLayout ll=(RelativeLayout) findViewById(R.id.rl);
for(int i = 0; i < 20; i++) {
TextView cb = new TextView(this);
cb.setText("YORUMLAR"+yorum[0]+i);
cb.setTextSize(30);
ll.addView(cb);
}
So how can i put the output on the bottom of the screen linearly.
You should use LinearLayout to automatically add one TextView after another.
Assuming you can't live without RelativeLayout, you'll need to dynamically generate ids for all TextView you create in order to put one view under another. Here is example:
public class HelloWorld extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
RelativeLayout layout = (RelativeLayout)findViewById(R.id.layout);
Random rnd = new Random();
int prevTextViewId = 0;
for(int i = 0; i < 10; i++)
{
final TextView textView = new TextView(this);
textView.setText("Text "+i);
textView.setTextColor(rnd.nextInt() | 0xff000000);
int curTextViewId = prevTextViewId + 1;
textView.setId(curTextViewId);
final RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.BELOW, prevTextViewId);
textView.setLayoutParams(params);
prevTextViewId = curTextViewId;
layout.addView(textView, params);
}
}
}
You've to provide the location of your newly added view. As #Adinia said, with no position, it will be aligned to the top by default. So you can use the following code to do it with RelativeLayout;
RelativeLayout containerLayout = (RelativeLayout) findViewById(R.id.container);
for (int i = 0; i < 20; i++) {
TextView dynaText = new TextView(this);
dynaText.setText("Some text " + i);
dynaText.setTextSize(30);
// Set the location of your textView.
dynaText.setPadding(0, (i * 30), 0, 0);
containerLayout.addView(dynaText);
}
If you want to show multiple textviews one after the other, then you should go with LinearLayout.
You may also add Dynamic textview to relative layout. Here with i have attached some code this may help you.
RelativeLayout ll=(RelativeLayout) findViewById(R.id.rl);
for(int i = 0; i < 20; i++)
{
TextView cb = new TextView(this);
cb.setText("YORUMLAR"+yorum[0]+i);
cb.setTextSize(30);
cb.setId(2000+i);
RelativeLayout.LayoutParams TextViewLayoutParams = new RelativeLayout.LayoutParams(100,100);
if (i != 0 )DispViewLayoutParams.addRule(RelativeLayout.BELOW, 2000 - (i-1));
ll.addView(cb,TextViewLayoutParams);
}

Categories

Resources