I has to ask you how to find my Views, I created them dynamically because all information about Texts were in my string-array, and now I would like to find it to store this in Class by getters, to use it in another classes, in feature I would like to make backend to store information thats why I chose class for temporary solution.
Thats my code
sportlist = getResources().getStringArray(R.array.btnsport);
for(j=0;j<sportlist.length;j++){
sporthash.put(j,sportlist[j]);
System.out.println(sporthash);
}
//Here I create my TableRow with TextView
TableRow.LayoutParams lp = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT);
lp.height = 120;
lp.setMargins(8,8,8,8);
for(j=0;j<sportlist.length;j++) {
TableRow row = new TableRow(getActivity());
row.setLayoutParams(lp);
final TextView t = new TextView(getActivity());
t.setPadding(10, 10, 10, 10);
t.setText(sporthash.get(j));
t.setGravity(Gravity.CENTER);
t.setClickable(true);
t.setTextSize(18);
t.setId(j);
t.setBackgroundResource(R.drawable.sport_false);
t.setTextColor(Color.BLACK);
Then after this I have saving button, which send information to my Storage.class. I try to set t.setId(j) and find it by new TextView h, h.findViewById(j) but its return strage code. I would to find Views with t.BackgroundResource(R.drawable.sport_true) and send them to my Storage.class.
Thats my button, in for I tryed to find my views, so what solution would be best ?
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Storage sto = new Storage();
sto.setAge(BirthDate.getText().toString());
sto.setImage(civ);
sto.setLocation(Map.getText().toString());
System.out.println(Map.getText().toString());
for(j=0;j<sportlist.length;j++) {
}
Intent newIntent = new Intent(getActivity(),ProfilActivity.class);
startActivity(newIntent);
}
});
You can't use setId here, because setId should be used with generateViewId:
From documentation of generateViewId():
generateViewId
Generate a value suitable for use in setId(int). This value will not collide with ID values generated at build time by aapt for R.id.
When you're trying to set the id with setId() there's probability your id is colliding with auto-generated id by the Android Studio. So, you need to ensure the id is unique.
You can use setTag() and getTag() to avoid the problem with setId()
Related
I have been on this problem for a while now.
I am hoping to gather top trending keywords and place into an ArrayList.
Each keyword is to be placed on a toggleButton, (user selects keyword and it enhances search). I need the buttons to be in a grid like form on the Android mobile app, I also need the buttons to be placed in an ArrayList so I can reference later. I've tried so many different loops, for loops and loops in loop and keep hitting the same two problems:
prob 1) either the keywords are not read, or repeated in each column if I create the buttons within the layout loop.
prob 2) I create the buttons first and then reference to them in the layout loop and I get a error message:
"java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first"
I've scanned the internet, I've tried different methods and I think its just something I am missing in my code (this layer of code is one of many layers, this one holds the buttons...any pointers will be appreciated.
trending = new ArrayList<String>() {
{
add("one"); add("two"); add("three") ;add("four");add("five");
add("six");add("seven");add("eight");add("nine");add("ten");
add("eleven");
}};
//LAYOUT SETTINGS 5
TableLayout rLayout5 = new TableLayout(this);
rLayout5.setOrientation(TableLayout.VERTICAL);
LayoutParams param7 = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
param7.addRule(RelativeLayout.BELOW, rLayout4.getId());
rLayout5.setBackgroundColor(Color.parseColor("#EEEBAA"));
rLayout5.setLayoutParams(param7);
// List<ToggleButton> togButtStore = new ArrayList<ToggleButton>();
int i = 0 ;
while (i < trending.size()){
if (i % 3 == 0){
tr = new TableRow(this);
rLayout5.addView(tr);
}
toggBtn = new ToggleButton(this);
toggBtn.setText(trending.get(i));
toggBtn.setId(i);
toggBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//something here
}
});
tr.addView(toggBtn);
i++;
}
rLayout5.addView(tr); ///<---error points to this line
root.addView(rLayout1);
rLayout1.addView(text1);
root.addView(rLayout4);
root.addView(rLayout3);
root.addView(rLayout5);
setContentView(root);
}
You are adding tr twice to the rLayout5. Delete the line where your error is....
this is my first question so I hope to make it clear.
I have one textView with some numerical text and next to it one button with one click listener and what I want is that when you click on the button the numerical value (>=0) of the TextView decrements in one.
Here is part of my code:
TextView Counter = new TextView(this);
if (intSeries != 0)
Counter.setText(Integer.toString(intSeries));
else
Counter.setText("0");
Counter.setId(4);
tablaContador.addView(Counter,Tr);
Button Done = new Button(this);
Done.setText("-1");
if (intSeries != 0)
Done.setVisibility(View.VISIBLE);
else
Done.setVisibility(View.GONE);
Done.setId(6);
Done.setOnClickListener(this);
And this is the onClick funcion (part of it):
#Override
public void onClick(final View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case 6:{
TextView text = (TextView)findViewById(4);
int series = Integer.parseInt(text.getText().toString());
series--;
text.setText(series);
if (series==0){
Button boton = (Button)findViewById(6);
boton.setVisibility(View.GONE);
}
}
}
}
The error is when I try to make the setText inside the onClick function, I hope it can be fixed or maybe recieve other idea to do it.
Thank you so much.
I would avoid all this hardcoding of Ids, use resources instead.
Your call to
text.setText(series)
is passing an int. The only valid setText(int resId) overload expects a resource associated with the int value, i.e. a string resource.
Convert your series value to a string.
Something like:
text.setText(Integer.toString(series));
You should setup series as an integer. And increase/descrease it as you wish. When you want to change the button's text convert the int to String.
Instead of:
text.setText(series);
use:
text.setText(String.valueOf(series));
Variablenames in java can't start with a capital letter. That is reserved for classnames.
Counter -> counter
Done -> done
I tried this and it worked:
//Create onClickListener
OnClickListener pickChoice = new OnClickListener()
{
public void onClick(View v)
{
TextView txt = (TextView) findViewById(4);
int number = Integer.valueOf(txt.getText().toString());
txt.setText(String.valueOf(number -1));
}
};
//Create layout
LinearLayout lnLayout = new LinearLayout(this);
lnLayout.setOrientation(LinearLayout.VERTICAL);
TextView txt = new TextView(this);
txt.setId(4);
txt.setText("0");
lnLayout.addView(txt);
Button Done = new Button(this);
Done.setText("-1");
Done.setId(6);
Done.setOnClickListener(pickChoice);
lnLayout.addView(Done);
setContentView(lnLayout);
Where are you creating your button inside? an activity? the part where you pass the onClickListener to the button doesn't make sense, maybe the button is getting a wrong listener and gets you an error every time you press the button ?
The code should be easy to understand, if there is anything you need me to explain please ask :)
First off I have searched for this info for about a week and found very little. So hopefully this long read helps some other new people.
I have created a UI from JSON. This UI has all kinds of Views. Such as EditText, RadioButton, CheckBox, Spinner, etc. Now I need to account for certain inevitable scenarios. Screen rotation, phone call, back button, home button etc. Since all these Views are created after a network call/response and this takes time I do not want to repeat this action each time. So saving the actual RadioButton or EditText and what was selected on the RadioButton or typed into the EditText is extremely important. From what I've read for screen rotation I use onSaveInstanceState(). For anything else I would use onPause() because it is the only thing that is garunteed to be called.
The problem is I have no idea how to store programatically created Views with no id's in sharedprefs or a bundle let alone the values they hold. Lets look at my code and then discuss what I think is currently possible.
allEdit = new ArrayList<EditText>();
else if (map.get(TAG_FIELD).equals(et)) {
Log.v("RESPONSE", "About to create an EditText");
// find
LinearLayout content = (LinearLayout) getActivity()
.findViewById(R.id.add);
// create
TextView tv = new TextView(getActivity());
EditText et = new EditText(getActivity());
LinearLayout ll1 = new LinearLayout(getActivity());
// set
tv.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.MATCH_PARENT));
et.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
ll1.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
tv.setText(map.get(TAG_NAME));
ll1.setOrientation(LinearLayout.HORIZONTAL);
// add
ll1.addView(tv);
ll1.addView(et);
allEdit.add(et);
content.addView(ll1);
}
So in the example above I have created an EditText and stored it in an ArrayList<EditText>. Now my thought is that in onPause() I could do something like this.
for (int i = 0; i < allEdit.size(); i++) {
EditText et = allEdit.get(i);
String input = et.getText().toString();
prefsEdit.put(input);
}
Which I think might work, it also might overwrite the String "input" inside shared preferences over and over again. Not totally sure how that works. It also still does not solve how to save the actual EditText so that it does not have to be recreated.
Now in onSavedInstanceState() I think I may be able to get away with just inserting the whole ArrayList<EditText> as serializable, right? Like this...
putSerializable("key", allEdit)
However that does not save the values inside them.
So how do I save these Views and their values in onSavedInstanceState() and onPause()? Perhaps more importantly, do I need both? Can I get away with just using onPause()?
Thank you
I havent tried this, but it sounds like it would work in practice. When creating the activity (before the JSON populates) create your own ViewGroup. From there, read the JSON and add every view that you get to the VeiwGroup. Then, when you want to save the information or whatever do this
int viewCount = mViewGroup.getChildCount();
for(i=0;i<viewCount;i++) {
newView = mViewGroup.getChildAt(i);
if (newView instanceOf EditText) {
EditText newEditText = (EditText)newView
string value = newEditText.getText();
}
else if (newView instanceOf RadioButton) {
same as above ^
etc...
}
}
Then, for each of the values you pull add them to an array, maybe even a NamedPair to store their ID and value (by ID I mean index of which view it is). So
public List<String> lstEditTextValues = new ArrayList<String>();
After all that is said and done, then you can itterate through each one, and save it as an individual value through the bundle, save in a shared pref, or put into a static class level variable (not the safest way to retain information, but does work).
Hope this helps. Let me know if im completely off topic
I created a dynamic form without much problems, but I need to recover the values from the fields (controls) of the form, but I'm not sure of how to do this.
For example, I have this piece of code:
if(tipoP.equals("TEXTAREA")){
EditText ta = new EditText(this);
ta.setId(i);
LayoutParams params3 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, (float) 0.3);
params3.setMargins(20, 0, 20, 0);
ta.setLayoutParams(params3);
ta.setLines(3);
ta.setRawInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE);
ll.addView(ta);
}
How do I add a listener that captures the text of the EditText and put it inside a Vector variable?
I tried this:
ta.setOnClickListener(new OnClickListener(){
public void onClick(View view){
EditText t = (EditText) findViewById(i);
res.add(t.getText().toString);
}
});
But I'm not getting the id (variable i) because its in another execution environment. How do I solve this? Any help would be appreciated!!
You should not use setId for dynamically created views but setTag and findViewByTag.
You could create a button dynamically and set an onClickListener on it. Inside the listener, you can just reference the EditText directly (no need for tags or ids) as long as you have made it final.
In my application I create dynamic rows in table much as in this tutorial:
http://en.androidwiki.com/wiki/Dynamically_adding_rows_to_TableLayout
for(int i = startDay; i < startDay + 7; i++){
/* Create a TextView to be the row-content. */
TextView day = new TextView(this);
day.setText(Integer.toString(i));
day.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
day.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.i("Listener: ", "Click");
}
So now when I click on a TextView I can register click event, but how do I determine which TextView was clicked?
Not just an object which I get with an event but data like which day number was clicked?
Ideally I would want to have data attached to every view I create dynamically.
Something like data() method in Javascript jQuery.
Right now I can see only 1 way to solve this - while creating TextView add id with data and when clicked - get id back and parse it to get my data. But it strikes me as ugly approach.
Is there a way to attach arbitrary data to android views?
Found answer going through view methods. Maybe it will be useful for someone.
Methods I needed were:
setTag() and getTag()
http://developer.android.com/reference/android/view/View.html#setTag%28java.lang.Object%29