I am new in android. I have an array of images:
private int[] textureArrayWin = {
R.drawable.basketball,
R.drawable.soccer
};
Try to dynamically add them to my view:
for(int i=0; i < textureArrayWin.length; i++){
Log.v("asd", "index=" + i);
ImageView tv = new ImageView(this);
tv.setScaleType(ScaleType.CENTER_CROP);
tv.setImageResource(textureArrayWin[i]);
tv.setAdjustViewBounds(true);
tv.setMaxHeight(20);
tv.setMaxWidth(20);
myLayout.addView(tv);
}
But don't know how:
Fit them by "setMaxHeight", they are still big
How to know index of clicked image in array or to receive some id of image which allow to know the unique id of image in my layout. In javascript, for example, I can do it by adding attr to element and in handler receive attribute by "this.getAttribute(someAttr)"
You can use the Id attribute to identify the views.
Assign a Id to each view by:
myView.setId(<some Integer value here>);
You can later refer to same view by:
View v = findViewById(<same Integer value here>);
Related
I'm trying to create a function that pulls together information that is currently scattered around different parts of my project.
As part of this task, I have a layout file with something like the following content... basically a set of rows, with each row having a label (TextView) and a UI element (e.g. CheckBox, Spinner or EditText) to collect information from the user:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/MyLinearLayout.Section"
android:id="#+id/section_pressure" >
<TableLayout style="#style/MyTableLayout"
android:id="#+id/table_pressure" >
<TableRow style="#style/MyTableRow" >
<TextView
style="#style/MyTextView.Label.WithHelp"
android:tag="label_show"
android:text="#string/label_show" />
<CheckBox
style="#style/MyCheckBox"
android:id="#+id/pressure" />
</TableRow>
<TableRow style="#style/MyTableRow" >
<TextView
style="#style/MyTextView.Label.WithHelp"
android:tag="label_unit"
android:text="#string/label_unit" />
<Spinner
style="#style/MySpinnerStyle"
android:id="#+id/pressureUnit" />
</TableRow>
</TableLayout>
</LinearLayout>
I already have an array of all the android:id values for the UI elements, and from that I want to generate another array of the corresponding android:text labels.
e.g. from R.id.pressureUnit I want to find the associated R.string.label_unit from that TableRow, so that I have a central record of what label is used for each UI element... currently that information is scattered across lots of different layout files.
Is this possible programmatically?
From what I understand you want to find #string resource ID of a sibling view of a given view.
Assuming you have the xml file already inflated, you can do the following:
private int getSiblingStringId(#IdRes int viewId) {
View uiElement = findViewById(viewId);
ViewGroup parent = (ViewGroup) uiElement.getParent();
// iterate through the siblings
for (int i = 0; i < parent.getChildCount(); i++) {
View view = parent.getChildAt(i);
if (view instanceof TextView) {
String value = ((TextView) view).getText().toString();
// found
return getStringIdFromValue(value);
}
}
throw new IllegalArgumentException("no TextView sibling for " + viewId);
}
private int getStringIdFromValue(String value) {
// get all fields using reflection
Field[] fields = R.string.class.getDeclaredFields();
for (Field field : fields) {
int stringResId = getResources().getIdentifier(field.getName(), "string", getPackageName());
String s = getString(stringResId);
if (s.equals(value)) return stringResId;
}
throw new IllegalArgumentException("no matching string for " + value);
}
The above code will work inside an activity. You might need to modify it a bit for other classes. (You will need to call findViewById, getResources and getString)
Well, I would set an ID to each table row. Then, programmatically get every child view under each row by iterating over the row's children. From there, you can easily manipulate every view by simply determining which one are you at by using instanceof. But, let's assume you cannot change this, you can still be doing it but it might not be efficient.
Since I don't really know the structure of your array of ids, I just assume its an array of integers called uiIds. Then, you would have to do something like
TableLayout layout = findViewById(R.id.table_pressure);
TableRow tr = null;
View rowChild = null;
TextView tv = null;
View secondaryView = null;
int tableChildCount = layout.getChildCount();
int rowChildCount = 0;
// Since I don't really know the structure of your array of ids,
// I just assume its an array of integers called uiIds
//This will contain the corresponding text strings of every textview
List<String> textLabels = Arrays.asList(new String[uiIds.length]);
// Go over all the rows on your table
for (int i = 0; i < tableChildCount; i++) {
// I'm assuming that you only have rows as the children of your table
tr = (TableRow) layout.getChildAt(i); //This is the row
rowChildCount = tr.getChildCount();
tv = null;
secondaryView = null;
// Now go over all the children of the current row i
for (int j = 0; j < rowChildCount; j++) {
// Here I'm also assuming you only have two children on every row
rowChild = getChildAt(j);
// At this point, the view v could be any type of the ones you have
// used. Since we are interested in TextView simply do an instanceof
if ( rowChild instanceof TextView ) {
tv = (TextView) v;
} else {
// This is the other view in the row. The ones from which you alreade have its ids
// e.g. the spinner with id pressureUnit
secondaryView = rowChild; //We do not need to cast
}
}
// Now we construct the array
if (tv != null && secondaryView != null) {
// The id we just obtained is one from the ones you have already saved
// in an array called uiIds
int secondaryViewId = secondaryView.getId();
//Now, we need to find the index of this id in uiIds
for (int idx = 0; idx < uiIds.length; idx++) {
if ( uiIds[idx] == secondaryViewId ) {
//We have found a match. Then just add the text of the textview in the corresponding index of our new array
textLabels.set(idx,tv.getText().toString());
}
}
}
}
// At this point, textLabels should contain the text of the text view on every row
// such that the ith element in the array you already have corresponds to
// ith element of the array we just created.
// In other words, if uiIds[0] is equals to R.id.pressureUnit, then,
// textLabels.get(0) is equals to R.string.label_unit
I have edited the answer directly on the text editor so it might have some sintax erros. Hopefully this solves your problem or at least gives you an idea.
To get overview of your label mappings, I suggest to code more systematically, in this case to name the label just like the id.
#+id/pressure => #string/label_pressure
#+id/pressureUnit => #string/label_pressureUnit
I know this is not a direct answer to your question. However I think, if you work in this way, you don't need a central table of your mappings at all and your layouts become more readable. Android Studio makes it really easy to do this kind of changes.
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 have an imageView that I want to display a little icon of the country that you are currently in. I can get the country code, but problem is I can't dynamically change the imageView resource. My image files are all lowercase (Example: country code=US, image file=us)
My code (countryCode is the current countryCode in uppercase letters):
String lowerCountryCode = countryCode.toLowerCase();
String resource = "R.drawable." + lowerCountryCode;
img.setImageResource(resource);
Now, of course this will not work because setImageResource wants an int, so how can I do this?
One easy way to map that country name that you have to an int to be used in the setImageResource method is:
int id = getResources().getIdentifier(lowerCountryCode, "drawable", getPackageName());
setImageResource(id);
But you should really try to use different folders resources for the countries that you want to support.
This is how to set an image into ImageView using the setImageResource() method:
ImageView myImageView = (ImageView)v.findViewById(R.id.img_play);
// supossing to have an image called ic_play inside my drawables.
myImageView.setImageResource(R.drawable.ic_play);
you use that code
ImageView[] ivCard = new ImageView[1];
#override
protected void onCreate(Bundle savedInstanceState)
ivCard[0]=(ImageView)findViewById(R.id.imageView1);
You can use this code:
// Create an array that matches any country to its id (as String):
String[][] countriesId = new String[NUMBER_OF_COUNTRIES_SUPPORTED][];
// Initialize the array, where the first column will be the country's name (in uppercase) and the second column will be its id (as String):
countriesId[0] = new String[] {"US", String.valueOf(R.drawable.us)};
countriesId[1] = new String[] {"FR", String.valueOf(R.drawable.fr)};
// and so on...
// And after you get the variable "countryCode":
int i;
for(i = 0; i<countriesId.length; i++) {
if(countriesId[i][0].equals(countryCode))
break;
}
// Now "i" is the index of the country
img.setImageResource(Integer.parseInt(countriesId[i][1]));
you may try this:-
myImgView.setImageDrawable(getResources().getDrawable(R.drawable.image_name));
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 have a a set of 10 imageviews in my layout. I have given them sequential id's also as
android:id="#+id/pb1"
android:id="#+id/pb2"
Now I want to change background dynamically.
int totalPoi = listOfPOI.size();
int currentPoi = (j/totalPoi)*10;
for (i=1;i<=currentPoi;i++) {
imageview.setBackgroundResource(R.drawable.progressgreen);
}
Now inside the for loop I want to set the image view background dynamically. i,e if the currentpoi value is 3, background of 3 image views should be changed. What ever the times the for loop iterates that many image view's background should be changed. Hope the question is clear now.
Note : I have only 1 image progressgreen that need to be set to 10 image views
Finally I did this in the following way,
I placed all the id's in the array as
int[] imageViews = {R.id.pb1, R.id.pb2,R.id.pb3,R.id.pb4,R.id.pb5,R.id.pb6,R.id.pb7,R.id.pb8,R.id.pb9,R.id.pb10};
Now:
int pindex = 0;
for (pindex; pindex <currentPoi; pindex++) {
ImageView img = (ImageView) findViewById(imageViews[pindex]) ;
img.setImageResource(R.drawable.progressgreen);
}
Now, I am able to change the images dynamically.
#goto10. Thanks for your help. I will debug your point to see what went wrong in my side
Create an ImageView array:
ImageView views[] = new ImageView[10];
views[0] = (ImageView)findViewById(R.id.pb1);
...
views[9] = (ImageView)findViewById(R.id.pb10);
Now iterate the loop to set the background of images like this:
for (i=1;i<=currentPoi;i++)
{
views[i-1].setBackgroundResource(R.drawable.progressgreen);
}
you can do this by setting the name of drawables something like:
img_1, img_2, img_3...
for (i=1;i<=currentPoi;i++)
{
ImageView imageview=(ImageView) findViewById(getResources().getIdentifier("imgView_"+i, "id", getPackageName()));
imageview.setImageResource(getResources().getIdentifier("img_"+i, "drawable", getPackageName()));
}
Try this code.....
Create image Array..
private Integer[] mThumbIds = { R.drawable.bg_img_1, R.drawable.bg_img_2,
R.drawable.bg_img_3, R.drawable.bg_img_4, R.drawable.bg_img_5 };
And than modify your code
int totalPoi = listOfPOI.size();
int currentPoi = (j/totalPoi)*10;
for (i=1;i<=currentPoi;i++) {
imageview.setBackgroundResource(mThumbIds[i]);}
You could make an array of your ImageViews and then change them in your for loop.
ImageView views[] = new ImageView[10];
views[0] = (ImageView)findViewById(R.id.imageView0);
...
views[9] = (ImageView)findViewById(R.id.imageView9);
and then change your for loop to:
for (i=1;i<=currentPoi;i++) {
views[currentPoi].setBackgroundResource(R.drawable.progressgreen);
}
Arrays start at index 0, so make sure there's not an off-by-one error in here.
You'll need to give your ImageViews sequential ids, such as "#+id/pb1" and "#+id/pb2", etc.. Then you can get each of them in the loop like this:
for (i=1;i<=currentPoi;i++) {
// Find the image view based on it's name. We know it's pbx where 'x' is a number
// so we concatenate "pb" with the value of i in our loop to get the name
// of the identifier we're looking for. getResources.getIdentifier() is able to use
// this string value to find the ID of the imageView
int imageViewId = getResources().getIdentifier("pb" + i, "id", "com.your.package.name");
// Use the ID retrieved in the previous line to look up the ImageView object
ImageView imageView = (ImageView) findViewById(imageViewId);
// Set the background for the ImageView
imageView.setBackgroundResource(R.drawable.progressgreen);
}
Replace com.your.package.name with your application's package.