I need to accomodate three columns in a TableLayout.
The following code creates the table row headers & then populates the values in the columns. Table layout has been defined in the layout xml.
TableLayout tableLay = (TableLayout) findViewById(R.id.table);
// Table Headers
TextView firstNameHeader = new TextView(this);
firstNameHeader.setGravity(Gravity.CENTER);
TextView lastNameHeader = new TextView(this);
lastNameHeader.setGravity(Gravity.CENTER);
TextView ageHeader = new TextView(this);
ageHeader.setGravity(Gravity.CENTER);
// Adding the Table headers to Table Row
TableRow empHeaderTableRow = new TableRow(this);
empDetailsTableRow.addView(firstNameHeader);
empDetailsTableRow.addView(lastNameHeader);
empDetailsTableRow.addView(ageHeader);
// Adding the Table Row to Table Layout
tableLay.addView(empDetailsTableRow);
// Adding Column Data
for(int count = 0; count < empDetails.size ; count++){
TextView firstNameData = new TextView(this);
firstNameData.setGravity(Gravity.CENTER);
firstNameData.setText(...);
TextView lastNameData = new TextView(this);
lastNameData.setGravity(Gravity.CENTER);
lastNameData.setText(...);
TextView ageData = new TextView(this);
ageData.setText(...);
ageData.setGravity(Gravity.CENTER);
TableRow empDataTableRow = new TableRow(this);
empDataTableRow.addView(firstNameData);
empDataTableRow.addView(lastNameData);
empDataTableRow.addView(ageData);
}
// Adding the Table Row to Table Layout
tableLay.addView(empDataTableRow);
There is alignment issue with the above code.
When any of the data like first name , last name exceeds a certain length , the entire colum shifts out of the screen. In that case , only one column is visible on the screen while the rest of the columns goes beyond the screen.
I want to set fixed column width for the three columns , so that if any data wrt to a particular column exceeds length, it will get truncated or displayed on the second line & the other column positions (aligned) is not disturbed.
Do I need to truncate the text if it exceeds the column width or it can be done automatically with the help of any method already available in TextView.
Any hints/suggestions welcome.
You need to set width of textView to be fixed to resolve this issue. You can also use weight for this purpose.
Use android:shrinkColumns and android:stretchColumns xml-attributes.
You can use textview.setMaxLines(maxlines) and textview.setwidht() to fix this problem.
Related
I have this button on GridLayout called addnewTask. When you create this button, it will create an EditText.
private GridLayout gridLayout;
int rowIndex = 3;
int colIndex = 1;
int i=0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_task);
gridLayout = (GridLayout) findViewById(R.id.taskLayout);
}
This function to create EditText when the button is clicked -->
public void addView(View view) {
i++;
String tname = "task" + Integer.toString(i);
EditText editText = new EditText(this);
GridLayout.LayoutParams param = new GridLayout.LayoutParams();
param.height = ViewGroup.LayoutParams.WRAP_CONTENT;
param.width = GridLayout.LayoutParams.MATCH_PARENT;
param.rowSpec = GridLayout.spec(rowIndex);
param.columnSpec = GridLayout.spec(colIndex);
editText.setLayoutParams(param);
if (rowIndex > 3) {
editText.setTag(tname);
}
gridLayout.addView(editText);
rowIndex++;
}
My problem is that i want to set the android:id of EditText i created.
like this: When the button is clicked, EditText is created, in row 3, column 1 and id name task1.
When the button is clicked again, another EditText is created, in row 4, column 1 and id name task2.
When the button is clicked again, another EditText is created, in row 5, column 1 and id name task3.
ANS SO ON.....
Ids in android aren't strings - they are always numbers. Even if you write in xml #+id/textId, a number is generated for this text. You can see that in your R file.
What you can do is assign id to your edit texts by using editText.setId(int) method. If you want to be able to easily refer to the edit texts, you can either:
assign the ids sequentially: 1, then 2, 3 etc. Then id of the item would be (row-1) * <columnsCount> + column) (so if you have 3 columns, then second item in fifth row would have id 4 * 3 + 2)
create a map field of type Map<String, Integer>, and again assigns ids sequentially, and save them in.
String tname = "task" + Integer.toString(i);
EditText editText = new EditText(this);
editText.setId(i);
idsMap.put(tname, i);
You then get edittext's id by calling idsMap.get("task3")
Third option is to just keep reference to your EditText in a map: you'd then have a Map<String, EditText> map, and then call
String tname = "task" + Integer.toString(i);
EditText editText = new EditText(this);
editTextsMap.put(tname, editText);
You can keep references of these edit text in an array representing cells of your grid.
declare arraylist like this:
ArrayList<EditText> etArray = new ArrayList<>();
and keep reference to your EditText in array list at the end of your addView method like this:
etArray.add(i,edittext);
now refer these view like this:
etArray.get(i);
this way you will be able to refer them for accessing text.
assigning ids dynamically can cause problems as id is an integer and your assigned ids may cause conflict with system assigned ids to other components.
You can't set id as a String. You can only assign integer as Id. But if you want to use String as id for the ease of use then - in res/values/ids.xml file
<item name="edit_text_hello" type="id"/>
And then use it as:
edText.setId(R.id.edit_text_hello);
So you can do what you need.
I am getting number of string from server.
I want to show it on layout like below image
Everytime I'll be getting different type of string. so how to create dynamic layout for textview?
May be you are looking for a Flow Layout.
https://github.com/ApmeM/android-flowlayout
using this code, we can able to create linear layout dynamically with inside textview. if you want, just modify the code to as you like, above asked..
onCreate() Method :
private Button[] btnAdd ,btnQuestionPalete ; // GLobally
private LinearLayout layout_button ;
layout_button = (LinearLayout) findViewById(R.id.button_layout);
btnAdd = new Button[100] ;
LayoutParams param2 = new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 1f);
btnQuestionPalete = new Button[100];
for (int i = 0; i < noOfButton; i++) {
linearQuestionPalettesRow = new LinearLayout(getApplicationContext());
linearQuestionPalettesRow.setOrientation(LinearLayout.VERTICAL);
linearQuestionPalettesRow.setLayoutParams(param2);
linearQuestionPalettesRow.setPadding(10, 10, 10, 10);
textView[i] = new TextView(getApplicationContext());
textView[i].setId(i+1);
textView[i].setText("test");
textView[i].setTextColor(Color.BLACK);
textView[i].setGravity(Gravity.CENTER_HORIZONTAL);
linearQuestionPalettesRow.addView(textView[i]);
layout_button.addView(linearQuestionPalettesRow);
}
xml code :
<LinearLayout
android:id="#+id/button_layout"
android:layout_width="wrap_content"
android:layout_height="75dp"
android:orientation="horizontal"
>
</LinearLayout>
Its easy just add the stings to the array/arraylist and make arrayadapter out of it .Then pass it listView or DridView
You can use Table Layout to achieve this dynamically.
but i think you want your layout in zigzag manner like:
------------------
------------------
------------------
------------------
so you can do it using ListView(efficient)
but if you don't want this pattern and you don't have rows more than 5-10 then you can go for TableLayout
I am reading data from a SOAP service and then using that data to load images from the res folder locally. I am using a loop because there will always be six images being loaded. This is my code :
final TableLayout tblLay = (TableLayout)findViewById(R.id.lottotl);
final LayoutParams params = new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
for(int i=2;i<9;i++) {
final ImageView image = new ImageView(LastDraw.this);
image.setLayoutParams(trparams);
image.setMaxHeight(20);
image.setMaxWidth(20);
String imgName = "img_" + split[i].substring(split[i].indexOf("=") + 1);
int id = getResources().getIdentifier(imgName, "drawable", getPackageName());
image.setImageResource(id);
row2.setLayoutParams(params);
row2.addView(image);
}
tblLay.addView(row2);
The issue I am having is that there is a gap between the first image and the consecutive images.
It looks like this (each number representing an image):
1.........23456
I am thinking it has to do with the layout of the row in the tablelayout, I could be wrong.
Thank you
Anyone?
Figured it out ... feel kind of stupid but, I learnt something! I load a textview into the first row and then the imageviews into the second row. The textview is in the first column and its width is making the first column stretch ... THAT is why there is a gap.
I am trying to change the values of several TextView elements but iterating through an array list and adding these values. However I can't seem to find a way to change the R.id value that is used each time. For example:
for (int i=0; i<arrayList.size(); i++)
{
TextView t = (TextView) dialog.findViewById(R.id.value+(i));
t.setText(arrayList.get(i));
}
Where the values are in the format animals_eng1,animals_eng2 etc..
Any help appreciated.
Your best bet is to create an array containing the resource IDs of each text view and looping through them..
ex.
int[] textViewIds = new int[] { R.id.animals_eng1, R.id.animals_eng2, R.id.animals_eng3 };
Then in your activity you can loop through them and set the values like you desire
for (int i=0; i<arrayList.size(); i++)
{
((TextView)findViewById(textViewIds[i])).setText(arrayList.get(i));
}
You'll have to make sure your arrayList size is the same as the number of textview resource IDs you set or you'll end up with an out of bounds exception when looping
I don't know of a way to do exactly what you're asking, but here are two alternatives:
1.Create an array of Integers, and assign each element of the array to a different view id value
int[] ids = new int[arrayList.size()];
ids[0] = R.id.view0;
ids[1] = R.id.view1;
ids[2] = R.id.view2;
//...ids[n] = R.id.viewN; where n goes up to arrayList.size()
for (int i : ids){
((TextView)dialog.findViewById(ids[i])).setText(arrayList.get(i));
}
Note that the above method sorta defeats the point because you have to have a line for every TextView, if you want something more dynamic:
2.Tag your TextViews in your layout xml by adding android:tag="prefix0", for example, to each of your TextViews. Before the loop find the parent View of your layout, and then use the findViewWithTag method of that view within the for loop. From your code I'm guessing you're using a Dialog with a custom layout xml, so you'd first find the parent of that:
ViewGroup parent = dialog.findViewById(R.id.parent); //or whatever the name of your parent LinearLayout/RelativeLayout/whatever is
String commonPrefix = "prefix"; //or whatever you've tagged your views with
for (int i=0; i<arrayList.size(); i++){
TextView t = (TextView) parent.findViewWithTag(commonPrefix+i);
t.setText(arrayList.get(i));
}
One way to solve this would be putting your resource ids in an int array and getting the resource at index i.
TextView t = (TextView) dialog.findViewById(R.id.value+(i))
becomes
TextView t = (TextView) dialog.findViewById(resourceArray[i])
if all of your views are on the same container (and only them) , simply iterate over its children .
if not , you can add an array of ids (in res) and iterate over it .
I'm new, so sorry if this turns out so simple that I should have solved myself. I've spent a couple days thinking about it. I've researched a ton and searched many other posts here, but no success.
I have a dialog with DatePicker, Buttons, EditText fields, and Spinners. I can populate everything i need from the stored items in my DB to the dialog. But when i try to get the numbers entered into some of the EditText fields, it throws NumberFormatException. I can hard code values into variables to store, and hide my attempt to get the value in a try and it will run fine. The values get stored and when I open the dialog again they populate into the right areas.
Here's partial code-
EditText et = new EditText(getContext());
for(int i=0; i<=etcount; i++){
placed = -1; //reset for next iteration
//try to get number from edittext
et.findViewById(i);
placed = Integer.parseInt(et.getText().toString());
awake++;
/*
try {
//et.findViewById(i);
placed = Integer.parseInt(findViewById(i).toString());
//placed = Integer.parseInt(et.getText().toString());
} catch(NumberFormatException nfe) {
System.out.println("Could not parse " + nfe);
}*/
I commented out the try block cause I wanted to troubleshoot quickly.
etcount variable is initialized at onCreate with -1 value, before getting values from DB. If there are values stored in the DB it gets incremented by 1, then code is called to dynamically add an EditText and Spinner to the layout. Also the EditText id is set to the value of etcount. Here is that code-
//this will be ran when +placement button pressed, or if there are items in db stored
//adds 2 rows to dialog, one for textview to label items, one row for edittext with number
//and spinner with what item it is
private void createTableRow(int numPlaced, int itmPlaced){
etcount++; //used to count how many edittext fields there are so that they can be saved later
spincount++; //to count how many spinner there are
tl = (TableLayout)findViewById(R.id.tableLayoutVisit); //the tablelayout name
//need to create row for textview, then another row for edittext and spinner
tr1 = new TableRow(this.getContext()); //table row 1, for textview
tr1.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
TextView tv = new TextView(this.getContext());
tv.setText("Amount Placed");
tv.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
tr1.addView(tv); //add textview to tablerow1
tl.addView(tr1, new TableLayout.LayoutParams( //add row to tablelayout
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
tr2 = new TableRow(this.getContext()); //tablerow2: edittext and spinner
tr2.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
EditText et = new EditText(this.getContext());
et.setId(etcount);
et.setInputType(InputType.TYPE_CLASS_NUMBER);
if(numPlaced!=0){ //if being populated from previous visit
et.setText(Integer.toString(numPlaced));
//et.setText("" +numPlaced);
}
//need to have listener to read data
et.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
Spinner spin = new Spinner(this.getContext());
spin.setId(spincount);
spinArray = getContext().getResources().getStringArray(R.array.itemplaced);
ArrayAdapter adapter = new ArrayAdapter(getContext(),
android.R.layout.simple_spinner_item, spinArray);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spin.setAdapter(adapter);
if(itmPlaced!=-1){
spin.setSelection(itmPlaced); //assign correct value
}
spin.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
tr2.addView(et);
tr2.addView(spin);
tl.addView(tr2, new TableLayout.LayoutParams( //add row to tablelayout
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
I pass it (0,-1) if it is a new item and not currently stored in DB. Also you probably noticed I forced it to accept TYPE_CLASS_NUMBER. But I don't think the issue is there. Again, if I hard code values it will save into the DB and the next time I open it it dynamically creates EditText/Spinner row in layout and populates the EditText with the value in the DB.
So... something is wrong with the first section I think, the et.findViewById(i); or placed = Integer.parseInt(et.getText().toString());. The value of "etcount" should be -1 if nothing was populated from DB, and 0 etc(etcount++) each time something is populated from DB.
Sorry if this is longwinded, wanted to be specific. Hope this is enough info! Any help would be great!!! Thanks in advance.
Try this:
EditText et = new EditText(this);
for (int i = 0; i <= etcount; i++) {
placed = -1;
et = (EditText) this.findViewById(i);
placed = Integer.parseInt(et.getText().toString());
//...
}
It seems to me that I've found an error.
The main problem in your code that you do not assign unique values in setId methods. In your case some editTexts and spins can have the same IDs. This is wrong. Every element must have a unique identifier. This is the first what you should correct in your code.
After that you can use my approach. But it seems to me that something wrong in this approach. It is not beautiful ) Try to find best practices in this field.
Few suggestions from my side:
1) try to check whether getText method not giving you empty string"" or null.
2) place your EditText et; to class variable not a local instance.
example public class ExampleActivity extends Activity
{
EditText et;//place it here instead in oncreate methods.
}// or make it final if defining in oncreate.
according to your code, issues seems in your for loop
for(int i=0; i<=etcount; i++){
placed = -1; //reset for next iteration
//try to get number from edittext // which edit text you are trying to access. am sure it is returning null to you.
et.findViewById(i);
placed = Integer.parseInt(et.getText().toString());